Example project to publish messages to a MQTT-SN broker using the u-blox SARA-N200 NB-IoT modem

Dependencies:   MQTTSNPacket X-NUCLEO-SARA-N200

Committer:
KeystoneElectronic
Date:
Wed Aug 22 16:31:30 2018 +0200
Revision:
7:ab32680de141
Parent:
6:16be6bf59d30
Use json

Who changed what in which revision?

UserRevisionLine numberNew contents of line
keystone.electronic.solutions@gmail.com 1:70b751b7a189 1 #include <stdio.h>
keystone.electronic.solutions@gmail.com 1:70b751b7a189 2 #include <Serial.h>
KeystoneElectronic 0:c0cf12ee5420 3
keystone.electronic.solutions@gmail.com 1:70b751b7a189 4 #include "mbed.h"
keystone.electronic.solutions@gmail.com 1:70b751b7a189 5 #include "sara_n2.h"
keystone.electronic.solutions@gmail.com 1:70b751b7a189 6 #include "MQTTmbed.h"
keystone.electronic.solutions@gmail.com 1:70b751b7a189 7 #include "MQTTSNUDP.h"
keystone.electronic.solutions@gmail.com 1:70b751b7a189 8 #include "MQTTSNClient.h"
keystone.electronic.solutions@gmail.com 1:70b751b7a189 9
keystone.electronic.solutions@gmail.com 1:70b751b7a189 10 Serial pc(SERIAL_TX, SERIAL_RX, 115200);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 11 DigitalOut myled(LED1);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 12 InterruptIn button(USER_BUTTON);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 13 UARTSerial sara(PA_9, PA_10, 9600);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 14 DigitalOut sara_reset(D7);
KeystoneElectronic 0:c0cf12ee5420 15
keystone.electronic.solutions@gmail.com 1:70b751b7a189 16 //#define INFO_TRACE(_class, _string, ...) printf( "%8s: " _string, _class, ##__VA_ARGS__)
keystone.electronic.solutions@gmail.com 1:70b751b7a189 17 #undef TRACE
keystone.electronic.solutions@gmail.com 1:70b751b7a189 18 #define TRACE(_string, ...) INFO_TRACE( "MQTT", _string, ##__VA_ARGS__ )
keystone.electronic.solutions@gmail.com 1:70b751b7a189 19
keystone.electronic.solutions@gmail.com 1:70b751b7a189 20 float led_flash_rate = 0.5;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 21
keystone.electronic.solutions@gmail.com 1:70b751b7a189 22 void messageArrived(MQTTSN::MessageData& md)
keystone.electronic.solutions@gmail.com 1:70b751b7a189 23 {
keystone.electronic.solutions@gmail.com 1:70b751b7a189 24 MQTTSN::Message &message = md.message;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 25 TRACE("Message arrived: qos %d, retained %d, dup %d, packetid %d\n",
keystone.electronic.solutions@gmail.com 1:70b751b7a189 26 message.qos,
keystone.electronic.solutions@gmail.com 1:70b751b7a189 27 message.retained,
keystone.electronic.solutions@gmail.com 1:70b751b7a189 28 message.dup,
keystone.electronic.solutions@gmail.com 1:70b751b7a189 29 message.id);
KeystoneElectronic 7:ab32680de141 30 char *payload = (char*)message.payload;
KeystoneElectronic 7:ab32680de141 31 payload[message.payloadlen] = 0;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 32
KeystoneElectronic 7:ab32680de141 33 TRACE("Payload %s\n", payload);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 34 char *ptr;
KeystoneElectronic 7:ab32680de141 35 float new_rate = strtof((const char*)payload, &ptr);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 36 if(new_rate > 0)
keystone.electronic.solutions@gmail.com 1:70b751b7a189 37 {
keystone.electronic.solutions@gmail.com 1:70b751b7a189 38 TRACE("New rate %f\n", new_rate);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 39 led_flash_rate = new_rate;
KeystoneElectronic 0:c0cf12ee5420 40 }
KeystoneElectronic 0:c0cf12ee5420 41 }
KeystoneElectronic 0:c0cf12ee5420 42
keystone.electronic.solutions@gmail.com 1:70b751b7a189 43 enum eMQTTstates
keystone.electronic.solutions@gmail.com 1:70b751b7a189 44 {
keystone.electronic.solutions@gmail.com 1:70b751b7a189 45 MQTT_SOCKET_DISCONNECTED,
keystone.electronic.solutions@gmail.com 1:70b751b7a189 46 MQTT_SOCKET_CONNECTED,
keystone.electronic.solutions@gmail.com 1:70b751b7a189 47 MQTT_CLIENT_CONNECTED,
keystone.electronic.solutions@gmail.com 1:70b751b7a189 48 MQTT_CLIENT_PUBLISH,
keystone.electronic.solutions@gmail.com 1:70b751b7a189 49 MQTT_CLIENT_SUBSCRIBED
keystone.electronic.solutions@gmail.com 1:70b751b7a189 50 }mMQTTstate;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 51
keystone.electronic.solutions@gmail.com 1:70b751b7a189 52
keystone.electronic.solutions@gmail.com 1:70b751b7a189 53 SARA_N2 sara_mdm(&sara, &sara_reset);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 54 MQTTSNUDP ipsocket = MQTTSNUDP(&sara_mdm);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 55 MQTTSNPacket_connectData data = MQTTSNPacket_connectData_initializer;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 56 MQTTSN_topicid topicid;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 57 MQTTSN::QoS grantedQoS;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 58 char topicString[64];
KeystoneElectronic 7:ab32680de141 59 char publishMessage[32];
KeystoneElectronic 7:ab32680de141 60 bool buttonPressed = false;
KeystoneElectronic 7:ab32680de141 61 int aliveCount = 0;
KeystoneElectronic 7:ab32680de141 62 int colorIndex = 0;
KeystoneElectronic 7:ab32680de141 63 char sendBuffer[512];
KeystoneElectronic 7:ab32680de141 64
KeystoneElectronic 7:ab32680de141 65 char *colorNames[] =
KeystoneElectronic 7:ab32680de141 66 {
KeystoneElectronic 7:ab32680de141 67 "red",
KeystoneElectronic 7:ab32680de141 68 "green",
KeystoneElectronic 7:ab32680de141 69 "yellow",
KeystoneElectronic 7:ab32680de141 70 "blue",
KeystoneElectronic 7:ab32680de141 71 "grey"
KeystoneElectronic 7:ab32680de141 72 };
keystone.electronic.solutions@gmail.com 1:70b751b7a189 73
KeystoneElectronic 7:ab32680de141 74 void fillMessage(char *msg)
KeystoneElectronic 7:ab32680de141 75 {
KeystoneElectronic 7:ab32680de141 76 char temp[64];
keystone.electronic.solutions@gmail.com 1:70b751b7a189 77
KeystoneElectronic 7:ab32680de141 78 sprintf(msg, "{\"IMEA\":\"%s\",", sara_mdm.getIMEA());
KeystoneElectronic 7:ab32680de141 79 sprintf(temp, "\"SIM\":\"%s\",", sara_mdm.getSIMserial());
KeystoneElectronic 7:ab32680de141 80 strcat(msg, temp);
KeystoneElectronic 7:ab32680de141 81 sprintf(temp, "\"message\":\"%s\",", publishMessage);
KeystoneElectronic 7:ab32680de141 82 strcat(msg, temp);
KeystoneElectronic 7:ab32680de141 83 sprintf(temp, "\"color\":\"%s\",", colorNames[colorIndex]);
KeystoneElectronic 7:ab32680de141 84 strcat(msg, temp);
KeystoneElectronic 7:ab32680de141 85 sprintf(temp, "\"alive\":%d}", aliveCount);
KeystoneElectronic 7:ab32680de141 86 strcat(msg, temp);
KeystoneElectronic 7:ab32680de141 87 }
KeystoneElectronic 5:749a8fb7f27e 88
keystone.electronic.solutions@gmail.com 1:70b751b7a189 89 void mqtt_fsm(MQTTSN::Client<MQTTSNUDP, Countdown> *client)
keystone.electronic.solutions@gmail.com 1:70b751b7a189 90 {
keystone.electronic.solutions@gmail.com 1:70b751b7a189 91 static int pub_count = 0;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 92 switch(mMQTTstate)
keystone.electronic.solutions@gmail.com 1:70b751b7a189 93 {
keystone.electronic.solutions@gmail.com 1:70b751b7a189 94 case MQTT_SOCKET_DISCONNECTED:
keystone.electronic.solutions@gmail.com 1:70b751b7a189 95 {
keystone.electronic.solutions@gmail.com 1:70b751b7a189 96 const char* hostname = MBED_CONF_APP_MQTT_SN_HOST;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 97 int port = MBED_CONF_APP_MQTT_SN_PORT;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 98 TRACE("Connecting to %s:%d\n", hostname, port);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 99 int socket = ipsocket.connect((char*)hostname, port);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 100 if(socket >= 0)
keystone.electronic.solutions@gmail.com 1:70b751b7a189 101 {
keystone.electronic.solutions@gmail.com 1:70b751b7a189 102 TRACE("Socket connected - %d\n", socket);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 103 mMQTTstate = MQTT_SOCKET_CONNECTED;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 104 }
keystone.electronic.solutions@gmail.com 1:70b751b7a189 105 }
keystone.electronic.solutions@gmail.com 1:70b751b7a189 106 break;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 107
keystone.electronic.solutions@gmail.com 1:70b751b7a189 108 case MQTT_SOCKET_CONNECTED:
keystone.electronic.solutions@gmail.com 1:70b751b7a189 109 {
keystone.electronic.solutions@gmail.com 1:70b751b7a189 110 data.clientID.cstring = (char*)"NUCLEO_NB-IoT";
keystone.electronic.solutions@gmail.com 1:70b751b7a189 111 data.duration = 100;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 112 int rc = client->connect(data);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 113 TRACE("Connect - %d\n", rc);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 114 if(rc == MQTTSN::SUCCESS)
keystone.electronic.solutions@gmail.com 1:70b751b7a189 115 {
keystone.electronic.solutions@gmail.com 1:70b751b7a189 116 printf("Client Connected\n");
keystone.electronic.solutions@gmail.com 1:70b751b7a189 117 mMQTTstate = MQTT_CLIENT_CONNECTED;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 118 }
keystone.electronic.solutions@gmail.com 1:70b751b7a189 119 }
keystone.electronic.solutions@gmail.com 1:70b751b7a189 120 break;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 121 case MQTT_CLIENT_CONNECTED:
keystone.electronic.solutions@gmail.com 1:70b751b7a189 122 {
keystone.electronic.solutions@gmail.com 1:70b751b7a189 123 topicid.type = MQTTSN_TOPIC_TYPE_NORMAL;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 124 topicid.data.long_.name = topicString;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 125 topicid.data.long_.len = strlen(topicString);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 126 int rc = client->subscribe(topicid, MQTTSN::QOS1, grantedQoS, messageArrived);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 127 TRACE("Subscribe - %d\n", rc);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 128 if(rc == MQTTSN::SUCCESS)
keystone.electronic.solutions@gmail.com 1:70b751b7a189 129 {
keystone.electronic.solutions@gmail.com 1:70b751b7a189 130 printf("Client Subscribed\n");
keystone.electronic.solutions@gmail.com 1:70b751b7a189 131 mMQTTstate = MQTT_CLIENT_PUBLISH;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 132 }
keystone.electronic.solutions@gmail.com 1:70b751b7a189 133 }
keystone.electronic.solutions@gmail.com 1:70b751b7a189 134 break;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 135 case MQTT_CLIENT_PUBLISH:
keystone.electronic.solutions@gmail.com 1:70b751b7a189 136 {
keystone.electronic.solutions@gmail.com 1:70b751b7a189 137 pub_count = 0;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 138
KeystoneElectronic 7:ab32680de141 139 fillMessage(sendBuffer);
KeystoneElectronic 7:ab32680de141 140
keystone.electronic.solutions@gmail.com 1:70b751b7a189 141 MQTTSN::Message message;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 142 message.qos = MQTTSN::QOS0;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 143 message.retained = false;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 144 message.dup = false;
KeystoneElectronic 7:ab32680de141 145 message.payload = (void*)sendBuffer;
KeystoneElectronic 7:ab32680de141 146 message.payloadlen = strlen(sendBuffer);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 147 int rc = client->publish(topicid, message);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 148 if(rc == MQTTSN::SUCCESS)
keystone.electronic.solutions@gmail.com 1:70b751b7a189 149 {
KeystoneElectronic 7:ab32680de141 150 TRACE("Publishes %s\n", sendBuffer);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 151 }
keystone.electronic.solutions@gmail.com 1:70b751b7a189 152
keystone.electronic.solutions@gmail.com 1:70b751b7a189 153 mMQTTstate = MQTT_CLIENT_SUBSCRIBED;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 154 }
keystone.electronic.solutions@gmail.com 1:70b751b7a189 155 break;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 156 case MQTT_CLIENT_SUBSCRIBED:
keystone.electronic.solutions@gmail.com 1:70b751b7a189 157 {
keystone.electronic.solutions@gmail.com 1:70b751b7a189 158 client->yield(100);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 159
keystone.electronic.solutions@gmail.com 1:70b751b7a189 160 if(buttonPressed)
keystone.electronic.solutions@gmail.com 1:70b751b7a189 161 {
keystone.electronic.solutions@gmail.com 1:70b751b7a189 162 buttonPressed = false;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 163 mMQTTstate = MQTT_CLIENT_PUBLISH;
KeystoneElectronic 7:ab32680de141 164
KeystoneElectronic 7:ab32680de141 165 sprintf(publishMessage, "Color changed");
KeystoneElectronic 7:ab32680de141 166 if(++colorIndex > 4)
KeystoneElectronic 7:ab32680de141 167 colorIndex = 0;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 168 }
keystone.electronic.solutions@gmail.com 1:70b751b7a189 169
KeystoneElectronic 6:16be6bf59d30 170 if(pub_count++ > 100)
keystone.electronic.solutions@gmail.com 1:70b751b7a189 171 {
keystone.electronic.solutions@gmail.com 1:70b751b7a189 172 mMQTTstate = MQTT_CLIENT_PUBLISH;
KeystoneElectronic 7:ab32680de141 173 sprintf(publishMessage, "X-Nucleo is alive");
keystone.electronic.solutions@gmail.com 1:70b751b7a189 174
KeystoneElectronic 7:ab32680de141 175 aliveCount++;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 176 }
keystone.electronic.solutions@gmail.com 1:70b751b7a189 177
keystone.electronic.solutions@gmail.com 1:70b751b7a189 178 }
keystone.electronic.solutions@gmail.com 1:70b751b7a189 179 break;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 180 }
keystone.electronic.solutions@gmail.com 1:70b751b7a189 181 }
keystone.electronic.solutions@gmail.com 1:70b751b7a189 182
keystone.electronic.solutions@gmail.com 1:70b751b7a189 183 void pressedEvent()
keystone.electronic.solutions@gmail.com 1:70b751b7a189 184 {
keystone.electronic.solutions@gmail.com 1:70b751b7a189 185 buttonPressed = true;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 186 }
keystone.electronic.solutions@gmail.com 1:70b751b7a189 187
keystone.electronic.solutions@gmail.com 1:70b751b7a189 188 int main(void)
keystone.electronic.solutions@gmail.com 1:70b751b7a189 189 {
keystone.electronic.solutions@gmail.com 1:70b751b7a189 190 printf("\n\nNUCLEO_X_SARA-N200 HelloMQTT-SN\n");
keystone.electronic.solutions@gmail.com 1:70b751b7a189 191 printf("Version: 0x%08X\n", MBED_CONF_APP_VERSION);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 192 printf("mbed-os: %d.%d.%d\n", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 193
keystone.electronic.solutions@gmail.com 1:70b751b7a189 194 strcpy(topicString, MBED_CONF_APP_TOPIC);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 195 sprintf(publishMessage, "NUCLEO NB-IoT online");
keystone.electronic.solutions@gmail.com 1:70b751b7a189 196 MQTTSN::Client<MQTTSNUDP, Countdown> client = MQTTSN::Client<MQTTSNUDP, Countdown>(ipsocket);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 197
keystone.electronic.solutions@gmail.com 1:70b751b7a189 198 button.fall(&pressedEvent);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 199
keystone.electronic.solutions@gmail.com 1:70b751b7a189 200 while(1)
keystone.electronic.solutions@gmail.com 1:70b751b7a189 201 {
keystone.electronic.solutions@gmail.com 1:70b751b7a189 202 wait(led_flash_rate);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 203 myled = 1;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 204 wait(led_flash_rate);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 205 myled = 0;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 206
keystone.electronic.solutions@gmail.com 1:70b751b7a189 207 sara_mdm.fsm();
keystone.electronic.solutions@gmail.com 1:70b751b7a189 208 mqtt_fsm(&client);
keystone.electronic.solutions@gmail.com 1:70b751b7a189 209 }
keystone.electronic.solutions@gmail.com 1:70b751b7a189 210
keystone.electronic.solutions@gmail.com 1:70b751b7a189 211
keystone.electronic.solutions@gmail.com 1:70b751b7a189 212 return 0;
keystone.electronic.solutions@gmail.com 1:70b751b7a189 213 }