IoT based security system that detects suspicious movements through a motion detector and alerts the user on their gmail. In the presence of motion sensed between 7 to 9 times, the Grove PIR sensor sends an input to the board which is connected to internet via Ethernet. The board publishes the sensor data on IBM IoT foundation, which is known as IBM Watson. The data is then sent to IBM Bluemix which provides real time analysis and the remote time data management and monitoring. For more information : https://developer.ibm.com/recipes/tutorials/mbed-c-client-library-for-ibm-iot-foundation/

Dependencies:   C12832 EthernetInterface LM75B MMA7660 MQTT mbed-rtos mbed

Fork of IBMIoTClientEthernetExample by IBM Watson IoT

Committer:
chris
Date:
Mon Oct 20 14:37:33 2014 +0000
Revision:
10:0b5e0dfee08e
Parent:
9:58eb378727d9
Child:
11:7a6df9a2dcdc
Added a new menu item to display the software revision

Who changed what in which revision?

UserRevisionLine numberNew contents of line
samdanbury 6:37b6d0d56190 1 /*******************************************************************************
samdanbury 6:37b6d0d56190 2 * Copyright (c) 2014 IBM Corp.
samdanbury 6:37b6d0d56190 3 *
samdanbury 6:37b6d0d56190 4 * All rights reserved. This program and the accompanying materials
samdanbury 6:37b6d0d56190 5 * are made available under the terms of the Eclipse Public License v1.0
samdanbury 6:37b6d0d56190 6 * and Eclipse Distribution License v1.0 which accompany this distribution.
samdanbury 6:37b6d0d56190 7 *
samdanbury 6:37b6d0d56190 8 * The Eclipse Public License is available at
samdanbury 6:37b6d0d56190 9 * http://www.eclipse.org/legal/epl-v10.html
samdanbury 6:37b6d0d56190 10 * and the Eclipse Distribution License is available at
samdanbury 6:37b6d0d56190 11 * http://www.eclipse.org/org/documents/edl-v10.php.
samdanbury 6:37b6d0d56190 12 *
samdanbury 6:37b6d0d56190 13 * Contributors:
samdanbury 6:37b6d0d56190 14 * Sam Danbury - initial implementation
samdanbury 6:37b6d0d56190 15 * Ian Craggs - refactoring to remove STL and other changes
icraggs 8:80d49dd91542 16 * Sam Grove - added check for Ethernet cable.
chris 10:0b5e0dfee08e 17 * Chris Styles - Added additional menu screen for software revision
chris 10:0b5e0dfee08e 18 *
chris 10:0b5e0dfee08e 19 * To do :
chris 10:0b5e0dfee08e 20 * Add magnetometer sensor output to IoT data stream
chris 10:0b5e0dfee08e 21 *
samdanbury 6:37b6d0d56190 22 *******************************************************************************/
samdanbury 6:37b6d0d56190 23
samdanbury 6:37b6d0d56190 24 #include "LM75B.h"
samdanbury 6:37b6d0d56190 25 #include "MMA7660.h"
samdanbury 6:37b6d0d56190 26 #include "MQTTClient.h"
samdanbury 6:37b6d0d56190 27 #include "MQTTEthernet.h"
samdanbury 6:37b6d0d56190 28 #include "C12832.h"
samdanbury 6:37b6d0d56190 29 #include "Arial12x12.h"
samdanbury 6:37b6d0d56190 30 #include "rtos.h"
samdanbury 6:37b6d0d56190 31
chris 10:0b5e0dfee08e 32 // Update this to the next number *before* a commit
chris 10:0b5e0dfee08e 33 #define __APP_SW_REVISION__ "10"
chris 10:0b5e0dfee08e 34
samdanbury 6:37b6d0d56190 35 // Configuration values needed to connect to IBM IoT Cloud
icraggs 8:80d49dd91542 36 #define ORG "quickstart" // For a registered connection, replace with your org
icraggs 8:80d49dd91542 37 #define ID "" // For a registered connection, replace with your id
icraggs 8:80d49dd91542 38 #define AUTH_TOKEN "" // For a registered connection, replace with your auth-token
icraggs 8:80d49dd91542 39 #define TYPE DEFAULT_TYPE_NAME // For a registered connection, replace with your type
samdanbury 6:37b6d0d56190 40
samdanbury 6:37b6d0d56190 41 #define MQTT_PORT 1883
samdanbury 6:37b6d0d56190 42 #define MQTT_TLS_PORT 8883
samdanbury 6:37b6d0d56190 43 #define IBM_IOT_PORT MQTT_PORT
samdanbury 6:37b6d0d56190 44
samdanbury 6:37b6d0d56190 45 #define MQTT_MAX_PACKET_SIZE 250
samdanbury 6:37b6d0d56190 46
samdanbury 6:37b6d0d56190 47 #if defined(TARGET_LPC1768)
samdanbury 6:37b6d0d56190 48 #warning "Compiling for mbed LPC1768"
samdanbury 6:37b6d0d56190 49 #include "LPC1768.h"
samdanbury 6:37b6d0d56190 50 #elif defined(TARGET_K64F)
samdanbury 6:37b6d0d56190 51 #warning "Compiling for mbed K64F"
samdanbury 6:37b6d0d56190 52 #include "K64F.h"
samdanbury 6:37b6d0d56190 53 #endif
samdanbury 6:37b6d0d56190 54
icraggs 8:80d49dd91542 55 bool quickstartMode = true;
samdanbury 6:37b6d0d56190 56 char org[11] = ORG;
samdanbury 6:37b6d0d56190 57 char type[30] = TYPE;
samdanbury 6:37b6d0d56190 58 char id[30] = ID; // mac without colons
samdanbury 6:37b6d0d56190 59 char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode
samdanbury 6:37b6d0d56190 60
samdanbury 6:37b6d0d56190 61 bool connected = false;
samdanbury 6:37b6d0d56190 62 char* joystickPos = "CENTRE";
samdanbury 6:37b6d0d56190 63 int blink_interval = 0;
samdanbury 6:37b6d0d56190 64
samdanbury 6:37b6d0d56190 65
samdanbury 6:37b6d0d56190 66 void off()
samdanbury 6:37b6d0d56190 67 {
samdanbury 6:37b6d0d56190 68 r = g = b = 1.0; // 1 is off, 0 is full brightness
samdanbury 6:37b6d0d56190 69 }
samdanbury 6:37b6d0d56190 70
samdanbury 6:37b6d0d56190 71 void red()
samdanbury 6:37b6d0d56190 72 {
samdanbury 6:37b6d0d56190 73 r = 0.7; g = 1.0; b = 1.0; // 1 is off, 0 is full brightness
samdanbury 6:37b6d0d56190 74 }
samdanbury 6:37b6d0d56190 75
samdanbury 6:37b6d0d56190 76 void yellow()
samdanbury 6:37b6d0d56190 77 {
samdanbury 6:37b6d0d56190 78 r = 0.7; g = 0.7; b = 1.0; // 1 is off, 0 is full brightness
samdanbury 6:37b6d0d56190 79 }
samdanbury 6:37b6d0d56190 80
samdanbury 6:37b6d0d56190 81 void green()
samdanbury 6:37b6d0d56190 82 {
samdanbury 6:37b6d0d56190 83 r = 1.0; g = 0.7; b = 1.0; // 1 is off, 0 is full brightness
samdanbury 6:37b6d0d56190 84 }
samdanbury 6:37b6d0d56190 85
samdanbury 6:37b6d0d56190 86
samdanbury 6:37b6d0d56190 87 void flashing_yellow(void const *args)
samdanbury 6:37b6d0d56190 88 {
samdanbury 6:37b6d0d56190 89 bool on = false;
samdanbury 6:37b6d0d56190 90 while (!connected) // flashing yellow only while connecting
samdanbury 6:37b6d0d56190 91 {
samdanbury 6:37b6d0d56190 92 on = !on;
samdanbury 6:37b6d0d56190 93 if (on)
samdanbury 6:37b6d0d56190 94 yellow();
samdanbury 6:37b6d0d56190 95 else
samdanbury 6:37b6d0d56190 96 off();
samdanbury 6:37b6d0d56190 97 wait(0.5);
samdanbury 6:37b6d0d56190 98 }
samdanbury 6:37b6d0d56190 99 }
samdanbury 6:37b6d0d56190 100
samdanbury 6:37b6d0d56190 101
samdanbury 6:37b6d0d56190 102 void flashing_red(void const *args) // to be used when the connection is lost
samdanbury 6:37b6d0d56190 103 {
samdanbury 6:37b6d0d56190 104 bool on = false;
samdanbury 6:37b6d0d56190 105 while (!connected)
samdanbury 6:37b6d0d56190 106 {
samdanbury 6:37b6d0d56190 107 on = !on;
samdanbury 6:37b6d0d56190 108 if (on)
samdanbury 6:37b6d0d56190 109 red();
samdanbury 6:37b6d0d56190 110 else
samdanbury 6:37b6d0d56190 111 off();
samdanbury 6:37b6d0d56190 112 wait(2.0);
samdanbury 6:37b6d0d56190 113 }
samdanbury 6:37b6d0d56190 114 }
samdanbury 6:37b6d0d56190 115
samdanbury 6:37b6d0d56190 116
samdanbury 6:37b6d0d56190 117 void printMenu(int menuItem)
samdanbury 6:37b6d0d56190 118 {
samdanbury 6:37b6d0d56190 119 lcd.cls();
samdanbury 6:37b6d0d56190 120 lcd.locate(0,0);
samdanbury 6:37b6d0d56190 121 switch (menuItem)
samdanbury 6:37b6d0d56190 122 {
samdanbury 6:37b6d0d56190 123 case 0:
samdanbury 6:37b6d0d56190 124 lcd.printf("IBM IoT Cloud");
samdanbury 6:37b6d0d56190 125 lcd.locate(0,16);
samdanbury 6:37b6d0d56190 126 lcd.printf("Scroll with joystick");
samdanbury 6:37b6d0d56190 127 break;
samdanbury 6:37b6d0d56190 128 case 1:
samdanbury 6:37b6d0d56190 129 lcd.printf("Go to:");
samdanbury 6:37b6d0d56190 130 lcd.locate(0,16);
samdanbury 6:37b6d0d56190 131 lcd.printf("http://ibm.biz/iotqstart");
samdanbury 6:37b6d0d56190 132 break;
samdanbury 6:37b6d0d56190 133 case 2:
samdanbury 6:37b6d0d56190 134 lcd.printf("Device Identity:");
samdanbury 6:37b6d0d56190 135 lcd.locate(0,16);
samdanbury 6:37b6d0d56190 136 lcd.printf("%s", id);
samdanbury 6:37b6d0d56190 137 break;
samdanbury 6:37b6d0d56190 138 case 3:
samdanbury 6:37b6d0d56190 139 lcd.printf("Status:");
samdanbury 6:37b6d0d56190 140 lcd.locate(0,16);
samdanbury 6:37b6d0d56190 141 lcd.printf(connected ? "Connected" : "Disconnected");
samdanbury 6:37b6d0d56190 142 break;
chris 10:0b5e0dfee08e 143 case 4:
chris 10:0b5e0dfee08e 144 lcd.printf("App version:");
chris 10:0b5e0dfee08e 145 lcd.locate(0,16);
chris 10:0b5e0dfee08e 146 lcd.printf("%s",__APP_SW_REVISION__);
chris 10:0b5e0dfee08e 147 break;
samdanbury 6:37b6d0d56190 148 }
samdanbury 6:37b6d0d56190 149 }
samdanbury 6:37b6d0d56190 150
samdanbury 6:37b6d0d56190 151
samdanbury 6:37b6d0d56190 152 void setMenu()
samdanbury 6:37b6d0d56190 153 {
samdanbury 6:37b6d0d56190 154 static int menuItem = 0;
samdanbury 6:37b6d0d56190 155 if (Down)
samdanbury 6:37b6d0d56190 156 {
samdanbury 6:37b6d0d56190 157 joystickPos = "DOWN";
chris 10:0b5e0dfee08e 158 if (menuItem >= 0 && menuItem < 4)
samdanbury 6:37b6d0d56190 159 printMenu(++menuItem);
samdanbury 6:37b6d0d56190 160 }
samdanbury 6:37b6d0d56190 161 else if (Left)
samdanbury 6:37b6d0d56190 162 joystickPos = "LEFT";
samdanbury 6:37b6d0d56190 163 else if (Click)
samdanbury 6:37b6d0d56190 164 joystickPos = "CLICK";
samdanbury 6:37b6d0d56190 165 else if (Up)
samdanbury 6:37b6d0d56190 166 {
samdanbury 6:37b6d0d56190 167 joystickPos = "UP";
chris 10:0b5e0dfee08e 168 if (menuItem <= 4 && menuItem > 0)
samdanbury 6:37b6d0d56190 169 printMenu(--menuItem);
samdanbury 6:37b6d0d56190 170 }
samdanbury 6:37b6d0d56190 171 else if (Right)
samdanbury 6:37b6d0d56190 172 joystickPos = "RIGHT";
samdanbury 6:37b6d0d56190 173 else
samdanbury 6:37b6d0d56190 174 joystickPos = "CENTRE";
samdanbury 6:37b6d0d56190 175 }
samdanbury 6:37b6d0d56190 176
samdanbury 6:37b6d0d56190 177
samdanbury 6:37b6d0d56190 178 /**
samdanbury 6:37b6d0d56190 179 * Display a message on the LCD screen prefixed with IBM IoT Cloud
samdanbury 6:37b6d0d56190 180 */
samdanbury 6:37b6d0d56190 181 void displayMessage(char* message)
samdanbury 6:37b6d0d56190 182 {
samdanbury 6:37b6d0d56190 183 lcd.cls();
samdanbury 6:37b6d0d56190 184 lcd.locate(0,0);
samdanbury 6:37b6d0d56190 185 lcd.printf("IBM IoT Cloud");
samdanbury 6:37b6d0d56190 186 lcd.locate(0,16);
samdanbury 6:37b6d0d56190 187 lcd.printf(message);
samdanbury 6:37b6d0d56190 188 }
samdanbury 6:37b6d0d56190 189
samdanbury 6:37b6d0d56190 190
samdanbury 6:37b6d0d56190 191 int connect(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack)
samdanbury 6:37b6d0d56190 192 {
samdanbury 6:37b6d0d56190 193 const char* iot_ibm = ".messaging.internetofthings.ibmcloud.com";
samdanbury 6:37b6d0d56190 194
samdanbury 6:37b6d0d56190 195 char hostname[strlen(org) + strlen(iot_ibm) + 1];
samdanbury 6:37b6d0d56190 196 sprintf(hostname, "%s%s", org, iot_ibm);
samdanbury 6:37b6d0d56190 197 int rc = ipstack->connect(hostname, IBM_IOT_PORT);
samdanbury 6:37b6d0d56190 198 if (rc != 0)
samdanbury 6:37b6d0d56190 199 return rc;
samdanbury 6:37b6d0d56190 200
samdanbury 6:37b6d0d56190 201 // Construct clientId - d:org:type:id
samdanbury 6:37b6d0d56190 202 char clientId[strlen(org) + strlen(type) + strlen(id) + 5];
samdanbury 6:37b6d0d56190 203 sprintf(clientId, "d:%s:%s:%s", org, type, id);
samdanbury 6:37b6d0d56190 204 DEBUG("clientid is %s\n", clientId);
samdanbury 6:37b6d0d56190 205
samdanbury 6:37b6d0d56190 206 // MQTT Connect
samdanbury 6:37b6d0d56190 207 MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
samdanbury 6:37b6d0d56190 208 data.MQTTVersion = 3;
samdanbury 6:37b6d0d56190 209 data.clientID.cstring = clientId;
samdanbury 6:37b6d0d56190 210
samdanbury 6:37b6d0d56190 211 if (!quickstartMode)
samdanbury 6:37b6d0d56190 212 {
samdanbury 6:37b6d0d56190 213 data.username.cstring = "use-token-auth";
samdanbury 6:37b6d0d56190 214 data.password.cstring = auth_token;
samdanbury 6:37b6d0d56190 215 }
samdanbury 6:37b6d0d56190 216
icraggs 8:80d49dd91542 217 if ((rc = client->connect(data)) == 0)
samdanbury 6:37b6d0d56190 218 {
samdanbury 6:37b6d0d56190 219 connected = true;
samdanbury 6:37b6d0d56190 220 green();
samdanbury 6:37b6d0d56190 221 displayMessage("Connected");
samdanbury 6:37b6d0d56190 222 wait(2);
samdanbury 6:37b6d0d56190 223 displayMessage("Scroll with joystick");
samdanbury 6:37b6d0d56190 224 }
samdanbury 6:37b6d0d56190 225 return rc;
samdanbury 6:37b6d0d56190 226 }
samdanbury 6:37b6d0d56190 227
samdanbury 6:37b6d0d56190 228
samdanbury 6:37b6d0d56190 229 int getConnTimeout(int attemptNumber)
samdanbury 6:37b6d0d56190 230 { // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute
samdanbury 6:37b6d0d56190 231 // after 20 attempts, retry every 10 minutes
samdanbury 6:37b6d0d56190 232 return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600;
samdanbury 6:37b6d0d56190 233 }
samdanbury 6:37b6d0d56190 234
samdanbury 6:37b6d0d56190 235
samdanbury 6:37b6d0d56190 236 void attemptConnect(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack)
samdanbury 6:37b6d0d56190 237 {
samdanbury 6:37b6d0d56190 238 int retryAttempt = 0;
samdanbury 6:37b6d0d56190 239 connected = false;
icraggs 8:80d49dd91542 240
icraggs 8:80d49dd91542 241 // make sure a cable is connected before starting to connect
icraggs 8:80d49dd91542 242 while (!linkStatus()) {
icraggs 8:80d49dd91542 243 wait(1.0f);
icraggs 8:80d49dd91542 244 WARN("Ethernet link not present. Check cable connection\n");
icraggs 8:80d49dd91542 245 }
samdanbury 6:37b6d0d56190 246
samdanbury 6:37b6d0d56190 247 while (connect(client, ipstack) != 0)
samdanbury 6:37b6d0d56190 248 {
samdanbury 6:37b6d0d56190 249 #if defined(TARGET_K64F)
samdanbury 6:37b6d0d56190 250 red();
samdanbury 6:37b6d0d56190 251 #else
samdanbury 6:37b6d0d56190 252 Thread red_thread(flashing_red);
samdanbury 6:37b6d0d56190 253 #endif
samdanbury 6:37b6d0d56190 254 int timeout = getConnTimeout(++retryAttempt);
samdanbury 6:37b6d0d56190 255 WARN("Retry attempt number %d waiting %d\n", retryAttempt, timeout);
icraggs 8:80d49dd91542 256
icraggs 8:80d49dd91542 257 // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed
icraggs 8:80d49dd91542 258 // or maybe just add the proper members to do this disconnect and call attemptConnect(...)
icraggs 8:80d49dd91542 259
icraggs 8:80d49dd91542 260 // this works - reset the system when the retry count gets to a threshold
icraggs 8:80d49dd91542 261 if (retryAttempt == 5)
icraggs 8:80d49dd91542 262 NVIC_SystemReset();
icraggs 8:80d49dd91542 263 else
icraggs 8:80d49dd91542 264 wait(timeout);
samdanbury 6:37b6d0d56190 265 }
samdanbury 6:37b6d0d56190 266 }
samdanbury 6:37b6d0d56190 267
samdanbury 6:37b6d0d56190 268
samdanbury 6:37b6d0d56190 269 int publish(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack)
samdanbury 6:37b6d0d56190 270 {
samdanbury 6:37b6d0d56190 271 MQTT::Message message;
samdanbury 6:37b6d0d56190 272 char* pubTopic = "iot-2/evt/status/fmt/json";
samdanbury 6:37b6d0d56190 273
samdanbury 6:37b6d0d56190 274 char buf[250];
samdanbury 6:37b6d0d56190 275 sprintf(buf,
samdanbury 6:37b6d0d56190 276 "{\"d\":{\"myName\":\"IoT mbed\",\"accelX\":%0.4f,\"accelY\":%0.4f,\"accelZ\":%0.4f,\"temp\":%0.4f,\"joystick\":\"%s\",\"potentiometer1\":%0.4f,\"potentiometer2\":%0.4f}}",
samdanbury 6:37b6d0d56190 277 MMA.x(), MMA.y(), MMA.z(), sensor.temp(), joystickPos, ain1.read(), ain2.read());
samdanbury 6:37b6d0d56190 278 message.qos = MQTT::QOS0;
samdanbury 6:37b6d0d56190 279 message.retained = false;
samdanbury 6:37b6d0d56190 280 message.dup = false;
samdanbury 6:37b6d0d56190 281 message.payload = (void*)buf;
samdanbury 6:37b6d0d56190 282 message.payloadlen = strlen(buf);
samdanbury 6:37b6d0d56190 283
samdanbury 6:37b6d0d56190 284 LOG("Publishing %s\n", buf);
icraggs 8:80d49dd91542 285 return client->publish(pubTopic, message);
samdanbury 6:37b6d0d56190 286 }
samdanbury 6:37b6d0d56190 287
samdanbury 6:37b6d0d56190 288
samdanbury 6:37b6d0d56190 289 #if defined(TARGET_K64F)
samdanbury 6:37b6d0d56190 290 int getUUID48(char* buf, int buflen)
samdanbury 6:37b6d0d56190 291 {
samdanbury 6:37b6d0d56190 292 unsigned int UUID_LOC_WORD0 = 0x40048060;
samdanbury 6:37b6d0d56190 293 unsigned int UUID_LOC_WORD1 = 0x4004805C;
samdanbury 6:37b6d0d56190 294
samdanbury 6:37b6d0d56190 295 // Fetch word 0
samdanbury 6:37b6d0d56190 296 uint32_t word0 = *(uint32_t *)UUID_LOC_WORD0;
samdanbury 6:37b6d0d56190 297
samdanbury 6:37b6d0d56190 298 // Fetch word 1
samdanbury 6:37b6d0d56190 299 // we only want bottom 16 bits of word1 (MAC bits 32-47)
samdanbury 6:37b6d0d56190 300 // and bit 9 forced to 1, bit 8 forced to 0
samdanbury 6:37b6d0d56190 301 // Locally administered MAC, reduced conflicts
samdanbury 6:37b6d0d56190 302 // http://en.wikipedia.org/wiki/MAC_address
samdanbury 6:37b6d0d56190 303 uint32_t word1 = *(uint32_t *)UUID_LOC_WORD1;
samdanbury 6:37b6d0d56190 304 word1 |= 0x00000200;
samdanbury 6:37b6d0d56190 305 word1 &= 0x0000FEFF;
samdanbury 6:37b6d0d56190 306
icraggs 9:58eb378727d9 307 int rc = snprintf(buf, buflen, "%4x%08x", word1, word0); // Device id must be in lower case
samdanbury 6:37b6d0d56190 308
samdanbury 6:37b6d0d56190 309 return rc;
samdanbury 6:37b6d0d56190 310 }
samdanbury 6:37b6d0d56190 311 #else
samdanbury 6:37b6d0d56190 312 char* getMac(EthernetInterface& eth, char* buf, int buflen) // Obtain MAC address
samdanbury 6:37b6d0d56190 313 {
samdanbury 6:37b6d0d56190 314 strncpy(buf, eth.getMACAddress(), buflen);
samdanbury 6:37b6d0d56190 315
samdanbury 6:37b6d0d56190 316 char* pos; // Remove colons from mac address
samdanbury 6:37b6d0d56190 317 while ((pos = strchr(buf, ':')) != NULL)
samdanbury 6:37b6d0d56190 318 memmove(pos, pos + 1, strlen(pos) + 1);
samdanbury 6:37b6d0d56190 319 return buf;
samdanbury 6:37b6d0d56190 320 }
samdanbury 6:37b6d0d56190 321 #endif
samdanbury 6:37b6d0d56190 322
samdanbury 6:37b6d0d56190 323
samdanbury 6:37b6d0d56190 324 void messageArrived(MQTT::MessageData& md)
samdanbury 6:37b6d0d56190 325 {
samdanbury 6:37b6d0d56190 326 MQTT::Message &message = md.message;
samdanbury 6:37b6d0d56190 327 char topic[md.topicName.lenstring.len + 1];
samdanbury 6:37b6d0d56190 328
samdanbury 6:37b6d0d56190 329 sprintf(topic, "%.*s", md.topicName.lenstring.len, md.topicName.lenstring.data);
samdanbury 6:37b6d0d56190 330
samdanbury 6:37b6d0d56190 331 LOG("Message arrived on topic %s: %.*s\n", topic, message.payloadlen, message.payload);
samdanbury 6:37b6d0d56190 332
samdanbury 6:37b6d0d56190 333 // Command topic: iot-2/cmd/blink/fmt/json - cmd is the string between cmd/ and /fmt/
samdanbury 6:37b6d0d56190 334 char* start = strstr(topic, "/cmd/") + 5;
samdanbury 6:37b6d0d56190 335 int len = strstr(topic, "/fmt/") - start;
samdanbury 6:37b6d0d56190 336
samdanbury 6:37b6d0d56190 337 if (memcmp(start, "blink", len) == 0)
samdanbury 6:37b6d0d56190 338 {
samdanbury 6:37b6d0d56190 339 char payload[message.payloadlen + 1];
samdanbury 6:37b6d0d56190 340 sprintf(payload, "%.*s", message.payloadlen, (char*)message.payload);
samdanbury 6:37b6d0d56190 341
samdanbury 6:37b6d0d56190 342 char* pos = strchr(payload, '}');
samdanbury 6:37b6d0d56190 343 if (pos != NULL)
samdanbury 6:37b6d0d56190 344 {
samdanbury 6:37b6d0d56190 345 *pos = '\0';
samdanbury 6:37b6d0d56190 346 if ((pos = strchr(payload, ':')) != NULL)
samdanbury 6:37b6d0d56190 347 {
samdanbury 6:37b6d0d56190 348 int blink_rate = atoi(pos + 1);
samdanbury 6:37b6d0d56190 349 blink_interval = (blink_rate <= 0) ? 0 : (blink_rate > 50 ? 1 : 50/blink_rate);
samdanbury 6:37b6d0d56190 350 }
samdanbury 6:37b6d0d56190 351 }
samdanbury 6:37b6d0d56190 352 }
samdanbury 6:37b6d0d56190 353 else
samdanbury 6:37b6d0d56190 354 WARN("Unsupported command: %.*s\n", len, start);
samdanbury 6:37b6d0d56190 355 }
samdanbury 6:37b6d0d56190 356
samdanbury 6:37b6d0d56190 357
samdanbury 6:37b6d0d56190 358 int main()
samdanbury 6:37b6d0d56190 359 {
icraggs 8:80d49dd91542 360 quickstartMode = (strcmp(org, "quickstart") == 0);
icraggs 8:80d49dd91542 361
samdanbury 6:37b6d0d56190 362 lcd.set_font((unsigned char*) Arial12x12); // Set a nice font for the LCD screen
samdanbury 6:37b6d0d56190 363
samdanbury 6:37b6d0d56190 364 led2 = LED2_OFF; // K64F: turn off the main board LED
samdanbury 6:37b6d0d56190 365
samdanbury 6:37b6d0d56190 366 displayMessage("Connecting");
samdanbury 6:37b6d0d56190 367 #if defined(TARGET_K64F)
samdanbury 6:37b6d0d56190 368 yellow(); // Don't flash on the K64F, because starting a thread causes the EthernetInterface init call to hang
samdanbury 6:37b6d0d56190 369 #else
samdanbury 6:37b6d0d56190 370 Thread yellow_thread(flashing_yellow);
samdanbury 6:37b6d0d56190 371 #endif
samdanbury 6:37b6d0d56190 372
samdanbury 6:37b6d0d56190 373 MQTTEthernet ipstack;
samdanbury 6:37b6d0d56190 374 MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE> client(ipstack);
samdanbury 6:37b6d0d56190 375
samdanbury 6:37b6d0d56190 376 if (quickstartMode)
samdanbury 6:37b6d0d56190 377 {
samdanbury 6:37b6d0d56190 378 #if defined(TARGET_K64F)
samdanbury 6:37b6d0d56190 379 getUUID48(id, sizeof(id)); // getMac doesn't work on the K64F
samdanbury 6:37b6d0d56190 380 #else
samdanbury 6:37b6d0d56190 381 getMac(ipstack.getEth(), id, sizeof(id));
samdanbury 6:37b6d0d56190 382 #endif
samdanbury 6:37b6d0d56190 383 }
samdanbury 6:37b6d0d56190 384
samdanbury 6:37b6d0d56190 385 attemptConnect(&client, &ipstack);
samdanbury 6:37b6d0d56190 386
samdanbury 6:37b6d0d56190 387 if (!quickstartMode)
samdanbury 6:37b6d0d56190 388 {
samdanbury 6:37b6d0d56190 389 int rc = 0;
samdanbury 6:37b6d0d56190 390 if ((rc = client.subscribe("iot-2/cmd/+/fmt/json", MQTT::QOS1, messageArrived)) != 0)
samdanbury 6:37b6d0d56190 391 WARN("rc from MQTT subscribe is %d\n", rc);
samdanbury 6:37b6d0d56190 392 }
samdanbury 6:37b6d0d56190 393
samdanbury 6:37b6d0d56190 394 blink_interval = 0;
samdanbury 6:37b6d0d56190 395 int count = 0;
samdanbury 6:37b6d0d56190 396 while (true)
samdanbury 6:37b6d0d56190 397 {
samdanbury 6:37b6d0d56190 398 if (++count == 100)
samdanbury 6:37b6d0d56190 399 { // Publish a message every second
samdanbury 6:37b6d0d56190 400 if (publish(&client, &ipstack) != 0)
samdanbury 6:37b6d0d56190 401 attemptConnect(&client, &ipstack); // if we have lost the connection
samdanbury 6:37b6d0d56190 402 count = 0;
samdanbury 6:37b6d0d56190 403 }
samdanbury 6:37b6d0d56190 404
samdanbury 6:37b6d0d56190 405 if (blink_interval == 0)
samdanbury 6:37b6d0d56190 406 led2 = LED2_OFF;
samdanbury 6:37b6d0d56190 407 else if (count % blink_interval == 0)
samdanbury 6:37b6d0d56190 408 led2 = !led2;
samdanbury 6:37b6d0d56190 409 if (count % 20 == 0)
samdanbury 6:37b6d0d56190 410 setMenu();
samdanbury 6:37b6d0d56190 411 client.yield(10); // allow the MQTT client to receive messages
samdanbury 6:37b6d0d56190 412 }
samdanbury 6:37b6d0d56190 413 }