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:
Fri Dec 26 07:54:23 2014 +0000
Revision:
4:0c9bdee36e2a
Parent:
3:64a7d39e423b
DHT11 module attached to update real temperature and humidity.

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
hillkim7 4:0c9bdee36e2a 35 // It shows real temperature and humidity with DHT11.
hillkim7 4:0c9bdee36e2a 36 #define DHT11_TEMPERATURE 0
hillkim7 4:0c9bdee36e2a 37
hillkim7 4:0c9bdee36e2a 38 #if DHT11_TEMPERATURE
hillkim7 4:0c9bdee36e2a 39 #include "DHT11.h"
hillkim7 4:0c9bdee36e2a 40
hillkim7 4:0c9bdee36e2a 41 DHT11 dht(D4);
hillkim7 4:0c9bdee36e2a 42
hillkim7 4:0c9bdee36e2a 43 #endif
hillkim7 4:0c9bdee36e2a 44
kaizen 0:910036879da0 45 #if (QUICKSTARTMODE)
hillkim7 3:64a7d39e423b 46 // Configuration values needed to connect to IBM IoT Cloud
hillkim7 3:64a7d39e423b 47 #define ORG "quickstart" // For a registered connection, replace with your org
hillkim7 3:64a7d39e423b 48 #define ID "" // For a registered connection, replace with your id
hillkim7 3:64a7d39e423b 49 #define AUTH_TOKEN "" // For a registered connection, replace with your auth-token
hillkim7 3:64a7d39e423b 50 #define TYPE "iotsample-mbed-nucleo"
kaizen 0:910036879da0 51 #else
kaizen 1:532d83b9f910 52 #define ORG "uasfg"
kaizen 1:532d83b9f910 53 #define ID ""
kaizen 1:532d83b9f910 54 #define AUTH_TOKEN "mhhWy4Qg)C*w3jL@(O"
kaizen 1:532d83b9f910 55 #define TYPE "W5500"
kaizen 0:910036879da0 56 #endif
kaizen 0:910036879da0 57
kaizen 0:910036879da0 58 #define MQTT_PORT 1883
kaizen 0:910036879da0 59 #define MQTT_TLS_PORT 8883
kaizen 0:910036879da0 60 #define IBM_IOT_PORT MQTT_PORT
kaizen 0:910036879da0 61
kaizen 0:910036879da0 62 #define MQTT_MAX_PACKET_SIZE 250
kaizen 0:910036879da0 63
kaizen 0:910036879da0 64
kaizen 1:532d83b9f910 65 #define USING_HW_STACK_W5500
kaizen 1:532d83b9f910 66
kaizen 0:910036879da0 67 bool quickstartMode = (QUICKSTARTMODE) ? true : false;
kaizen 0:910036879da0 68 char org[11] = ORG;
kaizen 0:910036879da0 69 char type[30] = TYPE;
kaizen 0:910036879da0 70 char id[30] = ID; // mac without colons
kaizen 0:910036879da0 71 char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode
kaizen 0:910036879da0 72
kaizen 0:910036879da0 73 bool connected = false;
kaizen 0:910036879da0 74
kaizen 0:910036879da0 75
kaizen 0:910036879da0 76 char* getMac(EthernetInterface& eth, char* buf, int buflen) // Obtain MAC address
kaizen 0:910036879da0 77 {
kaizen 1:532d83b9f910 78 strncpy(buf, eth.getMACAddress(), buflen);
kaizen 0:910036879da0 79
kaizen 0:910036879da0 80 char* pos; // Remove colons from mac address
kaizen 0:910036879da0 81 while ((pos = strchr(buf, ':')) != NULL)
kaizen 0:910036879da0 82 memmove(pos, pos + 1, strlen(pos) + 1);
hillkim7 3:64a7d39e423b 83
hillkim7 3:64a7d39e423b 84 size_t len = strlen(buf);
hillkim7 3:64a7d39e423b 85 while (len-- > 0)
hillkim7 3:64a7d39e423b 86 if (buf[len] >= 'A' && buf[len] <= 'Z')
hillkim7 3:64a7d39e423b 87 {
hillkim7 3:64a7d39e423b 88 buf[len] = buf[len] + ('a' - 'A');
hillkim7 3:64a7d39e423b 89 }
kaizen 0:910036879da0 90 return buf;
kaizen 0:910036879da0 91 }
kaizen 0:910036879da0 92
kaizen 0:910036879da0 93
kaizen 0:910036879da0 94 int connect(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack)
kaizen 0:910036879da0 95 {
kaizen 0:910036879da0 96 const char* iot_ibm = ".messaging.internetofthings.ibmcloud.com";
kaizen 0:910036879da0 97
kaizen 0:910036879da0 98 char hostname[strlen(org) + strlen(iot_ibm) + 1];
kaizen 0:910036879da0 99 sprintf(hostname, "%s%s", org, iot_ibm);
hillkim7 3:64a7d39e423b 100
hillkim7 3:64a7d39e423b 101 //strcpy(hostname, "192.168.11.203");
hillkim7 3:64a7d39e423b 102 DEBUG("connect host='%s' port=%u\r\n", hostname, IBM_IOT_PORT);
kaizen 0:910036879da0 103 int rc = ipstack->connect(hostname, IBM_IOT_PORT);
kaizen 1:532d83b9f910 104
kaizen 0:910036879da0 105 if (rc != 0)
kaizen 0:910036879da0 106 return rc;
kaizen 0:910036879da0 107
kaizen 0:910036879da0 108 // Construct clientId - d:org:type:id
kaizen 0:910036879da0 109 char clientId[strlen(org) + strlen(type) + strlen(id) + 5];
kaizen 0:910036879da0 110 sprintf(clientId, "d:%s:%s:%s", org, type, id);
kaizen 0:910036879da0 111 DEBUG("clientid is %s\r\n", clientId);
kaizen 0:910036879da0 112
kaizen 0:910036879da0 113 // MQTT Connect
kaizen 0:910036879da0 114 MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
kaizen 0:910036879da0 115 data.MQTTVersion = 3;
kaizen 0:910036879da0 116 data.clientID.cstring = clientId;
kaizen 0:910036879da0 117
kaizen 0:910036879da0 118 if (!quickstartMode)
kaizen 0:910036879da0 119 {
kaizen 0:910036879da0 120 data.username.cstring = "use-token-auth";
kaizen 0:910036879da0 121 data.password.cstring = auth_token;
kaizen 0:910036879da0 122 }
kaizen 0:910036879da0 123
kaizen 0:910036879da0 124 if ((rc = client->connect(&data)) == 0)
kaizen 0:910036879da0 125 {
kaizen 0:910036879da0 126 connected = true;
kaizen 0:910036879da0 127 }
hillkim7 3:64a7d39e423b 128 else
hillkim7 3:64a7d39e423b 129 {
hillkim7 3:64a7d39e423b 130 WARN("MQTT client connect error: %d\r\n", rc);
hillkim7 3:64a7d39e423b 131 }
kaizen 1:532d83b9f910 132
kaizen 0:910036879da0 133 return rc;
kaizen 0:910036879da0 134 }
kaizen 0:910036879da0 135
kaizen 0:910036879da0 136
kaizen 0:910036879da0 137 int getConnTimeout(int attemptNumber)
kaizen 0:910036879da0 138 { // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute
kaizen 0:910036879da0 139 // after 20 attempts, retry every 10 minutes
kaizen 0:910036879da0 140 return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600;
kaizen 0:910036879da0 141 }
kaizen 0:910036879da0 142
kaizen 0:910036879da0 143
kaizen 0:910036879da0 144 void attemptConnect(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack)
kaizen 0:910036879da0 145 {
kaizen 0:910036879da0 146 int retryAttempt = 0;
kaizen 0:910036879da0 147 connected = false;
kaizen 0:910036879da0 148
kaizen 0:910036879da0 149 // make sure a cable is connected before starting to connect
kaizen 0:910036879da0 150 while ( !ipstack->getEth().linkstatus() ) {
kaizen 0:910036879da0 151 wait(1.0f);
kaizen 0:910036879da0 152 WARN("Ethernet link not present. Check cable connection\r\n");
kaizen 0:910036879da0 153 }
kaizen 0:910036879da0 154
kaizen 0:910036879da0 155 while (connect(client, ipstack) != 0)
kaizen 0:910036879da0 156 {
kaizen 0:910036879da0 157 int timeout = getConnTimeout(++retryAttempt);
kaizen 0:910036879da0 158 WARN("Retry attempt number %d waiting %d\r\n", retryAttempt, timeout);
kaizen 0:910036879da0 159 wait(timeout);
kaizen 0:910036879da0 160 }
kaizen 0:910036879da0 161 }
kaizen 0:910036879da0 162
kaizen 0:910036879da0 163 int publish(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack)
kaizen 0:910036879da0 164 {
kaizen 0:910036879da0 165 MQTT::Message message;
kaizen 0:910036879da0 166 char* pubTopic = "iot-2/evt/status/fmt/json";
kaizen 0:910036879da0 167
kaizen 0:910036879da0 168 char buf[250];
hillkim7 4:0c9bdee36e2a 169 double temp, humi;
hillkim7 4:0c9bdee36e2a 170
hillkim7 4:0c9bdee36e2a 171 #if DHT11_TEMPERATURE
hillkim7 4:0c9bdee36e2a 172 int s = dht.readData();
hillkim7 4:0c9bdee36e2a 173 if (s != DHT11::OK) {
hillkim7 4:0c9bdee36e2a 174 printf("DHT11 Error: %d\r\n", s);
hillkim7 4:0c9bdee36e2a 175 temp = humi = 0;
hillkim7 4:0c9bdee36e2a 176 }
hillkim7 4:0c9bdee36e2a 177 else {
hillkim7 4:0c9bdee36e2a 178 printf("T:%d, H:%d\r\n", dht.readTemperature(), dht.readHumidity());
hillkim7 4:0c9bdee36e2a 179 temp = dht.readTemperature();
hillkim7 4:0c9bdee36e2a 180 humi = dht.readHumidity();
hillkim7 4:0c9bdee36e2a 181 }
hillkim7 4:0c9bdee36e2a 182 #else
hillkim7 4:0c9bdee36e2a 183 // simulate environment data
hillkim7 4:0c9bdee36e2a 184 temp = (120+(rand()%100)) / 10.0;
hillkim7 4:0c9bdee36e2a 185 humi = (200+(rand()%150)) / 10.0;
hillkim7 4:0c9bdee36e2a 186 #endif
kaizen 0:910036879da0 187 sprintf(buf,
hillkim7 4:0c9bdee36e2a 188 "{\"d\":{\"myName\":\"IoT mbed\",\"temperature\":%.1f,\"humidity\":%.1f}}",
hillkim7 4:0c9bdee36e2a 189 temp, humi);
kaizen 0:910036879da0 190
kaizen 0:910036879da0 191 message.qos = MQTT::QOS0;
kaizen 0:910036879da0 192 message.retained = false;
kaizen 0:910036879da0 193 message.dup = false;
kaizen 0:910036879da0 194 message.payload = (void*)buf;
kaizen 0:910036879da0 195 message.payloadlen = strlen(buf);
kaizen 0:910036879da0 196
kaizen 0:910036879da0 197 LOG("Publishing %s\r\n", buf);
kaizen 0:910036879da0 198 return client->publish(pubTopic, &message);
kaizen 0:910036879da0 199 }
kaizen 0:910036879da0 200
kaizen 0:910036879da0 201
kaizen 0:910036879da0 202 void messageArrived(MQTT::MessageData& md)
kaizen 0:910036879da0 203 {
kaizen 0:910036879da0 204 MQTT::Message &message = md.message;
kaizen 0:910036879da0 205 char topic[md.topicName.lenstring.len + 1];
kaizen 0:910036879da0 206
kaizen 0:910036879da0 207 sprintf(topic, "%.*s", md.topicName.lenstring.len, md.topicName.lenstring.data);
kaizen 0:910036879da0 208
kaizen 0:910036879da0 209 LOG("Message arrived on topic %s: %.*s\r\n", topic, message.payloadlen, message.payload);
kaizen 0:910036879da0 210
kaizen 0:910036879da0 211 // Command topic: iot-2/cmd/blink/fmt/json - cmd is the string between cmd/ and /fmt/
kaizen 0:910036879da0 212 char* start = strstr(topic, "/cmd/") + 5;
kaizen 0:910036879da0 213 int len = strstr(topic, "/fmt/") - start;
kaizen 0:910036879da0 214
kaizen 0:910036879da0 215 if (memcmp(start, "blink", len) == 0)
kaizen 0:910036879da0 216 {
kaizen 0:910036879da0 217 char payload[message.payloadlen + 1];
kaizen 0:910036879da0 218 sprintf(payload, "%.*s", message.payloadlen, (char*)message.payload);
kaizen 0:910036879da0 219
kaizen 0:910036879da0 220 char* pos = strchr(payload, '}');
kaizen 0:910036879da0 221 if (pos != NULL)
kaizen 0:910036879da0 222 {
kaizen 0:910036879da0 223 *pos = '\0';
kaizen 0:910036879da0 224 if ((pos = strchr(payload, ':')) != NULL)
kaizen 0:910036879da0 225 {
kaizen 0:910036879da0 226 }
kaizen 0:910036879da0 227 }
kaizen 0:910036879da0 228 }
kaizen 0:910036879da0 229 else
kaizen 0:910036879da0 230 WARN("Unsupported command: %.*s\r\n", len, start);
kaizen 0:910036879da0 231 }
kaizen 0:910036879da0 232
kaizen 0:910036879da0 233 int main()
kaizen 0:910036879da0 234 {
hillkim7 3:64a7d39e423b 235 //#if defined(TARGET_KL25Z)
kaizen 2:87c816cd88e2 236 Serial pc(USBTX, USBRX);
kaizen 2:87c816cd88e2 237 pc.baud(115200);
kaizen 2:87c816cd88e2 238
kaizen 2:87c816cd88e2 239 SPI spi(D11, D12, D13); // mosi, miso, sclk
kaizen 2:87c816cd88e2 240 wait(1);
hillkim7 3:64a7d39e423b 241
hillkim7 3:64a7d39e423b 242 #if defined(TARGET_STM32F401RE)
hillkim7 3:64a7d39e423b 243 MQTTEthernet ipstack(&spi, D10, D5);
hillkim7 3:64a7d39e423b 244 #else
kaizen 2:87c816cd88e2 245 MQTTEthernet ipstack(&spi, D10, D9); //scs(D10), nRESET(PTA20)
hillkim7 3:64a7d39e423b 246 #endif
kaizen 2:87c816cd88e2 247 MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE> client(ipstack);
hillkim7 3:64a7d39e423b 248 //#endif
kaizen 0:910036879da0 249
hillkim7 3:64a7d39e423b 250 LOG("ETH MAC: %s IP: %s GW: %s\r\n",
hillkim7 3:64a7d39e423b 251 ipstack.getEth().getMACAddress(),
hillkim7 3:64a7d39e423b 252 ipstack.getEth().getIPAddress(),
hillkim7 3:64a7d39e423b 253 ipstack.getEth().getGateway());
kaizen 1:532d83b9f910 254 getMac(ipstack.getEth(), id, sizeof(id));
hillkim7 3:64a7d39e423b 255 LOG("attemptConnect\r\n");
kaizen 0:910036879da0 256 attemptConnect(&client, &ipstack);
kaizen 0:910036879da0 257
kaizen 0:910036879da0 258 int count = 0;
kaizen 0:910036879da0 259 while (true)
kaizen 0:910036879da0 260 {
kaizen 0:910036879da0 261 if (!ipstack.getEth().linkstatus()) {
hillkim7 3:64a7d39e423b 262 WARN("Reset on link down\r\n");
hillkim7 3:64a7d39e423b 263 wait(1);
kaizen 0:910036879da0 264 NVIC_SystemReset();
kaizen 0:910036879da0 265 // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed
kaizen 0:910036879da0 266 // or maybe just add the proper members to do this disconnect and call attemptConnect(...)
kaizen 0:910036879da0 267 }
kaizen 0:910036879da0 268
hillkim7 4:0c9bdee36e2a 269 if (++count == 200)
hillkim7 4:0c9bdee36e2a 270 { // Publish a message every two second
kaizen 0:910036879da0 271 if (publish(&client, &ipstack) != 0)
hillkim7 3:64a7d39e423b 272 {
hillkim7 3:64a7d39e423b 273 WARN("publish error\r\n");
hillkim7 3:64a7d39e423b 274 //attemptConnect(&client, &ipstack); // if we have lost the connection
hillkim7 3:64a7d39e423b 275 }
kaizen 0:910036879da0 276 count = 0;
kaizen 0:910036879da0 277 }
kaizen 0:910036879da0 278
kaizen 0:910036879da0 279 client.yield(10); // allow the MQTT client to receive messages
kaizen 0:910036879da0 280 }
kaizen 0:910036879da0 281 }
hillkim7 3:64a7d39e423b 282