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
I post description regarding this source code here.
http://developer.mbed.org/users/hillkim7/notebook/ibmiotclientethernetexample_w5200/
Diff: main.cpp
- Revision:
- 0:910036879da0
- Child:
- 1:532d83b9f910
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Fri Sep 26 08:06:10 2014 +0000 @@ -0,0 +1,204 @@ +#include "mbed.h" +#include "MQTTClient.h" +#include "MQTTEthernet.h" + +// Configuration values needed to connect to IBM IoT Cloud +#define QUICKSTARTMODE 1 +#if (QUICKSTARTMODE) +#define ORG "quickstart" +#define ID "" +#define AUTH_TOKEN "" +#define TYPE "iotsample-mbed-lpc1768" +#else +#define ORG "Replace with your org" +#define ID "Replace with your id" +#define TYPE "Replace with your type" +#define AUTH_TOKEN "Replace with your auth-token" +#endif + +#define MQTT_PORT 1883 +#define MQTT_TLS_PORT 8883 +#define IBM_IOT_PORT MQTT_PORT + +#define MQTT_MAX_PACKET_SIZE 250 + + +bool quickstartMode = (QUICKSTARTMODE) ? true : false; +char org[11] = ORG; +char type[30] = TYPE; +char id[30] = ID; // mac without colons +char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode + +bool connected = false; + + +char* getMac(EthernetInterface& eth, char* buf, int buflen) // Obtain MAC address +{ + //strncpy(buf, eth.getMACAddress(), buflen); + strncpy(buf,"00:02:f7:f2:05:00",buflen); + + char* pos; // Remove colons from mac address + while ((pos = strchr(buf, ':')) != NULL) + memmove(pos, pos + 1, strlen(pos) + 1); + return buf; +} + + +int connect(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack) +{ + const char* iot_ibm = ".messaging.internetofthings.ibmcloud.com"; + + char hostname[strlen(org) + strlen(iot_ibm) + 1]; + sprintf(hostname, "%s%s", org, iot_ibm); + int rc = ipstack->connect(hostname, IBM_IOT_PORT); + if (rc != 0) + return rc; + + // Construct clientId - d:org:type:id + char clientId[strlen(org) + strlen(type) + strlen(id) + 5]; + sprintf(clientId, "d:%s:%s:%s", org, type, id); + DEBUG("clientid is %s\r\n", clientId); + + // MQTT Connect + MQTTPacket_connectData data = MQTTPacket_connectData_initializer; + data.MQTTVersion = 3; + data.clientID.cstring = clientId; + + if (!quickstartMode) + { + data.username.cstring = "use-token-auth"; + data.password.cstring = auth_token; + } + + if ((rc = client->connect(&data)) == 0) + { + connected = true; + } + return rc; +} + + +int getConnTimeout(int attemptNumber) +{ // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute + // after 20 attempts, retry every 10 minutes + return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600; +} + + +void attemptConnect(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack) +{ + int retryAttempt = 0; + connected = false; + + // make sure a cable is connected before starting to connect + while ( !ipstack->getEth().linkstatus() ) { + wait(1.0f); + WARN("Ethernet link not present. Check cable connection\r\n"); + } + + while (connect(client, ipstack) != 0) + { + int timeout = getConnTimeout(++retryAttempt); + WARN("Retry attempt number %d waiting %d\r\n", retryAttempt, timeout); + wait(timeout); + } +} + +int publish(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack) +{ + MQTT::Message message; + char* pubTopic = "iot-2/evt/status/fmt/json"; + + char buf[250]; + sprintf(buf, + "{\"d\":{\"myName\":\"IoT mbed\",\"accelX\":%0.4f,\"accelY\":%0.4f,\"accelZ\":%0.4f,\"temp\":%0.4f,\"joystick\":\"%s\",\"potentiometer1\":%0.4f,\"potentiometer2\":%0.4f}}", + 12.4, 22.3, 12.2, 25.3, "up", 12.3, 22.1); + + message.qos = MQTT::QOS0; + message.retained = false; + message.dup = false; + message.payload = (void*)buf; + message.payloadlen = strlen(buf); + + LOG("Publishing %s\r\n", buf); + return client->publish(pubTopic, &message); +} + + +void messageArrived(MQTT::MessageData& md) +{ + MQTT::Message &message = md.message; + char topic[md.topicName.lenstring.len + 1]; + + sprintf(topic, "%.*s", md.topicName.lenstring.len, md.topicName.lenstring.data); + + LOG("Message arrived on topic %s: %.*s\r\n", topic, message.payloadlen, message.payload); + + // Command topic: iot-2/cmd/blink/fmt/json - cmd is the string between cmd/ and /fmt/ + char* start = strstr(topic, "/cmd/") + 5; + int len = strstr(topic, "/fmt/") - start; + + if (memcmp(start, "blink", len) == 0) + { + char payload[message.payloadlen + 1]; + sprintf(payload, "%.*s", message.payloadlen, (char*)message.payload); + + char* pos = strchr(payload, '}'); + if (pos != NULL) + { + *pos = '\0'; + if ((pos = strchr(payload, ':')) != NULL) + { + } + } + } + else + WARN("Unsupported command: %.*s\r\n", len, start); +} + + + +int main() +{ + Serial pc(USBTX, USBRX); + pc.baud(115200); + + SPI spi(D11, D12, D13); // mosi, miso, sclk + wait(1); + + MQTTEthernet ipstack(&spi, D10, D9); //scs(D10), nRESET(PTA20) + MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE> client(ipstack); + + if (quickstartMode ) + { + getMac(ipstack.getEth(), id, sizeof(id)); + } + + attemptConnect(&client, &ipstack); + + if (!quickstartMode) + { + int rc = 0; + if ((rc = client.subscribe("iot-2/cmd/+/fmt/json", MQTT::QOS1, messageArrived)) != 0) + WARN("rc from MQTT subscribe is %d\r\n", rc); + } + + int count = 0; + while (true) + { + if (!ipstack.getEth().linkstatus()) { + NVIC_SystemReset(); + // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed + // or maybe just add the proper members to do this disconnect and call attemptConnect(...) + } + + if (++count == 100) + { // Publish a message every second + if (publish(&client, &ipstack) != 0) + attemptConnect(&client, &ipstack); // if we have lost the connection + count = 0; + } + + client.yield(10); // allow the MQTT client to receive messages + } +}