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:
icraggs
Date:
Mon Aug 03 12:41:51 2015 +0000
Revision:
16:2420bfbf5f1c
Parent:
15:09458079f4bb
Child:
17:74801ec6a672
Add authorization check and diagnostic messages

Who changed what in which revision?

UserRevisionLine numberNew contents of line
samdanbury 6:37b6d0d56190 1 /*******************************************************************************
icraggs 16:2420bfbf5f1c 2 * Copyright (c) 2014, 2015 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
icraggs 16:2420bfbf5f1c 18 * James Sutton - Mac fix and extra debug
icraggs 16:2420bfbf5f1c 19 * Ian Craggs - add not authorized messages
chris 10:0b5e0dfee08e 20 *
chris 10:0b5e0dfee08e 21 * To do :
chris 10:0b5e0dfee08e 22 * Add magnetometer sensor output to IoT data stream
chris 10:0b5e0dfee08e 23 *
samdanbury 6:37b6d0d56190 24 *******************************************************************************/
samdanbury 6:37b6d0d56190 25
samdanbury 6:37b6d0d56190 26 #include "LM75B.h"
samdanbury 6:37b6d0d56190 27 #include "MMA7660.h"
samdanbury 6:37b6d0d56190 28 #include "MQTTClient.h"
samdanbury 6:37b6d0d56190 29 #include "MQTTEthernet.h"
samdanbury 6:37b6d0d56190 30 #include "C12832.h"
samdanbury 6:37b6d0d56190 31 #include "Arial12x12.h"
samdanbury 6:37b6d0d56190 32 #include "rtos.h"
samdanbury 6:37b6d0d56190 33
chris 10:0b5e0dfee08e 34 // Update this to the next number *before* a commit
icraggs 16:2420bfbf5f1c 35 #define __APP_SW_REVISION__ "12"
chris 10:0b5e0dfee08e 36
samdanbury 6:37b6d0d56190 37 // Configuration values needed to connect to IBM IoT Cloud
icraggs 8:80d49dd91542 38 #define ORG "quickstart" // For a registered connection, replace with your org
icraggs 8:80d49dd91542 39 #define ID "" // For a registered connection, replace with your id
icraggs 8:80d49dd91542 40 #define AUTH_TOKEN "" // For a registered connection, replace with your auth-token
icraggs 8:80d49dd91542 41 #define TYPE DEFAULT_TYPE_NAME // For a registered connection, replace with your type
samdanbury 6:37b6d0d56190 42
samdanbury 6:37b6d0d56190 43 #define MQTT_PORT 1883
samdanbury 6:37b6d0d56190 44 #define MQTT_TLS_PORT 8883
samdanbury 6:37b6d0d56190 45 #define IBM_IOT_PORT MQTT_PORT
samdanbury 6:37b6d0d56190 46
samdanbury 6:37b6d0d56190 47 #define MQTT_MAX_PACKET_SIZE 250
samdanbury 6:37b6d0d56190 48
mazgch 11:7a6df9a2dcdc 49 #if defined(TARGET_UBLOX_C027)
mazgch 11:7a6df9a2dcdc 50 #warning "Compiling for mbed C027"
mazgch 11:7a6df9a2dcdc 51 #include "C027.h"
mazgch 11:7a6df9a2dcdc 52 #elif defined(TARGET_LPC1768)
samdanbury 6:37b6d0d56190 53 #warning "Compiling for mbed LPC1768"
samdanbury 6:37b6d0d56190 54 #include "LPC1768.h"
samdanbury 6:37b6d0d56190 55 #elif defined(TARGET_K64F)
samdanbury 6:37b6d0d56190 56 #warning "Compiling for mbed K64F"
samdanbury 6:37b6d0d56190 57 #include "K64F.h"
samdanbury 6:37b6d0d56190 58 #endif
samdanbury 6:37b6d0d56190 59
jsutton 14:1f961d19f3cf 60
icraggs 8:80d49dd91542 61 bool quickstartMode = true;
samdanbury 6:37b6d0d56190 62 char org[11] = ORG;
samdanbury 6:37b6d0d56190 63 char type[30] = TYPE;
samdanbury 6:37b6d0d56190 64 char id[30] = ID; // mac without colons
samdanbury 6:37b6d0d56190 65 char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode
samdanbury 6:37b6d0d56190 66
samdanbury 6:37b6d0d56190 67 bool connected = false;
jsutton 14:1f961d19f3cf 68 bool mqttConnecting = false;
jsutton 14:1f961d19f3cf 69 bool netConnected = false;
jsutton 14:1f961d19f3cf 70 bool netConnecting = false;
jsutton 14:1f961d19f3cf 71 bool ethernetInitialising = true;
icraggs 16:2420bfbf5f1c 72 int connack_rc = 0; // MQTT connack return code
jsutton 14:1f961d19f3cf 73 int retryAttempt = 0;
jsutton 14:1f961d19f3cf 74 int menuItem = 0;
jsutton 14:1f961d19f3cf 75
samdanbury 6:37b6d0d56190 76 char* joystickPos = "CENTRE";
samdanbury 6:37b6d0d56190 77 int blink_interval = 0;
samdanbury 6:37b6d0d56190 78
jsutton 13:85801e3b83d3 79 char* ip_addr = "";
jsutton 13:85801e3b83d3 80 char* gateway_addr = "";
jsutton 14:1f961d19f3cf 81 char* host_addr = "";
jsutton 14:1f961d19f3cf 82 int connectTimeout = 1000;
jsutton 14:1f961d19f3cf 83
jsutton 14:1f961d19f3cf 84 // If we wanted to manually set the MAC address,
jsutton 14:1f961d19f3cf 85 // this is how to do it. In this example, we take
jsutton 14:1f961d19f3cf 86 // the original Mbed Set MAC address and combine it
jsutton 14:1f961d19f3cf 87 // with a prefix of our choosing.
jsutton 14:1f961d19f3cf 88 /*
jsutton 14:1f961d19f3cf 89 extern "C" void $Super$$mbed_mac_address(char *s);
jsutton 14:1f961d19f3cf 90 extern "C" void $Sub$$mbed_mac_address(char *s)
jsutton 14:1f961d19f3cf 91 {
jsutton 15:09458079f4bb 92 char originalMAC[6] = "";
jsutton 15:09458079f4bb 93 $Super$$mbed_mac_address(originalMAC);
jsutton 14:1f961d19f3cf 94
jsutton 14:1f961d19f3cf 95 char mac[6];
jsutton 14:1f961d19f3cf 96 mac[0] = 0x00;
jsutton 14:1f961d19f3cf 97 mac[1] = 0x08;
jsutton 14:1f961d19f3cf 98 mac[2] = 0xdc;
jsutton 15:09458079f4bb 99 mac[3] = originalMAC[3];
jsutton 15:09458079f4bb 100 mac[4] = originalMAC[4];
jsutton 15:09458079f4bb 101 mac[5] = originalMAC[5];
jsutton 14:1f961d19f3cf 102 memcpy(s, mac, 6);
jsutton 14:1f961d19f3cf 103 }
jsutton 14:1f961d19f3cf 104 */
jsutton 13:85801e3b83d3 105
samdanbury 6:37b6d0d56190 106
samdanbury 6:37b6d0d56190 107 void off()
samdanbury 6:37b6d0d56190 108 {
samdanbury 6:37b6d0d56190 109 r = g = b = 1.0; // 1 is off, 0 is full brightness
samdanbury 6:37b6d0d56190 110 }
samdanbury 6:37b6d0d56190 111
samdanbury 6:37b6d0d56190 112 void red()
samdanbury 6:37b6d0d56190 113 {
samdanbury 6:37b6d0d56190 114 r = 0.7; g = 1.0; b = 1.0; // 1 is off, 0 is full brightness
samdanbury 6:37b6d0d56190 115 }
samdanbury 6:37b6d0d56190 116
samdanbury 6:37b6d0d56190 117 void yellow()
samdanbury 6:37b6d0d56190 118 {
samdanbury 6:37b6d0d56190 119 r = 0.7; g = 0.7; b = 1.0; // 1 is off, 0 is full brightness
samdanbury 6:37b6d0d56190 120 }
samdanbury 6:37b6d0d56190 121
samdanbury 6:37b6d0d56190 122 void green()
samdanbury 6:37b6d0d56190 123 {
samdanbury 6:37b6d0d56190 124 r = 1.0; g = 0.7; b = 1.0; // 1 is off, 0 is full brightness
samdanbury 6:37b6d0d56190 125 }
samdanbury 6:37b6d0d56190 126
samdanbury 6:37b6d0d56190 127
samdanbury 6:37b6d0d56190 128 void flashing_yellow(void const *args)
samdanbury 6:37b6d0d56190 129 {
samdanbury 6:37b6d0d56190 130 bool on = false;
icraggs 16:2420bfbf5f1c 131 while (!connected && connack_rc != MQTT_NOT_AUTHORIZED && connack_rc != MQTT_BAD_USERNAME_OR_PASSWORD) // flashing yellow only while connecting
samdanbury 6:37b6d0d56190 132 {
samdanbury 6:37b6d0d56190 133 on = !on;
samdanbury 6:37b6d0d56190 134 if (on)
samdanbury 6:37b6d0d56190 135 yellow();
samdanbury 6:37b6d0d56190 136 else
samdanbury 6:37b6d0d56190 137 off();
samdanbury 6:37b6d0d56190 138 wait(0.5);
samdanbury 6:37b6d0d56190 139 }
samdanbury 6:37b6d0d56190 140 }
samdanbury 6:37b6d0d56190 141
samdanbury 6:37b6d0d56190 142
samdanbury 6:37b6d0d56190 143 void flashing_red(void const *args) // to be used when the connection is lost
samdanbury 6:37b6d0d56190 144 {
samdanbury 6:37b6d0d56190 145 bool on = false;
samdanbury 6:37b6d0d56190 146 while (!connected)
samdanbury 6:37b6d0d56190 147 {
samdanbury 6:37b6d0d56190 148 on = !on;
samdanbury 6:37b6d0d56190 149 if (on)
samdanbury 6:37b6d0d56190 150 red();
samdanbury 6:37b6d0d56190 151 else
samdanbury 6:37b6d0d56190 152 off();
samdanbury 6:37b6d0d56190 153 wait(2.0);
samdanbury 6:37b6d0d56190 154 }
samdanbury 6:37b6d0d56190 155 }
samdanbury 6:37b6d0d56190 156
samdanbury 6:37b6d0d56190 157
samdanbury 6:37b6d0d56190 158 void printMenu(int menuItem)
samdanbury 6:37b6d0d56190 159 {
samdanbury 6:37b6d0d56190 160 lcd.cls();
samdanbury 6:37b6d0d56190 161 lcd.locate(0,0);
samdanbury 6:37b6d0d56190 162 switch (menuItem)
samdanbury 6:37b6d0d56190 163 {
samdanbury 6:37b6d0d56190 164 case 0:
samdanbury 6:37b6d0d56190 165 lcd.printf("IBM IoT Cloud");
samdanbury 6:37b6d0d56190 166 lcd.locate(0,16);
samdanbury 6:37b6d0d56190 167 lcd.printf("Scroll with joystick");
samdanbury 6:37b6d0d56190 168 break;
samdanbury 6:37b6d0d56190 169 case 1:
samdanbury 6:37b6d0d56190 170 lcd.printf("Go to:");
samdanbury 6:37b6d0d56190 171 lcd.locate(0,16);
samdanbury 6:37b6d0d56190 172 lcd.printf("http://ibm.biz/iotqstart");
samdanbury 6:37b6d0d56190 173 break;
samdanbury 6:37b6d0d56190 174 case 2:
samdanbury 6:37b6d0d56190 175 lcd.printf("Device Identity:");
samdanbury 6:37b6d0d56190 176 lcd.locate(0,16);
samdanbury 6:37b6d0d56190 177 lcd.printf("%s", id);
samdanbury 6:37b6d0d56190 178 break;
samdanbury 6:37b6d0d56190 179 case 3:
jsutton 13:85801e3b83d3 180 lcd.printf("MQTT Status:");
samdanbury 6:37b6d0d56190 181 lcd.locate(0,16);
icraggs 16:2420bfbf5f1c 182 if (mqttConnecting)
jsutton 14:1f961d19f3cf 183 lcd.printf("Connecting... %d/5", retryAttempt);
icraggs 16:2420bfbf5f1c 184 else
icraggs 16:2420bfbf5f1c 185 {
icraggs 16:2420bfbf5f1c 186 if (connected)
icraggs 16:2420bfbf5f1c 187 lcd.printf("Connected");
icraggs 16:2420bfbf5f1c 188 else
icraggs 16:2420bfbf5f1c 189 {
icraggs 16:2420bfbf5f1c 190 switch (connack_rc)
icraggs 16:2420bfbf5f1c 191 {
icraggs 16:2420bfbf5f1c 192 case MQTT_CLIENTID_REJECTED:
icraggs 16:2420bfbf5f1c 193 lcd.printf("Clientid rejected");
icraggs 16:2420bfbf5f1c 194 break;
icraggs 16:2420bfbf5f1c 195 case MQTT_BAD_USERNAME_OR_PASSWORD:
icraggs 16:2420bfbf5f1c 196 lcd.printf("Invalid username or password");
icraggs 16:2420bfbf5f1c 197 break;
icraggs 16:2420bfbf5f1c 198 case MQTT_NOT_AUTHORIZED:
icraggs 16:2420bfbf5f1c 199 lcd.printf("Not authorized");
icraggs 16:2420bfbf5f1c 200 break;
icraggs 16:2420bfbf5f1c 201 default:
icraggs 16:2420bfbf5f1c 202 lcd.printf("Disconnected");
icraggs 16:2420bfbf5f1c 203 }
icraggs 16:2420bfbf5f1c 204 }
jsutton 14:1f961d19f3cf 205 }
samdanbury 6:37b6d0d56190 206 break;
chris 10:0b5e0dfee08e 207 case 4:
jsutton 14:1f961d19f3cf 208 lcd.printf("Ethernet State:");
jsutton 14:1f961d19f3cf 209 lcd.locate(0,16);
jsutton 14:1f961d19f3cf 210 lcd.printf(ethernetInitialising ? "Initialising..." : "Initialised");
jsutton 14:1f961d19f3cf 211 break;
jsutton 14:1f961d19f3cf 212 case 5:
jsutton 13:85801e3b83d3 213 lcd.printf("Socket State:");
jsutton 13:85801e3b83d3 214 lcd.locate(0,16);
icraggs 16:2420bfbf5f1c 215 if (netConnecting)
jsutton 14:1f961d19f3cf 216 lcd.printf("Connecting... %d/5", retryAttempt);
icraggs 16:2420bfbf5f1c 217 else
jsutton 14:1f961d19f3cf 218 lcd.printf(netConnected ? "Connected" : "Disconnected");
jsutton 13:85801e3b83d3 219 break;
jsutton 14:1f961d19f3cf 220 case 6:
jsutton 13:85801e3b83d3 221 lcd.printf("IP Address:");
jsutton 13:85801e3b83d3 222 lcd.locate(0,16);
jsutton 13:85801e3b83d3 223 lcd.printf("%s", ip_addr);
jsutton 13:85801e3b83d3 224 break;
jsutton 14:1f961d19f3cf 225 case 7:
jsutton 13:85801e3b83d3 226 lcd.printf("Gateway:");
jsutton 13:85801e3b83d3 227 lcd.locate(0,16);
icraggs 16:2420bfbf5f1c 228 lcd.printf("%s", gateway_addr);
jsutton 13:85801e3b83d3 229 break;
jsutton 14:1f961d19f3cf 230 case 8:
chris 10:0b5e0dfee08e 231 lcd.printf("App version:");
chris 10:0b5e0dfee08e 232 lcd.locate(0,16);
icraggs 16:2420bfbf5f1c 233 lcd.printf("%s", __APP_SW_REVISION__);
chris 10:0b5e0dfee08e 234 break;
jsutton 14:1f961d19f3cf 235 case 9:
jsutton 14:1f961d19f3cf 236 lcd.printf("Current Timeout:");
jsutton 14:1f961d19f3cf 237 lcd.locate(0,16);
icraggs 16:2420bfbf5f1c 238 lcd.printf("%d ms", connectTimeout);
jsutton 14:1f961d19f3cf 239 break;
samdanbury 6:37b6d0d56190 240 }
samdanbury 6:37b6d0d56190 241 }
samdanbury 6:37b6d0d56190 242
samdanbury 6:37b6d0d56190 243
samdanbury 6:37b6d0d56190 244 void setMenu()
samdanbury 6:37b6d0d56190 245 {
jsutton 14:1f961d19f3cf 246
samdanbury 6:37b6d0d56190 247 if (Down)
samdanbury 6:37b6d0d56190 248 {
samdanbury 6:37b6d0d56190 249 joystickPos = "DOWN";
jsutton 14:1f961d19f3cf 250 if (menuItem >= 0 && menuItem < 9)
samdanbury 6:37b6d0d56190 251 printMenu(++menuItem);
samdanbury 6:37b6d0d56190 252 }
samdanbury 6:37b6d0d56190 253 else if (Left)
samdanbury 6:37b6d0d56190 254 joystickPos = "LEFT";
samdanbury 6:37b6d0d56190 255 else if (Click)
samdanbury 6:37b6d0d56190 256 joystickPos = "CLICK";
samdanbury 6:37b6d0d56190 257 else if (Up)
samdanbury 6:37b6d0d56190 258 {
samdanbury 6:37b6d0d56190 259 joystickPos = "UP";
jsutton 14:1f961d19f3cf 260 if (menuItem <= 9 && menuItem > 0)
samdanbury 6:37b6d0d56190 261 printMenu(--menuItem);
samdanbury 6:37b6d0d56190 262 }
samdanbury 6:37b6d0d56190 263 else if (Right)
samdanbury 6:37b6d0d56190 264 joystickPos = "RIGHT";
samdanbury 6:37b6d0d56190 265 else
samdanbury 6:37b6d0d56190 266 joystickPos = "CENTRE";
samdanbury 6:37b6d0d56190 267 }
samdanbury 6:37b6d0d56190 268
jsutton 13:85801e3b83d3 269 void menu_loop(void const *args)
jsutton 13:85801e3b83d3 270 {
jsutton 14:1f961d19f3cf 271 int count = 0;
icraggs 16:2420bfbf5f1c 272 while(true)
icraggs 16:2420bfbf5f1c 273 {
jsutton 13:85801e3b83d3 274 setMenu();
icraggs 16:2420bfbf5f1c 275 if (++count % 10 == 0)
jsutton 14:1f961d19f3cf 276 printMenu(menuItem);
jsutton 14:1f961d19f3cf 277 Thread::wait(100);
jsutton 13:85801e3b83d3 278 }
jsutton 13:85801e3b83d3 279 }
jsutton 13:85801e3b83d3 280
samdanbury 6:37b6d0d56190 281
samdanbury 6:37b6d0d56190 282 /**
samdanbury 6:37b6d0d56190 283 * Display a message on the LCD screen prefixed with IBM IoT Cloud
samdanbury 6:37b6d0d56190 284 */
samdanbury 6:37b6d0d56190 285 void displayMessage(char* message)
samdanbury 6:37b6d0d56190 286 {
samdanbury 6:37b6d0d56190 287 lcd.cls();
samdanbury 6:37b6d0d56190 288 lcd.locate(0,0);
samdanbury 6:37b6d0d56190 289 lcd.printf("IBM IoT Cloud");
samdanbury 6:37b6d0d56190 290 lcd.locate(0,16);
samdanbury 6:37b6d0d56190 291 lcd.printf(message);
samdanbury 6:37b6d0d56190 292 }
samdanbury 6:37b6d0d56190 293
samdanbury 6:37b6d0d56190 294
samdanbury 6:37b6d0d56190 295 int connect(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack)
samdanbury 6:37b6d0d56190 296 {
samdanbury 6:37b6d0d56190 297 const char* iot_ibm = ".messaging.internetofthings.ibmcloud.com";
samdanbury 6:37b6d0d56190 298
samdanbury 6:37b6d0d56190 299 char hostname[strlen(org) + strlen(iot_ibm) + 1];
samdanbury 6:37b6d0d56190 300 sprintf(hostname, "%s%s", org, iot_ibm);
jsutton 13:85801e3b83d3 301 EthernetInterface& eth = ipstack->getEth();
jsutton 13:85801e3b83d3 302 ip_addr = eth.getIPAddress();
jsutton 13:85801e3b83d3 303 gateway_addr = eth.getGateway();
jsutton 14:1f961d19f3cf 304
jsutton 14:1f961d19f3cf 305 // Construct clientId - d:org:type:id
jsutton 14:1f961d19f3cf 306 char clientId[strlen(org) + strlen(type) + strlen(id) + 5];
jsutton 14:1f961d19f3cf 307 sprintf(clientId, "d:%s:%s:%s", org, type, id);
jsutton 14:1f961d19f3cf 308
icraggs 16:2420bfbf5f1c 309 // Network debug statements
jsutton 14:1f961d19f3cf 310 LOG("=====================================\n");
jsutton 14:1f961d19f3cf 311 LOG("Connecting Ethernet.\n");
jsutton 14:1f961d19f3cf 312 LOG("IP ADDRESS: %s\n", eth.getIPAddress());
jsutton 14:1f961d19f3cf 313 LOG("MAC ADDRESS: %s\n", eth.getMACAddress());
jsutton 14:1f961d19f3cf 314 LOG("Gateway: %s\n", eth.getGateway());
jsutton 14:1f961d19f3cf 315 LOG("Network Mask: %s\n", eth.getNetworkMask());
jsutton 14:1f961d19f3cf 316 LOG("Server Hostname: %s\n", hostname);
jsutton 14:1f961d19f3cf 317 LOG("Client ID: %s\n", clientId);
jsutton 14:1f961d19f3cf 318 LOG("=====================================\n");
jsutton 14:1f961d19f3cf 319
jsutton 14:1f961d19f3cf 320 netConnecting = true;
jsutton 14:1f961d19f3cf 321 int rc = ipstack->connect(hostname, IBM_IOT_PORT, connectTimeout);
icraggs 16:2420bfbf5f1c 322 if (rc != 0)
icraggs 16:2420bfbf5f1c 323 {
jsutton 13:85801e3b83d3 324 WARN("IP Stack returned: %d\n", rc);
samdanbury 6:37b6d0d56190 325 return rc;
jsutton 13:85801e3b83d3 326 }
jsutton 13:85801e3b83d3 327 netConnected = true;
jsutton 14:1f961d19f3cf 328 netConnecting = false;
jsutton 14:1f961d19f3cf 329
samdanbury 6:37b6d0d56190 330 // MQTT Connect
jsutton 14:1f961d19f3cf 331 mqttConnecting = true;
samdanbury 6:37b6d0d56190 332 MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
samdanbury 6:37b6d0d56190 333 data.MQTTVersion = 3;
samdanbury 6:37b6d0d56190 334 data.clientID.cstring = clientId;
samdanbury 6:37b6d0d56190 335
samdanbury 6:37b6d0d56190 336 if (!quickstartMode)
samdanbury 6:37b6d0d56190 337 {
samdanbury 6:37b6d0d56190 338 data.username.cstring = "use-token-auth";
samdanbury 6:37b6d0d56190 339 data.password.cstring = auth_token;
samdanbury 6:37b6d0d56190 340 }
samdanbury 6:37b6d0d56190 341
icraggs 8:80d49dd91542 342 if ((rc = client->connect(data)) == 0)
samdanbury 6:37b6d0d56190 343 {
samdanbury 6:37b6d0d56190 344 connected = true;
samdanbury 6:37b6d0d56190 345 green();
samdanbury 6:37b6d0d56190 346 displayMessage("Connected");
jsutton 13:85801e3b83d3 347 wait(1);
samdanbury 6:37b6d0d56190 348 displayMessage("Scroll with joystick");
samdanbury 6:37b6d0d56190 349 }
icraggs 16:2420bfbf5f1c 350 else
icraggs 16:2420bfbf5f1c 351 WARN("MQTT connect returned %d\n", rc);
icraggs 16:2420bfbf5f1c 352 if (rc >= 0)
icraggs 16:2420bfbf5f1c 353 connack_rc = rc;
jsutton 14:1f961d19f3cf 354 mqttConnecting = false;
samdanbury 6:37b6d0d56190 355 return rc;
samdanbury 6:37b6d0d56190 356 }
samdanbury 6:37b6d0d56190 357
samdanbury 6:37b6d0d56190 358
samdanbury 6:37b6d0d56190 359 int getConnTimeout(int attemptNumber)
samdanbury 6:37b6d0d56190 360 { // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute
samdanbury 6:37b6d0d56190 361 // after 20 attempts, retry every 10 minutes
samdanbury 6:37b6d0d56190 362 return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600;
samdanbury 6:37b6d0d56190 363 }
samdanbury 6:37b6d0d56190 364
samdanbury 6:37b6d0d56190 365
samdanbury 6:37b6d0d56190 366 void attemptConnect(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack)
samdanbury 6:37b6d0d56190 367 {
samdanbury 6:37b6d0d56190 368 connected = false;
icraggs 16:2420bfbf5f1c 369
icraggs 8:80d49dd91542 370 // make sure a cable is connected before starting to connect
icraggs 16:2420bfbf5f1c 371 while (!linkStatus())
icraggs 16:2420bfbf5f1c 372 {
icraggs 8:80d49dd91542 373 wait(1.0f);
icraggs 8:80d49dd91542 374 WARN("Ethernet link not present. Check cable connection\n");
icraggs 8:80d49dd91542 375 }
samdanbury 6:37b6d0d56190 376
icraggs 16:2420bfbf5f1c 377 while (connect(client, ipstack) != MQTT_CONNECTION_ACCEPTED)
samdanbury 6:37b6d0d56190 378 {
icraggs 16:2420bfbf5f1c 379 if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD)
icraggs 16:2420bfbf5f1c 380 return; // don't reattempt to connect if credentials are wrong
icraggs 16:2420bfbf5f1c 381
samdanbury 6:37b6d0d56190 382 Thread red_thread(flashing_red);
chris 12:8b480eb8a496 383
samdanbury 6:37b6d0d56190 384 int timeout = getConnTimeout(++retryAttempt);
samdanbury 6:37b6d0d56190 385 WARN("Retry attempt number %d waiting %d\n", retryAttempt, timeout);
icraggs 8:80d49dd91542 386
icraggs 8:80d49dd91542 387 // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed
icraggs 8:80d49dd91542 388 // or maybe just add the proper members to do this disconnect and call attemptConnect(...)
icraggs 8:80d49dd91542 389
icraggs 8:80d49dd91542 390 // this works - reset the system when the retry count gets to a threshold
icraggs 8:80d49dd91542 391 if (retryAttempt == 5)
icraggs 8:80d49dd91542 392 NVIC_SystemReset();
icraggs 8:80d49dd91542 393 else
icraggs 8:80d49dd91542 394 wait(timeout);
samdanbury 6:37b6d0d56190 395 }
samdanbury 6:37b6d0d56190 396 }
samdanbury 6:37b6d0d56190 397
samdanbury 6:37b6d0d56190 398
samdanbury 6:37b6d0d56190 399 int publish(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack)
samdanbury 6:37b6d0d56190 400 {
samdanbury 6:37b6d0d56190 401 MQTT::Message message;
samdanbury 6:37b6d0d56190 402 char* pubTopic = "iot-2/evt/status/fmt/json";
samdanbury 6:37b6d0d56190 403
samdanbury 6:37b6d0d56190 404 char buf[250];
samdanbury 6:37b6d0d56190 405 sprintf(buf,
samdanbury 6:37b6d0d56190 406 "{\"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 407 MMA.x(), MMA.y(), MMA.z(), sensor.temp(), joystickPos, ain1.read(), ain2.read());
samdanbury 6:37b6d0d56190 408 message.qos = MQTT::QOS0;
samdanbury 6:37b6d0d56190 409 message.retained = false;
samdanbury 6:37b6d0d56190 410 message.dup = false;
samdanbury 6:37b6d0d56190 411 message.payload = (void*)buf;
samdanbury 6:37b6d0d56190 412 message.payloadlen = strlen(buf);
samdanbury 6:37b6d0d56190 413
samdanbury 6:37b6d0d56190 414 LOG("Publishing %s\n", buf);
icraggs 8:80d49dd91542 415 return client->publish(pubTopic, message);
samdanbury 6:37b6d0d56190 416 }
samdanbury 6:37b6d0d56190 417
samdanbury 6:37b6d0d56190 418
samdanbury 6:37b6d0d56190 419 char* getMac(EthernetInterface& eth, char* buf, int buflen) // Obtain MAC address
samdanbury 6:37b6d0d56190 420 {
samdanbury 6:37b6d0d56190 421 strncpy(buf, eth.getMACAddress(), buflen);
samdanbury 6:37b6d0d56190 422
samdanbury 6:37b6d0d56190 423 char* pos; // Remove colons from mac address
samdanbury 6:37b6d0d56190 424 while ((pos = strchr(buf, ':')) != NULL)
samdanbury 6:37b6d0d56190 425 memmove(pos, pos + 1, strlen(pos) + 1);
samdanbury 6:37b6d0d56190 426 return buf;
samdanbury 6:37b6d0d56190 427 }
chris 12:8b480eb8a496 428
samdanbury 6:37b6d0d56190 429
samdanbury 6:37b6d0d56190 430 void messageArrived(MQTT::MessageData& md)
samdanbury 6:37b6d0d56190 431 {
samdanbury 6:37b6d0d56190 432 MQTT::Message &message = md.message;
samdanbury 6:37b6d0d56190 433 char topic[md.topicName.lenstring.len + 1];
samdanbury 6:37b6d0d56190 434
samdanbury 6:37b6d0d56190 435 sprintf(topic, "%.*s", md.topicName.lenstring.len, md.topicName.lenstring.data);
samdanbury 6:37b6d0d56190 436
samdanbury 6:37b6d0d56190 437 LOG("Message arrived on topic %s: %.*s\n", topic, message.payloadlen, message.payload);
samdanbury 6:37b6d0d56190 438
samdanbury 6:37b6d0d56190 439 // Command topic: iot-2/cmd/blink/fmt/json - cmd is the string between cmd/ and /fmt/
samdanbury 6:37b6d0d56190 440 char* start = strstr(topic, "/cmd/") + 5;
samdanbury 6:37b6d0d56190 441 int len = strstr(topic, "/fmt/") - start;
samdanbury 6:37b6d0d56190 442
samdanbury 6:37b6d0d56190 443 if (memcmp(start, "blink", len) == 0)
samdanbury 6:37b6d0d56190 444 {
samdanbury 6:37b6d0d56190 445 char payload[message.payloadlen + 1];
samdanbury 6:37b6d0d56190 446 sprintf(payload, "%.*s", message.payloadlen, (char*)message.payload);
samdanbury 6:37b6d0d56190 447
samdanbury 6:37b6d0d56190 448 char* pos = strchr(payload, '}');
samdanbury 6:37b6d0d56190 449 if (pos != NULL)
samdanbury 6:37b6d0d56190 450 {
samdanbury 6:37b6d0d56190 451 *pos = '\0';
samdanbury 6:37b6d0d56190 452 if ((pos = strchr(payload, ':')) != NULL)
samdanbury 6:37b6d0d56190 453 {
samdanbury 6:37b6d0d56190 454 int blink_rate = atoi(pos + 1);
samdanbury 6:37b6d0d56190 455 blink_interval = (blink_rate <= 0) ? 0 : (blink_rate > 50 ? 1 : 50/blink_rate);
samdanbury 6:37b6d0d56190 456 }
samdanbury 6:37b6d0d56190 457 }
samdanbury 6:37b6d0d56190 458 }
samdanbury 6:37b6d0d56190 459 else
samdanbury 6:37b6d0d56190 460 WARN("Unsupported command: %.*s\n", len, start);
samdanbury 6:37b6d0d56190 461 }
samdanbury 6:37b6d0d56190 462
samdanbury 6:37b6d0d56190 463
samdanbury 6:37b6d0d56190 464 int main()
samdanbury 6:37b6d0d56190 465 {
icraggs 8:80d49dd91542 466 quickstartMode = (strcmp(org, "quickstart") == 0);
icraggs 8:80d49dd91542 467
samdanbury 6:37b6d0d56190 468 lcd.set_font((unsigned char*) Arial12x12); // Set a nice font for the LCD screen
samdanbury 6:37b6d0d56190 469
samdanbury 6:37b6d0d56190 470 led2 = LED2_OFF; // K64F: turn off the main board LED
samdanbury 6:37b6d0d56190 471
samdanbury 6:37b6d0d56190 472 displayMessage("Connecting");
jsutton 13:85801e3b83d3 473 Thread yellow_thread(flashing_yellow);
jsutton 13:85801e3b83d3 474 Thread menu_thread(menu_loop);
jsutton 13:85801e3b83d3 475
jsutton 14:1f961d19f3cf 476 LOG("***** IBM IoT Client Ethernet Example *****\n");
samdanbury 6:37b6d0d56190 477 MQTTEthernet ipstack;
jsutton 14:1f961d19f3cf 478 ethernetInitialising = false;
samdanbury 6:37b6d0d56190 479 MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE> client(ipstack);
icraggs 16:2420bfbf5f1c 480 LOG("Ethernet Initialised.\n");
jsutton 13:85801e3b83d3 481
samdanbury 6:37b6d0d56190 482 if (quickstartMode)
icraggs 16:2420bfbf5f1c 483 getMac(ipstack.getEth(), id, sizeof(id));
icraggs 16:2420bfbf5f1c 484
icraggs 16:2420bfbf5f1c 485 attemptConnect(&client, &ipstack);
icraggs 16:2420bfbf5f1c 486
icraggs 16:2420bfbf5f1c 487 if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD)
samdanbury 6:37b6d0d56190 488 {
icraggs 16:2420bfbf5f1c 489 red();
icraggs 16:2420bfbf5f1c 490 while (true)
icraggs 16:2420bfbf5f1c 491 wait(1.0); // Permanent failures - don't retry
samdanbury 6:37b6d0d56190 492 }
icraggs 16:2420bfbf5f1c 493
samdanbury 6:37b6d0d56190 494 if (!quickstartMode)
samdanbury 6:37b6d0d56190 495 {
samdanbury 6:37b6d0d56190 496 int rc = 0;
samdanbury 6:37b6d0d56190 497 if ((rc = client.subscribe("iot-2/cmd/+/fmt/json", MQTT::QOS1, messageArrived)) != 0)
samdanbury 6:37b6d0d56190 498 WARN("rc from MQTT subscribe is %d\n", rc);
samdanbury 6:37b6d0d56190 499 }
samdanbury 6:37b6d0d56190 500
samdanbury 6:37b6d0d56190 501 blink_interval = 0;
samdanbury 6:37b6d0d56190 502 int count = 0;
samdanbury 6:37b6d0d56190 503 while (true)
samdanbury 6:37b6d0d56190 504 {
samdanbury 6:37b6d0d56190 505 if (++count == 100)
samdanbury 6:37b6d0d56190 506 { // Publish a message every second
samdanbury 6:37b6d0d56190 507 if (publish(&client, &ipstack) != 0)
samdanbury 6:37b6d0d56190 508 attemptConnect(&client, &ipstack); // if we have lost the connection
samdanbury 6:37b6d0d56190 509 count = 0;
samdanbury 6:37b6d0d56190 510 }
samdanbury 6:37b6d0d56190 511
samdanbury 6:37b6d0d56190 512 if (blink_interval == 0)
samdanbury 6:37b6d0d56190 513 led2 = LED2_OFF;
samdanbury 6:37b6d0d56190 514 else if (count % blink_interval == 0)
samdanbury 6:37b6d0d56190 515 led2 = !led2;
samdanbury 6:37b6d0d56190 516 client.yield(10); // allow the MQTT client to receive messages
samdanbury 6:37b6d0d56190 517 }
samdanbury 6:37b6d0d56190 518 }