Christian Dupaty / Mbed OS ESP8266_HelloMQTT_MosquittoV2

Dependencies:   MQTT

Files at this revision

API Documentation at this revision

Comitter:
cdupaty
Date:
Thu Jun 11 14:09:40 2020 +0000
Parent:
23:e38aaf532823
Commit message:
MQTT protocol test on STM32; broker tests.mosquitto.org; WIFI interface ESP8266; Issue of topic0 by pressing the button; If reception of ', switching of the led; If received from 'q' end of program

Changed in this revision

C12832.lib Show diff for this revision Revisions of this file
Linux-example/LinuxIPStack.h Show diff for this revision Revisions of this file
Linux-example/LinuxMQTT.h Show diff for this revision Revisions of this file
Linux-example/linux-main.cpp Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed_app.json Show annotated file Show diff for this revision Revisions of this file
--- a/C12832.lib	Tue Jan 16 13:41:29 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-https://mbed.org/teams/components/code/C12832/#03069e3deaa4
--- a/Linux-example/LinuxIPStack.h	Tue Jan 16 13:41:29 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-#if !defined(LINUX_IPSTACK_H)
-#define LINUX_IPSTACK_H
-
-class IPStack 
-{
-public:    
-    IPStack()
-    {
-
-    }
-    
-    int Socket_error(const char* aString)
-    {
-
-        if (errno != EINTR && errno != EAGAIN && errno != EINPROGRESS && errno != EWOULDBLOCK)
-        {
-            if (strcmp(aString, "shutdown") != 0 || (errno != ENOTCONN && errno != ECONNRESET))
-                printf("Socket error %s in %s for socket %d\n", strerror(errno), aString, mysock);
-        }
-        return errno;
-    }
-
-    int connect(const char* hostname, int port)
-    {
-        int type = SOCK_STREAM;
-        struct sockaddr_in address;
-        int rc = -1;
-        sa_family_t family = AF_INET;
-        struct addrinfo *result = NULL;
-        struct addrinfo hints = {0, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, 0, NULL, NULL, NULL};
-
-        if ((rc = getaddrinfo(hostname, NULL, &hints, &result)) == 0)
-        {
-            struct addrinfo* res = result;
-
-            /* prefer ip4 addresses */
-            while (res)
-            {
-                if (res->ai_family == AF_INET)
-                {
-                    result = res;
-                    break;
-                }
-                res = res->ai_next;
-            }
-
-            if (result->ai_family == AF_INET)
-            {
-                address.sin_port = htons(port);
-                address.sin_family = family = AF_INET;
-                address.sin_addr = ((struct sockaddr_in*)(result->ai_addr))->sin_addr;
-            }
-            else
-                rc = -1;
-
-            freeaddrinfo(result);
-        }
-
-        if (rc == 0)
-        {
-            mysock = socket(family, type, 0);
-            if (mysock != -1)
-            {
-                int opt = 1;
-
-                //if (setsockopt(mysock, SOL_SOCKET, SO_NOSIGPIPE, (void*)&opt, sizeof(opt)) != 0)
-                //  printf("Could not set SO_NOSIGPIPE for socket %d", mysock);
-                
-                rc = ::connect(mysock, (struct sockaddr*)&address, sizeof(address));
-            }
-        }
-
-        return rc;
-    }
-
-    int read(char* buffer, int len, int timeout_ms)
-    {
-        struct timeval interval = {timeout_ms / 1000, (timeout_ms % 1000) * 1000};
-        if (interval.tv_sec < 0 || (interval.tv_sec == 0 && interval.tv_usec <= 0))
-        {
-            interval.tv_sec = 0;
-            interval.tv_usec = 100;
-        }
-
-        setsockopt(mysock, SOL_SOCKET, SO_RCVTIMEO, (char *)&interval, sizeof(struct timeval));
-
-        //printf("reading %d bytes\n", len);
-        int rc = ::recv(mysock, buffer, (size_t)len, 0);
-        if (rc == -1)
-            Socket_error("read");
-        //printf("read %d bytes\n", rc);
-        return rc;
-    }
-    
-    int write(char* buffer, int len, int timeout)
-    {
-        struct timeval tv;
-
-        tv.tv_sec = 0;  /* 30 Secs Timeout */
-        tv.tv_usec = timeout * 1000;  // Not init'ing this can cause strange errors
-
-        setsockopt(mysock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval));
-        int rc = ::write(mysock, buffer, len);
-        //printf("write rc %d\n", rc);
-        return rc;
-    }
-
-    int disconnect()
-    {
-        return ::close(mysock);
-    }
-    
-private:
-
-    int mysock; 
-    
-};
-
-#endif
\ No newline at end of file
--- a/Linux-example/LinuxMQTT.h	Tue Jan 16 13:41:29 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-#if !defined(LINUXMQTT_H)
-#define LINUXMQTT_H
-
-class Countdown
-{
-public:
-    Countdown()
-    { 
-    
-    }
-
-    Countdown(int ms)
-    { 
-        countdown_ms(ms);
-    }
-    
-
-    bool expired()
-    {
-        struct timeval now, res;
-        gettimeofday(&now, NULL);
-        timersub(&end_time, &now, &res);        
-        //printf("left %d ms\n", (res.tv_sec < 0) ? 0 : res.tv_sec * 1000 + res.tv_usec / 1000);
-        //if (res.tv_sec > 0 || res.tv_usec > 0)
-        //  printf("expired %d %d\n", res.tv_sec, res.tv_usec);
-        return res.tv_sec < 0 || (res.tv_sec == 0 && res.tv_usec <= 0);
-    }
-    
-
-    void countdown_ms(int ms)  
-    {
-        struct timeval now;
-        gettimeofday(&now, NULL);
-        struct timeval interval = {ms / 1000, (ms % 1000) * 1000};
-        //printf("interval %d %d\n", interval.tv_sec, interval.tv_usec);
-        timeradd(&now, &interval, &end_time);
-    }
-
-    
-    void countdown(int seconds)
-    {
-        struct timeval now;
-        gettimeofday(&now, NULL);
-        struct timeval interval = {seconds, 0};
-        timeradd(&now, &interval, &end_time);
-    }
-
-    
-    int left_ms()
-    {
-        struct timeval now, res;
-        gettimeofday(&now, NULL);
-        timersub(&end_time, &now, &res);
-        //printf("left %d ms\n", (res.tv_sec < 0) ? 0 : res.tv_sec * 1000 + res.tv_usec / 1000);
-        return (res.tv_sec < 0) ? 0 : res.tv_sec * 1000 + res.tv_usec / 1000;
-    }
-    
-private:
-
-    struct timeval end_time;
-};
-
-
-#endif
\ No newline at end of file
--- a/Linux-example/linux-main.cpp	Tue Jan 16 13:41:29 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2014 IBM Corp.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * and Eclipse Distribution License v1.0 which accompany this distribution.
- *
- * The Eclipse Public License is available at
- *    http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- *   http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *    Ian Craggs - initial API and implementation and/or initial documentation
- *******************************************************************************/
-  
- /**
-  This is a sample program to illustrate the use of the MQTT Client library
-  on Linux.  The Client class requires two classes which mediate
-  access to system interfaces for networking and timing.  As long as these two
-  classes provide the required public programming interfaces, it does not matter
-  what facilities they use underneath. In this program, they use the Linux
-  system libraries.
- 
- */
-
-#if defined(LINUX)
-
-#include "LinuxMQTT.h"
-#include "LinuxIPStack.h"
-#include "MQTTClient.h"
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/select.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-
-#define DEFAULT_STACK_SIZE -1
-
-
-int arrivedcount = 0;
-
-void messageArrived(MQTT::Message* message)
-{
-	printf("Message %d arrived: qos %d, retained %d, dup %d, packetid %d\n", 
-		++arrivedcount, message->qos, message->retained, message->dup, message->id);
-    printf("Payload %.*s\n", message->payloadlen, (char*)message->payload);
-}
-
-
-int connect(MQTT::Client<IPStack, Countdown>::connectionLostInfo* info)
-{
-    const char* hostname = "localhost"; //"m2m.eclipse.org";
-    int port = 1883;
-    printf("Connecting to %s:%d\n", hostname, port);
-    int rc = info->network->connect(hostname, port);
-	if (rc != 0)
-	    printf("rc from TCP connect is %d\n", rc);
- 
-    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;       
-    data.MQTTVersion = 3;
-    data.clientID.cstring = (char*)"mbed-icraggs";
-    rc = info->client->connect(&data);
-	if (rc != 0)
-	    printf("rc from MQTT connect is %d\n", rc);
-    
-    return rc;
-}
-
-
-int main(int argc, char* argv[])
-{   
-    IPStack ipstack = IPStack();
-    float version = 0.3;
-    const char* topic = "mbed-sample";
-    
-    printf("Version is %f\n", version);
-              
-    MQTT::Client<IPStack, Countdown> client = MQTT::Client<IPStack, Countdown>(ipstack);
-    
-    client.setConnectionLostHandler(connect);
-
-    MQTT::Client<IPStack, Countdown>::connectionLostInfo info = {&client, &ipstack};
-    int rc = connect(&info);
-    
-    rc = client.subscribe(topic, MQTT::QOS2, messageArrived);   
-    if (rc != 0)
-        printf("rc from MQTT subscribe is %d\n", rc);
-
-    MQTT::Message message;
-
-    // QoS 0
-    char buf[100];
-    sprintf(buf, "Hello World!  QoS 0 message from app version %f", version);
-    message.qos = MQTT::QOS0;
-    message.retained = false;
-    message.dup = false;
-    message.payload = (void*)buf;
-    message.payloadlen = strlen(buf)+1;
-    rc = client.publish(topic, &message);
-    while (arrivedcount == 0)
-        client.yield(100);
-        
-    // QoS 1
-	printf("Now QoS 1\n");
-    sprintf(buf, "Hello World!  QoS 1 message from app version %f", version);
-    message.qos = MQTT::QOS1;
-    message.payloadlen = strlen(buf)+1;
-    rc = client.publish(topic, &message);
-    while (arrivedcount == 1)
-        client.yield(100);
-        
-    // QoS 2
-    sprintf(buf, "Hello World!  QoS 2 message from app version %f", version);
-    message.qos = MQTT::QOS2;
-    message.payloadlen = strlen(buf)+1;
-    rc = client.publish(topic, &message);
-    while (arrivedcount == 2)
-        client.yield(100);
-    
-    rc = client.unsubscribe(topic);
-    if (rc != 0)
-        printf("rc from unsubscribe was %d\n", rc);
-    
-    rc = client.disconnect();
-    if (rc != 0)
-        printf("rc from disconnect was %d\n", rc);
-    
-    ipstack.disconnect();
-    
-    printf("Finishing with %d messages received\n", arrivedcount);
-    
-    return 0;
-}
-
-#endif
--- a/main.cpp	Tue Jan 16 13:41:29 2018 +0000
+++ b/main.cpp	Thu Jun 11 14:09:40 2020 +0000
@@ -13,127 +13,162 @@
  * Contributors:
  *    Ian Craggs - initial API and implementation and/or initial documentation
  *    Ian Craggs - make sure QoS2 processing works, and add device headers
+ *
+ * Adaptation STM32 NUCLEO and mosquitto.org : C.Dupaty
+ * 06/2020
+ * 
+ This demo works on NUCLEO STM32.
+WIFI link with ESP8266 connected
+Configuration in mbed_app.json
+target_overrides for the UART connection of the ESP8266 and the WIFI connection (SSID / PASS)
+MQTT parameters are configured in #define below
+if receive payload with first q -> exit
+if receive payload with first l -> toggle LED1 on NUCLEO
+ * 
  *******************************************************************************/
 
- /**
-  This is a sample program to illustrate the use of the MQTT Client library
-  on the mbed platform.  The Client class requires two classes which mediate
-  access to system interfaces for networking and timing.  As long as these two
-  classes provide the required public programming interfaces, it does not matter
-  what facilities they use underneath. In this program, they use the mbed
-  system libraries.
-
- */
-
- // change this to 1 to output messages to LCD instead of serial
-#define USE_LCD 0
-
-#if USE_LCD
-#include "C12832.h"
-
-// the actual pins are defined in mbed_app.json and can be overridden per target
-C12832 lcd(LCD_MOSI, LCD_SCK, LCD_MISO, LCD_A0, LCD_NCS);
-
-#define logMessage lcd.cls();lcd.printf
-
-#else
-
-#define logMessage printf
-
-#endif
-
-#define MQTTCLIENT_QOS2 1
-
 #include "easy-connect.h"
 #include "MQTTNetwork.h"
 #include "MQTTmbed.h"
 #include "MQTTClient.h"
 
-int arrivedcount = 0;
+DigitalOut led(LED1);
+Serial pc(USBTX, USBRX);
 
+#define board "NUCLEO_F411RE"
+/*
+MQTT QOS,  There are 3 QoS levels in MQTT
+At most once (MQTT::QOS0)
+At least once (MQTT::QOS1)
+Exactly once (MQTT::QOS2).
+*/
+#define quality MQTT::QOS0
+/*
+retained flag : The broker stores the last retained message and the corresponding QoS for that topic. 
+Each client that subscribes to a topic pattern that matches the topic of the retained 
+message receives the retained message immediately after they subscribe. 
+The broker stores only one retained message per topic.
+*/
+#define ret false
+/*
+dup flag : The flag indicates that the message is a duplicate 
+and was resent because the intended recipient (client or broker) did not acknowledge the original message.
+*/
+#define dupli false
+
+//DigitalIn btn(USER_BUTTON); //PC13 sur F411
+DigitalIn btn(PA_8,PullUp);   // button connected with internal pullup
+
+const char* hostname = "test.mosquitto.org";
+const int port = 1883;
+char* ID ="mbedSTM32Fourcade";
+char* user =NULL;       // user & pass = NULL for broker with no credential.   
+char* pass =NULL;
+const char* topic = "topic0";
+int arrivedcount=0;
+bool quit=false;
+
+NetworkInterface* network = easy_connect(true);
+MQTTNetwork mqttNetwork(network);
+MQTT::Client<MQTTNetwork, Countdown> client(mqttNetwork);
+MQTT::Message message;
+MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
 
 void messageArrived(MQTT::MessageData& md)
 {
     MQTT::Message &message = md.message;
-    logMessage("Message arrived: qos %d, retained %d, dup %d, packetid %d\r\n", message.qos, message.retained, message.dup, message.id);
-    logMessage("Payload %.*s\r\n", message.payloadlen, (char*)message.payload);
-    ++arrivedcount;
+    pc.printf("\x1B[33m");   // yellow
+    pc.printf("Message arrived -> qos %d, retained %d, dup %d, packetid %d\r\n", message.qos, message.retained, message.dup, message.id);
+    pc.printf("Payload -> %.*s\r\n", message.payloadlen, (char*)message.payload);
+    ++arrivedcount;    
+    if (*(char*)message.payload=='q') 
+                    {
+                    pc.printf("\x1B[31m");   // red
+                    pc.printf("Exit command received\n\r");    
+                    quit=true;
+                    }
+    if (*(char*)message.payload=='l') 
+                    {
+                    led=!led;
+                    pc.printf("\x1B[31m");   // red
+                    pc.printf("toggle LED\n\r");
+                    }
+    pc.printf("\x1B[0m"); // raz
 }
 
+void connection(void)
+{
+int rc;
+    pc.printf("\x1B[32m");   // green
+    pc.printf("Connecting to MQTT broker %s:%d\r\n", hostname, port);
+   
+    if ((rc = client.connect(data)) != 0)
+        pc.printf("rc from MQTT connect is %d\r\n", rc);
+    else pc.printf("connection MQTT OK ID:%s USER:%s PASS:%s\r\n",ID,user,pass);
+
+    if ((rc = client.subscribe(topic, quality, messageArrived)) != 0)
+        pc.printf("rc from MQTT subscribe is %d\r\n", rc);
+        else pc.printf("Subscribe MQTT OK topic:%s quality:%d\r\n",topic,quality);
+    pc.printf("\x1B[0m"); // raz
+}
+
+void deconnection(void)
+{
+ int rc;
+  pc.printf("\x1B[36m");   // cyan
+ if ((rc = client.unsubscribe(topic)) != 0) pc.printf("rc from unsubscribe was %d\r\n", rc);
+    else pc.printf("unsubscribe OK \r\n");
+    if ((rc = client.disconnect()) != 0) pc.printf("rc from disconnect was %d\r\n", rc);
+    else pc.printf("disconnect OK\r\n");
+    mqttNetwork.disconnect();
+    pc.printf("\x1B[0m"); // raz
+}
 
 int main(int argc, char* argv[])
 {
-    float version = 0.6;
-    char* topic = "mbed-sample";
-
-    logMessage("HelloMQTT: version is %.2f\r\n", version);
-
-    NetworkInterface* network = easy_connect(true);
-    if (!network) {
-        return -1;
+    int rc;
+    int cpt=0;
+    char buf[100];
+    
+    //pc.printf("\x1B[2J");  //efface ecran
+    //pc.printf("\x1B[0;0H");   // curseur en 0,0
+    pc.printf("\x1B[1m");   // brillant
+    pc.printf("\r\nMQTT test on %s\r\n",board);
+    pc.printf("--------------------------\r\n\r\n");
+    pc.printf("\x1B[33m");   // yellow
+    wait(1);
+  
+// TCP connection
+    mqttNetwork.connect(hostname, port);
+    if (rc != 0) pc.printf("rc from TCP connect is %d\r\n", rc);
+    else pc.printf("WIFI network connection OK\r\n");
+    
+// MQTT data
+    data.MQTTVersion = 3;
+    data.clientID.cstring = ID;
+    data.username.cstring = user;
+    data.password.cstring = pass;
+    message.qos = quality;
+    message.retained = ret;
+    message.dup = dupli;
+    message.payload = (void*)buf;
+    connection();
+    while(!quit)
+    {
+        pc.printf("---> Press button to send : %s<--- \n\r",topic);
+        while(btn);
+        while(!btn);
+        //connection();
+        sprintf(buf, "Message from %s number -> %d \r\n", board,++cpt);
+        pc.printf("Send message -> %s\n\r",buf);
+        message.payloadlen = strlen(buf)+1;
+        if ((rc = client.publish(topic, message)) !=0) pc.printf("rc publication error %d\r\n", rc);
+        client.yield(100);
+        //deconnection();
     }
 
-    MQTTNetwork mqttNetwork(network);
-
-    MQTT::Client<MQTTNetwork, Countdown> client(mqttNetwork);
-
-    const char* hostname = "m2m.eclipse.org";
-    int port = 1883;
-    logMessage("Connecting to %s:%d\r\n", hostname, port);
-    int rc = mqttNetwork.connect(hostname, port);
-    if (rc != 0)
-        logMessage("rc from TCP connect is %d\r\n", rc);
-
-    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
-    data.MQTTVersion = 3;
-    data.clientID.cstring = "mbed-sample";
-    data.username.cstring = "testuser";
-    data.password.cstring = "testpassword";
-    if ((rc = client.connect(data)) != 0)
-        logMessage("rc from MQTT connect is %d\r\n", rc);
-
-    if ((rc = client.subscribe(topic, MQTT::QOS2, messageArrived)) != 0)
-        logMessage("rc from MQTT subscribe is %d\r\n", rc);
-
-    MQTT::Message message;
-
-    // QoS 0
-    char buf[100];
-    sprintf(buf, "Hello World!  QoS 0 message from app version %f\r\n", version);
-    message.qos = MQTT::QOS0;
-    message.retained = false;
-    message.dup = false;
-    message.payload = (void*)buf;
-    message.payloadlen = strlen(buf)+1;
-    rc = client.publish(topic, message);
-    while (arrivedcount < 1)
-        client.yield(100);
-
-    // QoS 1
-    sprintf(buf, "Hello World!  QoS 1 message from app version %f\r\n", version);
-    message.qos = MQTT::QOS1;
-    message.payloadlen = strlen(buf)+1;
-    rc = client.publish(topic, message);
-    while (arrivedcount < 2)
-        client.yield(100);
-
-    // QoS 2
-    sprintf(buf, "Hello World!  QoS 2 message from app version %f\r\n", version);
-    message.qos = MQTT::QOS2;
-    message.payloadlen = strlen(buf)+1;
-    rc = client.publish(topic, message);
-    while (arrivedcount < 3)
-        client.yield(100);
-
-    if ((rc = client.unsubscribe(topic)) != 0)
-        logMessage("rc from unsubscribe was %d\r\n", rc);
-
-    if ((rc = client.disconnect()) != 0)
-        logMessage("rc from disconnect was %d\r\n", rc);
-
-    mqttNetwork.disconnect();
-
-    logMessage("Version %.2f: finish %d msgs\r\n", version, arrivedcount);
+    deconnection();
+    pc.printf("Disconnect from MQTT network. End of program, %d messages arrived\r\n",arrivedcount);
 
     return 0;
 }
--- a/mbed_app.json	Tue Jan 16 13:41:29 2018 +0000
+++ b/mbed_app.json	Thu Jun 11 14:09:40 2020 +0000
@@ -2,7 +2,7 @@
     "config": {
         "network-interface":{
             "help": "options are ETHERNET, WIFI_ESP8266, WIFI_ODIN, WIFI_RTW, MESH_LOWPAN_ND, MESH_THREAD, CELLULAR_ONBOARD",
-            "value": "ETHERNET"
+            "value": "WIFI_ESP8266"
         },
         "mesh_radio_type": {
             "help": "options are ATMEL, MCR20",
@@ -10,40 +10,20 @@
         },
         "esp8266-tx": {
             "help": "Pin used as TX (connects to ESP8266 RX)",
-            "value": "D1"
+            "value": "D8"
         },
         "esp8266-rx": {
             "help": "Pin used as RX (connects to ESP8266 TX)",
-            "value": "D0"
+            "value": "D2"
         },
         "esp8266-ssid": {
-            "value": "\"SSID\""
+            "value": "\"spockWIFI3\""
         },
         "esp8266-password": {
-            "value": "\"Password\""
+            "value": "\"voyager8472ncc1701a\""
         },
         "esp8266-debug": {
-            "value": true
-        },
-        "lcd-mosi": {
-            "value": "D11",
-            "macro_name": "LCD_MOSI"
-        },
-        "lcd-sck": {
-            "value": "D13",
-            "macro_name": "LCD_SCK"
-        },
-        "lcd-miso": {
-            "value": "D12",
-            "macro_name": "LCD_MISO"
-        },
-        "lcd-a0": {
-            "value": "D7",
-            "macro_name": "LCD_A0"
-        },
-        "lcd-ncs": {
-            "value": "D10",
-            "macro_name": "LCD_NCS"
+            "value": false
         }
     },
     "target_overrides": {