MQTT demo program for Nucleo F401RE and Seeedstudio W5200 Ethernet Shield which is based on Wiznet IBMIoTClientEthernetExample_W5500.

Dependencies:   MQTT W5200Interface mbed DHT11

Fork of IBMIoTClientEthernetExample_W5500 by W5500-Ethernet-Interface Makers

I post description regarding this source code here.

http://developer.mbed.org/users/hillkim7/notebook/ibmiotclientethernetexample_w5200/

Committer:
hillkim7
Date:
Thu Dec 25 11:25:49 2014 +0000
Revision:
3:64a7d39e423b
Parent:
2:87c816cd88e2
Child:
4:0c9bdee36e2a
MQTT client demo with Nucleo F401RE + Seeedstudio W5200 Ethernet Shield.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kaizen 0:910036879da0 1 #include "mbed.h"
kaizen 0:910036879da0 2 #include "MQTTClient.h"
kaizen 0:910036879da0 3 #include "MQTTEthernet.h"
kaizen 0:910036879da0 4
hillkim7 3:64a7d39e423b 5 /* Dec 25, 2014
hillkim7 3:64a7d39e423b 6 This tutorial program is written to test IBM MQTT client functionality.
hillkim7 3:64a7d39e423b 7 This program is based on sample from Wiznet team but they only provides sample for W5500 chip.
hillkim7 3:64a7d39e423b 8 http://developer.mbed.org/teams/EthernetInterfaceW5500-makers/
hillkim7 3:64a7d39e423b 9 So I import that program and change it to run on W5200 chip.
hillkim7 3:64a7d39e423b 10
hillkim7 3:64a7d39e423b 11 You don't need to subscribe IBM cloud service to test demo.
hillkim7 3:64a7d39e423b 12 You can check it in QUICKSTARTMODE 1.
hillkim7 3:64a7d39e423b 13
hillkim7 3:64a7d39e423b 14 Test Environment:
hillkim7 3:64a7d39e423b 15 Nucleo F401RE + Seeedstudio W5200 Ethernet Shield.
hillkim7 3:64a7d39e423b 16
hillkim7 3:64a7d39e423b 17 Before you run this sample it is strongly recommended to read quick overview page from IBM.
hillkim7 3:64a7d39e423b 18 https://developer.ibm.com/iot/recipes/improvise-connect-quickstart/
hillkim7 3:64a7d39e423b 19
hillkim7 3:64a7d39e423b 20 Once you are success to compile and run this sample you can see demo result with your web browser
hillkim7 3:64a7d39e423b 21 by typing MAC address in " https://quickstart.internetofthings.ibmcloud.com/".
hillkim7 3:64a7d39e423b 22 Don't forget to change hard-coded MAC address in "W5200.cpp" file.
hillkim7 3:64a7d39e423b 23
hillkim7 3:64a7d39e423b 24
hillkim7 3:64a7d39e423b 25 Keep in mind, MAC address in client ID field should be lowercase.
hillkim7 3:64a7d39e423b 26 Original Wiznet code don't consider this and took my time.
hillkim7 3:64a7d39e423b 27 char id[30] = ID; // <<---- MAC address in this variable
hillkim7 3:64a7d39e423b 28 */
hillkim7 3:64a7d39e423b 29
kaizen 0:910036879da0 30 // Configuration values needed to connect to IBM IoT Cloud
hillkim7 3:64a7d39e423b 31 // Defined "QUICKSTARTMODE 1" unless you subscribed IBM IoT service.
hillkim7 3:64a7d39e423b 32
hillkim7 3:64a7d39e423b 33 #define QUICKSTARTMODE 1
hillkim7 3:64a7d39e423b 34
kaizen 0:910036879da0 35 #if (QUICKSTARTMODE)
hillkim7 3:64a7d39e423b 36 // Configuration values needed to connect to IBM IoT Cloud
hillkim7 3:64a7d39e423b 37 #define ORG "quickstart" // For a registered connection, replace with your org
hillkim7 3:64a7d39e423b 38 #define ID "" // For a registered connection, replace with your id
hillkim7 3:64a7d39e423b 39 #define AUTH_TOKEN "" // For a registered connection, replace with your auth-token
hillkim7 3:64a7d39e423b 40 #define TYPE "iotsample-mbed-nucleo"
kaizen 0:910036879da0 41 #else
kaizen 1:532d83b9f910 42 #define ORG "uasfg"
kaizen 1:532d83b9f910 43 #define ID ""
kaizen 1:532d83b9f910 44 #define AUTH_TOKEN "mhhWy4Qg)C*w3jL@(O"
kaizen 1:532d83b9f910 45 #define TYPE "W5500"
kaizen 0:910036879da0 46 #endif
kaizen 0:910036879da0 47
kaizen 0:910036879da0 48 #define MQTT_PORT 1883
kaizen 0:910036879da0 49 #define MQTT_TLS_PORT 8883
kaizen 0:910036879da0 50 #define IBM_IOT_PORT MQTT_PORT
kaizen 0:910036879da0 51
kaizen 0:910036879da0 52 #define MQTT_MAX_PACKET_SIZE 250
kaizen 0:910036879da0 53
kaizen 0:910036879da0 54
kaizen 1:532d83b9f910 55 #define USING_HW_STACK_W5500
kaizen 1:532d83b9f910 56
kaizen 0:910036879da0 57 bool quickstartMode = (QUICKSTARTMODE) ? true : false;
kaizen 0:910036879da0 58 char org[11] = ORG;
kaizen 0:910036879da0 59 char type[30] = TYPE;
kaizen 0:910036879da0 60 char id[30] = ID; // mac without colons
kaizen 0:910036879da0 61 char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode
kaizen 0:910036879da0 62
kaizen 0:910036879da0 63 bool connected = false;
kaizen 0:910036879da0 64
kaizen 0:910036879da0 65
kaizen 0:910036879da0 66 char* getMac(EthernetInterface& eth, char* buf, int buflen) // Obtain MAC address
kaizen 0:910036879da0 67 {
kaizen 1:532d83b9f910 68 strncpy(buf, eth.getMACAddress(), buflen);
kaizen 0:910036879da0 69
kaizen 0:910036879da0 70 char* pos; // Remove colons from mac address
kaizen 0:910036879da0 71 while ((pos = strchr(buf, ':')) != NULL)
kaizen 0:910036879da0 72 memmove(pos, pos + 1, strlen(pos) + 1);
hillkim7 3:64a7d39e423b 73
hillkim7 3:64a7d39e423b 74 size_t len = strlen(buf);
hillkim7 3:64a7d39e423b 75 while (len-- > 0)
hillkim7 3:64a7d39e423b 76 if (buf[len] >= 'A' && buf[len] <= 'Z')
hillkim7 3:64a7d39e423b 77 {
hillkim7 3:64a7d39e423b 78 buf[len] = buf[len] + ('a' - 'A');
hillkim7 3:64a7d39e423b 79 }
kaizen 0:910036879da0 80 return buf;
kaizen 0:910036879da0 81 }
kaizen 0:910036879da0 82
kaizen 0:910036879da0 83
kaizen 0:910036879da0 84 int connect(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack)
kaizen 0:910036879da0 85 {
kaizen 0:910036879da0 86 const char* iot_ibm = ".messaging.internetofthings.ibmcloud.com";
kaizen 0:910036879da0 87
kaizen 0:910036879da0 88 char hostname[strlen(org) + strlen(iot_ibm) + 1];
kaizen 0:910036879da0 89 sprintf(hostname, "%s%s", org, iot_ibm);
hillkim7 3:64a7d39e423b 90
hillkim7 3:64a7d39e423b 91 //strcpy(hostname, "192.168.11.203");
hillkim7 3:64a7d39e423b 92 DEBUG("connect host='%s' port=%u\r\n", hostname, IBM_IOT_PORT);
kaizen 0:910036879da0 93 int rc = ipstack->connect(hostname, IBM_IOT_PORT);
kaizen 1:532d83b9f910 94
kaizen 0:910036879da0 95 if (rc != 0)
kaizen 0:910036879da0 96 return rc;
kaizen 0:910036879da0 97
kaizen 0:910036879da0 98 // Construct clientId - d:org:type:id
kaizen 0:910036879da0 99 char clientId[strlen(org) + strlen(type) + strlen(id) + 5];
kaizen 0:910036879da0 100 sprintf(clientId, "d:%s:%s:%s", org, type, id);
kaizen 0:910036879da0 101 DEBUG("clientid is %s\r\n", clientId);
kaizen 0:910036879da0 102
kaizen 0:910036879da0 103 // MQTT Connect
kaizen 0:910036879da0 104 MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
kaizen 0:910036879da0 105 data.MQTTVersion = 3;
kaizen 0:910036879da0 106 data.clientID.cstring = clientId;
kaizen 0:910036879da0 107
kaizen 0:910036879da0 108 if (!quickstartMode)
kaizen 0:910036879da0 109 {
kaizen 0:910036879da0 110 data.username.cstring = "use-token-auth";
kaizen 0:910036879da0 111 data.password.cstring = auth_token;
kaizen 0:910036879da0 112 }
kaizen 0:910036879da0 113
kaizen 0:910036879da0 114 if ((rc = client->connect(&data)) == 0)
kaizen 0:910036879da0 115 {
kaizen 0:910036879da0 116 connected = true;
kaizen 0:910036879da0 117 }
hillkim7 3:64a7d39e423b 118 else
hillkim7 3:64a7d39e423b 119 {
hillkim7 3:64a7d39e423b 120 WARN("MQTT client connect error: %d\r\n", rc);
hillkim7 3:64a7d39e423b 121 }
kaizen 1:532d83b9f910 122
kaizen 0:910036879da0 123 return rc;
kaizen 0:910036879da0 124 }
kaizen 0:910036879da0 125
kaizen 0:910036879da0 126
kaizen 0:910036879da0 127 int getConnTimeout(int attemptNumber)
kaizen 0:910036879da0 128 { // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute
kaizen 0:910036879da0 129 // after 20 attempts, retry every 10 minutes
kaizen 0:910036879da0 130 return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600;
kaizen 0:910036879da0 131 }
kaizen 0:910036879da0 132
kaizen 0:910036879da0 133
kaizen 0:910036879da0 134 void attemptConnect(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack)
kaizen 0:910036879da0 135 {
kaizen 0:910036879da0 136 int retryAttempt = 0;
kaizen 0:910036879da0 137 connected = false;
kaizen 0:910036879da0 138
kaizen 0:910036879da0 139 // make sure a cable is connected before starting to connect
kaizen 0:910036879da0 140 while ( !ipstack->getEth().linkstatus() ) {
kaizen 0:910036879da0 141 wait(1.0f);
kaizen 0:910036879da0 142 WARN("Ethernet link not present. Check cable connection\r\n");
kaizen 0:910036879da0 143 }
kaizen 0:910036879da0 144
kaizen 0:910036879da0 145 while (connect(client, ipstack) != 0)
kaizen 0:910036879da0 146 {
kaizen 0:910036879da0 147 int timeout = getConnTimeout(++retryAttempt);
kaizen 0:910036879da0 148 WARN("Retry attempt number %d waiting %d\r\n", retryAttempt, timeout);
kaizen 0:910036879da0 149 wait(timeout);
kaizen 0:910036879da0 150 }
kaizen 0:910036879da0 151 }
kaizen 0:910036879da0 152
kaizen 0:910036879da0 153 int publish(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack)
kaizen 0:910036879da0 154 {
kaizen 0:910036879da0 155 MQTT::Message message;
kaizen 0:910036879da0 156 char* pubTopic = "iot-2/evt/status/fmt/json";
kaizen 0:910036879da0 157
kaizen 0:910036879da0 158 char buf[250];
kaizen 0:910036879da0 159 sprintf(buf,
hillkim7 3:64a7d39e423b 160 "{\"d\":{\"myName\":\"IoT mbed\",\"test_value\":%d}}",
hillkim7 3:64a7d39e423b 161 12+(rand()%10));
kaizen 0:910036879da0 162
kaizen 0:910036879da0 163 message.qos = MQTT::QOS0;
kaizen 0:910036879da0 164 message.retained = false;
kaizen 0:910036879da0 165 message.dup = false;
kaizen 0:910036879da0 166 message.payload = (void*)buf;
kaizen 0:910036879da0 167 message.payloadlen = strlen(buf);
kaizen 0:910036879da0 168
kaizen 0:910036879da0 169 LOG("Publishing %s\r\n", buf);
kaizen 0:910036879da0 170 return client->publish(pubTopic, &message);
kaizen 0:910036879da0 171 }
kaizen 0:910036879da0 172
kaizen 0:910036879da0 173
kaizen 0:910036879da0 174 void messageArrived(MQTT::MessageData& md)
kaizen 0:910036879da0 175 {
kaizen 0:910036879da0 176 MQTT::Message &message = md.message;
kaizen 0:910036879da0 177 char topic[md.topicName.lenstring.len + 1];
kaizen 0:910036879da0 178
kaizen 0:910036879da0 179 sprintf(topic, "%.*s", md.topicName.lenstring.len, md.topicName.lenstring.data);
kaizen 0:910036879da0 180
kaizen 0:910036879da0 181 LOG("Message arrived on topic %s: %.*s\r\n", topic, message.payloadlen, message.payload);
kaizen 0:910036879da0 182
kaizen 0:910036879da0 183 // Command topic: iot-2/cmd/blink/fmt/json - cmd is the string between cmd/ and /fmt/
kaizen 0:910036879da0 184 char* start = strstr(topic, "/cmd/") + 5;
kaizen 0:910036879da0 185 int len = strstr(topic, "/fmt/") - start;
kaizen 0:910036879da0 186
kaizen 0:910036879da0 187 if (memcmp(start, "blink", len) == 0)
kaizen 0:910036879da0 188 {
kaizen 0:910036879da0 189 char payload[message.payloadlen + 1];
kaizen 0:910036879da0 190 sprintf(payload, "%.*s", message.payloadlen, (char*)message.payload);
kaizen 0:910036879da0 191
kaizen 0:910036879da0 192 char* pos = strchr(payload, '}');
kaizen 0:910036879da0 193 if (pos != NULL)
kaizen 0:910036879da0 194 {
kaizen 0:910036879da0 195 *pos = '\0';
kaizen 0:910036879da0 196 if ((pos = strchr(payload, ':')) != NULL)
kaizen 0:910036879da0 197 {
kaizen 0:910036879da0 198 }
kaizen 0:910036879da0 199 }
kaizen 0:910036879da0 200 }
kaizen 0:910036879da0 201 else
kaizen 0:910036879da0 202 WARN("Unsupported command: %.*s\r\n", len, start);
kaizen 0:910036879da0 203 }
kaizen 0:910036879da0 204
kaizen 0:910036879da0 205 int main()
kaizen 0:910036879da0 206 {
hillkim7 3:64a7d39e423b 207 //#if defined(TARGET_KL25Z)
kaizen 2:87c816cd88e2 208 Serial pc(USBTX, USBRX);
kaizen 2:87c816cd88e2 209 pc.baud(115200);
kaizen 2:87c816cd88e2 210
kaizen 2:87c816cd88e2 211 SPI spi(D11, D12, D13); // mosi, miso, sclk
kaizen 2:87c816cd88e2 212 wait(1);
hillkim7 3:64a7d39e423b 213
hillkim7 3:64a7d39e423b 214 #if defined(TARGET_STM32F401RE)
hillkim7 3:64a7d39e423b 215 MQTTEthernet ipstack(&spi, D10, D5);
hillkim7 3:64a7d39e423b 216 #else
kaizen 2:87c816cd88e2 217 MQTTEthernet ipstack(&spi, D10, D9); //scs(D10), nRESET(PTA20)
hillkim7 3:64a7d39e423b 218 #endif
kaizen 2:87c816cd88e2 219 MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE> client(ipstack);
hillkim7 3:64a7d39e423b 220 //#endif
kaizen 0:910036879da0 221
hillkim7 3:64a7d39e423b 222 LOG("ETH MAC: %s IP: %s GW: %s\r\n",
hillkim7 3:64a7d39e423b 223 ipstack.getEth().getMACAddress(),
hillkim7 3:64a7d39e423b 224 ipstack.getEth().getIPAddress(),
hillkim7 3:64a7d39e423b 225 ipstack.getEth().getGateway());
kaizen 1:532d83b9f910 226 getMac(ipstack.getEth(), id, sizeof(id));
hillkim7 3:64a7d39e423b 227 LOG("attemptConnect\r\n");
kaizen 0:910036879da0 228 attemptConnect(&client, &ipstack);
kaizen 0:910036879da0 229
kaizen 0:910036879da0 230 int count = 0;
kaizen 0:910036879da0 231 while (true)
kaizen 0:910036879da0 232 {
kaizen 0:910036879da0 233 if (!ipstack.getEth().linkstatus()) {
hillkim7 3:64a7d39e423b 234 WARN("Reset on link down\r\n");
hillkim7 3:64a7d39e423b 235 wait(1);
kaizen 0:910036879da0 236 NVIC_SystemReset();
kaizen 0:910036879da0 237 // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed
kaizen 0:910036879da0 238 // or maybe just add the proper members to do this disconnect and call attemptConnect(...)
kaizen 0:910036879da0 239 }
kaizen 0:910036879da0 240
kaizen 0:910036879da0 241 if (++count == 100)
kaizen 0:910036879da0 242 { // Publish a message every second
kaizen 0:910036879da0 243 if (publish(&client, &ipstack) != 0)
hillkim7 3:64a7d39e423b 244 {
hillkim7 3:64a7d39e423b 245 WARN("publish error\r\n");
hillkim7 3:64a7d39e423b 246 //attemptConnect(&client, &ipstack); // if we have lost the connection
hillkim7 3:64a7d39e423b 247 }
kaizen 0:910036879da0 248 count = 0;
kaizen 0:910036879da0 249 }
kaizen 0:910036879da0 250
kaizen 0:910036879da0 251 client.yield(10); // allow the MQTT client to receive messages
kaizen 0:910036879da0 252 }
kaizen 0:910036879da0 253 }
hillkim7 3:64a7d39e423b 254