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:
mazgch
Date:
Tue Mar 10 08:24:52 2015 +0000
Revision:
11:7a6df9a2dcdc
Parent:
10:0b5e0dfee08e
Child:
12:8b480eb8a496
enable the C027

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