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:
samdanbury
Date:
Fri Jul 18 07:57:45 2014 +0000
Revision:
1:1f187285667c
Parent:
0:cae064bcbe5e
Child:
2:d8fddda78c38
Add reconnect logic, LCD menu that scrolls and lights to show MQTT connectivity status

Who changed what in which revision?

UserRevisionLine numberNew contents of line
samdanbury 0:cae064bcbe5e 1 /*******************************************************************************
samdanbury 0:cae064bcbe5e 2 * Copyright (c) 2014 IBM Corporation and other Contributors.
samdanbury 0:cae064bcbe5e 3 *
samdanbury 0:cae064bcbe5e 4 * All rights reserved. This program and the accompanying materials
samdanbury 0:cae064bcbe5e 5 * are made available under the terms of the Eclipse Public License v1.0
samdanbury 0:cae064bcbe5e 6 * which accompanies this distribution, and is available at
samdanbury 0:cae064bcbe5e 7 * http://www.eclipse.org/legal/epl-v10.html
samdanbury 0:cae064bcbe5e 8 *
samdanbury 0:cae064bcbe5e 9 * Contributors: Sam Danbury
samdanbury 0:cae064bcbe5e 10 * IBM - Initial Contribution
samdanbury 0:cae064bcbe5e 11 *******************************************************************************/
samdanbury 0:cae064bcbe5e 12
samdanbury 0:cae064bcbe5e 13 #include "stdio.h"
samdanbury 0:cae064bcbe5e 14 #include "mbed.h"
samdanbury 0:cae064bcbe5e 15 #include "rtos.h"
samdanbury 0:cae064bcbe5e 16 #include "C12832.h"
samdanbury 0:cae064bcbe5e 17 #include "LM75B.h"
samdanbury 0:cae064bcbe5e 18 #include "MMA7660.h"
samdanbury 0:cae064bcbe5e 19 #include "C12832.h"
samdanbury 0:cae064bcbe5e 20 #include "MQTTEthernetIoT.h"
samdanbury 0:cae064bcbe5e 21 #include "MQTTClient.h"
samdanbury 0:cae064bcbe5e 22 #include "ConfigFile.h"
samdanbury 1:1f187285667c 23 #include "Arial12x12.h"
samdanbury 0:cae064bcbe5e 24
samdanbury 0:cae064bcbe5e 25 #include <string>
samdanbury 0:cae064bcbe5e 26 #include <sstream>
samdanbury 0:cae064bcbe5e 27 #include <algorithm>
samdanbury 0:cae064bcbe5e 28
samdanbury 0:cae064bcbe5e 29 using namespace std;
samdanbury 0:cae064bcbe5e 30
samdanbury 0:cae064bcbe5e 31 #ifdef TARGET_LPC1768
samdanbury 0:cae064bcbe5e 32
samdanbury 0:cae064bcbe5e 33 #warning "Compiling for mbed LPC1768"
samdanbury 0:cae064bcbe5e 34
samdanbury 0:cae064bcbe5e 35 LocalFileSystem local("local");
samdanbury 0:cae064bcbe5e 36 C12832 lcd(p5, p7, p6, p8, p11);
samdanbury 0:cae064bcbe5e 37 DigitalOut led2(LED2);
samdanbury 1:1f187285667c 38 PwmOut r (p23);
samdanbury 1:1f187285667c 39 PwmOut g (p24);
samdanbury 1:1f187285667c 40 PwmOut b (p25);
samdanbury 0:cae064bcbe5e 41 MMA7660 MMA(p28, p27);
samdanbury 0:cae064bcbe5e 42 LM75B sensor(p28, p27);
samdanbury 0:cae064bcbe5e 43 DigitalIn Down(p12);
samdanbury 0:cae064bcbe5e 44 DigitalIn Left(p13);
samdanbury 0:cae064bcbe5e 45 DigitalIn Click(p14);
samdanbury 0:cae064bcbe5e 46 DigitalIn Up(p15);
samdanbury 0:cae064bcbe5e 47 DigitalIn Right(p16);
samdanbury 0:cae064bcbe5e 48 AnalogIn ain1(p19);
samdanbury 0:cae064bcbe5e 49 AnalogIn ain2(p20);
samdanbury 0:cae064bcbe5e 50
samdanbury 0:cae064bcbe5e 51 #elif TARGET_K64F
samdanbury 0:cae064bcbe5e 52
samdanbury 0:cae064bcbe5e 53 #warning "Compiling for mbed K64F"
samdanbury 0:cae064bcbe5e 54
samdanbury 0:cae064bcbe5e 55 //#define ORGANISATION "<org>";
samdanbury 0:cae064bcbe5e 56 //#define TYPE "<type>";
samdanbury 0:cae064bcbe5e 57 //#define ID "<id>";
samdanbury 0:cae064bcbe5e 58 //#define AUTHMETHOD "<auth-method>";
samdanbury 0:cae064bcbe5e 59 //#define AUTHTOKEN "<auth-token>";
samdanbury 0:cae064bcbe5e 60
samdanbury 0:cae064bcbe5e 61 C12832 lcd(D11, D13, D12, D7, D10);
samdanbury 1:1f187285667c 62 PwmOut r (D5);
samdanbury 1:1f187285667c 63 PwmOut g (D8);
samdanbury 1:1f187285667c 64 PwmOut b (D9);
samdanbury 1:1f187285667c 65 DigitalOut led2(LED2);
samdanbury 0:cae064bcbe5e 66 MMA7660 MMA(PTE25, PTE24);
samdanbury 0:cae064bcbe5e 67 LM75B sensor(PTE25, PTE24);
samdanbury 0:cae064bcbe5e 68 DigitalIn Up(A2);
samdanbury 0:cae064bcbe5e 69 DigitalIn Down(A3);
samdanbury 0:cae064bcbe5e 70 DigitalIn Right(A4);
samdanbury 0:cae064bcbe5e 71 DigitalIn Left(A5);
samdanbury 0:cae064bcbe5e 72 DigitalIn Click(D4);
samdanbury 0:cae064bcbe5e 73 AnalogIn ain1(A0);
samdanbury 0:cae064bcbe5e 74 AnalogIn ain2(A1);
samdanbury 0:cae064bcbe5e 75
samdanbury 0:cae064bcbe5e 76 #else
samdanbury 0:cae064bcbe5e 77
samdanbury 0:cae064bcbe5e 78 LocalFileSystem local("local");
samdanbury 0:cae064bcbe5e 79 C12832 lcd(D11, D13, D12, D7, D10);
samdanbury 0:cae064bcbe5e 80 DigitalOut led1(LED1);
samdanbury 0:cae064bcbe5e 81 DigitalOut led2(LED2);
samdanbury 0:cae064bcbe5e 82 DigitalOut led3(LED3);
samdanbury 0:cae064bcbe5e 83 MMA7660 MMA(D14, D15);
samdanbury 0:cae064bcbe5e 84 LM75B sensor(D14,D15);
samdanbury 0:cae064bcbe5e 85 DigitalIn Up(A2);
samdanbury 0:cae064bcbe5e 86 DigitalIn Down(A3);
samdanbury 0:cae064bcbe5e 87 DigitalIn Left(A4);
samdanbury 0:cae064bcbe5e 88 DigitalIn Right(A5);
samdanbury 0:cae064bcbe5e 89 DigitalIn Click(D4);
samdanbury 0:cae064bcbe5e 90 AnalogIn ain1 (A0);
samdanbury 0:cae064bcbe5e 91 AnalogIn ain2 (A1);
samdanbury 0:cae064bcbe5e 92
samdanbury 0:cae064bcbe5e 93 #endif
samdanbury 0:cae064bcbe5e 94
samdanbury 0:cae064bcbe5e 95 //Joystick
samdanbury 0:cae064bcbe5e 96 string joystickPos;
samdanbury 0:cae064bcbe5e 97 void joystickThread(void const *args);
samdanbury 0:cae064bcbe5e 98
samdanbury 0:cae064bcbe5e 99 //Commands
samdanbury 0:cae064bcbe5e 100 enum command {
samdanbury 0:cae064bcbe5e 101 blink
samdanbury 0:cae064bcbe5e 102 };
samdanbury 0:cae064bcbe5e 103 command getCommand (std::string const& command);
samdanbury 0:cae064bcbe5e 104 void messageArrived(MQTT::MessageData& md);
samdanbury 1:1f187285667c 105
samdanbury 1:1f187285667c 106 //MQTT
samdanbury 1:1f187285667c 107 void connect();
samdanbury 1:1f187285667c 108 void attemptConnect();
samdanbury 1:1f187285667c 109 int getConnTimeout(int attemptNumber);
samdanbury 1:1f187285667c 110 void subscribe();
samdanbury 0:cae064bcbe5e 111
samdanbury 0:cae064bcbe5e 112 //Config
samdanbury 0:cae064bcbe5e 113 void parseConfig();
samdanbury 0:cae064bcbe5e 114 bool quickstartMode = true;
samdanbury 0:cae064bcbe5e 115 string org = "";
samdanbury 0:cae064bcbe5e 116 string type = "";
samdanbury 0:cae064bcbe5e 117 string id = "";
samdanbury 0:cae064bcbe5e 118 string auth_method = "";
samdanbury 0:cae064bcbe5e 119 string auth_token = "";
samdanbury 0:cae064bcbe5e 120 string mac = "";
samdanbury 0:cae064bcbe5e 121
samdanbury 1:1f187285667c 122 //LCD menu
samdanbury 1:1f187285667c 123 bool connected = false;
samdanbury 1:1f187285667c 124 bool menuActivated = false;
samdanbury 1:1f187285667c 125 int menu = 0;
samdanbury 1:1f187285667c 126 void printMenu();
samdanbury 1:1f187285667c 127
samdanbury 1:1f187285667c 128 int interval;
samdanbury 1:1f187285667c 129 string getUUID48();
samdanbury 1:1f187285667c 130
samdanbury 1:1f187285667c 131 MQTTSocket ipstack;
samdanbury 1:1f187285667c 132 MQTT::Client<MQTTSocket, Countdown, 250>* client;
samdanbury 0:cae064bcbe5e 133
samdanbury 0:cae064bcbe5e 134 void parseConfig() {
samdanbury 0:cae064bcbe5e 135
samdanbury 0:cae064bcbe5e 136 ConfigFile cfg;
samdanbury 0:cae064bcbe5e 137
samdanbury 0:cae064bcbe5e 138 char value[30];
samdanbury 0:cae064bcbe5e 139 char value1[30];
samdanbury 0:cae064bcbe5e 140 char value2[30];
samdanbury 0:cae064bcbe5e 141 char value3[30];
samdanbury 0:cae064bcbe5e 142
samdanbury 0:cae064bcbe5e 143 if (cfg.read("/local/device.cfg")) {
samdanbury 0:cae064bcbe5e 144 quickstartMode = false;
samdanbury 0:cae064bcbe5e 145
samdanbury 0:cae064bcbe5e 146 if (cfg.getValue("org", value, sizeof(value))) {
samdanbury 0:cae064bcbe5e 147 stringstream ss(value);
samdanbury 0:cae064bcbe5e 148 ss >> org;
samdanbury 0:cae064bcbe5e 149 }
samdanbury 0:cae064bcbe5e 150 if (cfg.getValue("type", value1, sizeof(value1))) {
samdanbury 0:cae064bcbe5e 151 stringstream ss(value1);
samdanbury 0:cae064bcbe5e 152 ss >> type;
samdanbury 1:1f187285667c 153 }
samdanbury 0:cae064bcbe5e 154 if (cfg.getValue("id", value2, sizeof(value2))) {
samdanbury 0:cae064bcbe5e 155 stringstream ss(value2);
samdanbury 0:cae064bcbe5e 156 ss >> id;
samdanbury 0:cae064bcbe5e 157 }
samdanbury 0:cae064bcbe5e 158 if (cfg.getValue("auth-token", value3, sizeof(value3))) {
samdanbury 0:cae064bcbe5e 159 stringstream ss(value3);
samdanbury 0:cae064bcbe5e 160 ss >> auth_token;
samdanbury 0:cae064bcbe5e 161 }
samdanbury 0:cae064bcbe5e 162
samdanbury 0:cae064bcbe5e 163 } else {
samdanbury 0:cae064bcbe5e 164 quickstartMode = true;
samdanbury 0:cae064bcbe5e 165 org = "quickstart";
samdanbury 0:cae064bcbe5e 166 type = "iotsample-mbed-lpc1768";
samdanbury 0:cae064bcbe5e 167 id = mac;
samdanbury 0:cae064bcbe5e 168 }
samdanbury 0:cae064bcbe5e 169
samdanbury 0:cae064bcbe5e 170 #ifdef TARGET_K64F
samdanbury 0:cae064bcbe5e 171 #ifdef ORGANISATION
samdanbury 0:cae064bcbe5e 172 quickstartMode = false;
samdanbury 0:cae064bcbe5e 173 org = ORGANISATION;
samdanbury 0:cae064bcbe5e 174
samdanbury 0:cae064bcbe5e 175 #ifdef TYPE
samdanbury 0:cae064bcbe5e 176 type = TYPE;
samdanbury 0:cae064bcbe5e 177 #else
samdanbury 0:cae064bcbe5e 178 lcd.printf("Type is not defined");
samdanbury 0:cae064bcbe5e 179 #endif
samdanbury 0:cae064bcbe5e 180
samdanbury 0:cae064bcbe5e 181 #ifdef ID
samdanbury 0:cae064bcbe5e 182 id = ID;
samdanbury 0:cae064bcbe5e 183 #else
samdanbury 0:cae064bcbe5e 184 lcd.printf("ID is not defined");
samdanbury 0:cae064bcbe5e 185 #endif
samdanbury 0:cae064bcbe5e 186
samdanbury 0:cae064bcbe5e 187 #ifdef AUTHMETHOD
samdanbury 0:cae064bcbe5e 188 auth_method = AUTHMETHOD;
samdanbury 0:cae064bcbe5e 189 #else
samdanbury 0:cae064bcbe5e 190 lcd.printf("Auth method is not defined");
samdanbury 0:cae064bcbe5e 191 #endif
samdanbury 0:cae064bcbe5e 192
samdanbury 0:cae064bcbe5e 193 #ifdef AUTHTOKEN
samdanbury 0:cae064bcbe5e 194 auth_token = AUTHTOKEN;
samdanbury 0:cae064bcbe5e 195 #else
samdanbury 0:cae064bcbe5e 196 lcd.printf("Auth token is not defined");
samdanbury 0:cae064bcbe5e 197 #endif
samdanbury 0:cae064bcbe5e 198 #endif
samdanbury 0:cae064bcbe5e 199 #endif
samdanbury 0:cae064bcbe5e 200 }
samdanbury 0:cae064bcbe5e 201
samdanbury 0:cae064bcbe5e 202 int main()
samdanbury 0:cae064bcbe5e 203 {
samdanbury 1:1f187285667c 204 //RGB: yellow
samdanbury 1:1f187285667c 205 r = 0;
samdanbury 1:1f187285667c 206 g = 0;
samdanbury 1:1f187285667c 207 b = 1;
samdanbury 1:1f187285667c 208
samdanbury 1:1f187285667c 209 lcd.cls();
samdanbury 1:1f187285667c 210 lcd.set_font((unsigned char*) Arial12x12);
samdanbury 1:1f187285667c 211 lcd.locate(0,0);
samdanbury 1:1f187285667c 212 lcd.printf("IBM IoT Cloud");
samdanbury 1:1f187285667c 213 lcd.locate(0,16);
samdanbury 1:1f187285667c 214 lcd.printf("Connecting");
samdanbury 0:cae064bcbe5e 215
samdanbury 0:cae064bcbe5e 216 //Connect to network
samdanbury 1:1f187285667c 217 EthernetInterface eth;
samdanbury 1:1f187285667c 218 eth.init();
samdanbury 1:1f187285667c 219 eth.connect();
samdanbury 0:cae064bcbe5e 220
samdanbury 0:cae064bcbe5e 221 //Obtain mac address of mbed
samdanbury 0:cae064bcbe5e 222 #ifdef TARGET_K64F
samdanbury 0:cae064bcbe5e 223 mac = getUUID48();
samdanbury 0:cae064bcbe5e 224 #else
samdanbury 1:1f187285667c 225 mac = eth.getMACAddress();
samdanbury 0:cae064bcbe5e 226
samdanbury 0:cae064bcbe5e 227 //Remove colons from mac address
samdanbury 0:cae064bcbe5e 228 mac.erase(remove(mac.begin(), mac.end(), ':'), mac.end());
samdanbury 0:cae064bcbe5e 229 #endif
samdanbury 0:cae064bcbe5e 230
samdanbury 0:cae064bcbe5e 231 //Parse config file if present
samdanbury 0:cae064bcbe5e 232 parseConfig();
samdanbury 0:cae064bcbe5e 233
samdanbury 1:1f187285667c 234 attemptConnect();
samdanbury 0:cae064bcbe5e 235
samdanbury 0:cae064bcbe5e 236 if (!quickstartMode) {
samdanbury 1:1f187285667c 237 subscribe();
samdanbury 0:cae064bcbe5e 238 }
samdanbury 0:cae064bcbe5e 239
samdanbury 0:cae064bcbe5e 240 //Start thread to read data from joystick
samdanbury 0:cae064bcbe5e 241 joystickPos = "CENTRE";
samdanbury 0:cae064bcbe5e 242 Thread jThd(joystickThread);
samdanbury 0:cae064bcbe5e 243
samdanbury 0:cae064bcbe5e 244 interval = 0;
samdanbury 0:cae064bcbe5e 245 int i = 0;
samdanbury 0:cae064bcbe5e 246
samdanbury 0:cae064bcbe5e 247 while(1)
samdanbury 0:cae064bcbe5e 248 {
samdanbury 0:cae064bcbe5e 249 //Message published every second
samdanbury 0:cae064bcbe5e 250 if (i == 100) {
samdanbury 0:cae064bcbe5e 251 //MQTT Publish
samdanbury 0:cae064bcbe5e 252 MQTT::Message message;
samdanbury 0:cae064bcbe5e 253 char* pubTopic = "iot-2/evt/status/fmt/json";
samdanbury 0:cae064bcbe5e 254
samdanbury 0:cae064bcbe5e 255 char buf[250];
samdanbury 0:cae064bcbe5e 256 sprintf(buf,
samdanbury 0:cae064bcbe5e 257 "{\"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 0:cae064bcbe5e 258 MMA.x(), MMA.y(), MMA.z(),
samdanbury 0:cae064bcbe5e 259 sensor.temp(),
samdanbury 0:cae064bcbe5e 260 joystickPos,
samdanbury 0:cae064bcbe5e 261 ain1.read(),
samdanbury 0:cae064bcbe5e 262 ain2.read());
samdanbury 0:cae064bcbe5e 263 message.qos = MQTT::QOS0;
samdanbury 0:cae064bcbe5e 264 message.retained = false;
samdanbury 0:cae064bcbe5e 265 message.dup = false;
samdanbury 0:cae064bcbe5e 266 message.payload = (void*)buf;
samdanbury 0:cae064bcbe5e 267 message.payloadlen = strlen(buf);
samdanbury 0:cae064bcbe5e 268
samdanbury 1:1f187285667c 269 int rc = 0;
samdanbury 1:1f187285667c 270 if ((rc = client->publish(pubTopic, &message)) != 0) {
samdanbury 1:1f187285667c 271 connected = false;
samdanbury 1:1f187285667c 272 attemptConnect();
samdanbury 1:1f187285667c 273 }
samdanbury 0:cae064bcbe5e 274
samdanbury 0:cae064bcbe5e 275 i = 0;
samdanbury 0:cae064bcbe5e 276 }
samdanbury 0:cae064bcbe5e 277
samdanbury 0:cae064bcbe5e 278 if (interval == 0) {
samdanbury 1:1f187285667c 279 //led2 = 0;
samdanbury 0:cae064bcbe5e 280 } else {
samdanbury 0:cae064bcbe5e 281 if (i%(interval)==0) {
samdanbury 1:1f187285667c 282 //led2 = !led2;
samdanbury 0:cae064bcbe5e 283 }
samdanbury 0:cae064bcbe5e 284 }
samdanbury 0:cae064bcbe5e 285
samdanbury 0:cae064bcbe5e 286 wait(0.01);
samdanbury 0:cae064bcbe5e 287 i++;
samdanbury 1:1f187285667c 288 client->yield(1);
samdanbury 1:1f187285667c 289 }
samdanbury 1:1f187285667c 290 }
samdanbury 1:1f187285667c 291
samdanbury 1:1f187285667c 292 void attemptConnect() {
samdanbury 1:1f187285667c 293 int retryAttempt = 0;
samdanbury 1:1f187285667c 294 menuActivated = false;
samdanbury 1:1f187285667c 295
samdanbury 1:1f187285667c 296 //RGB: yellow
samdanbury 1:1f187285667c 297 r = 0;
samdanbury 1:1f187285667c 298 g = 0;
samdanbury 1:1f187285667c 299 b = 1;
samdanbury 1:1f187285667c 300
samdanbury 1:1f187285667c 301 lcd.cls();
samdanbury 1:1f187285667c 302 lcd.locate(0,0);
samdanbury 1:1f187285667c 303 lcd.printf("IBM IoT Cloud");
samdanbury 1:1f187285667c 304 lcd.locate(0,16);
samdanbury 1:1f187285667c 305 lcd.printf("Connecting");
samdanbury 1:1f187285667c 306
samdanbury 1:1f187285667c 307 while (!connected) {
samdanbury 1:1f187285667c 308
samdanbury 1:1f187285667c 309 int connTimeout = getConnTimeout(++retryAttempt);
samdanbury 1:1f187285667c 310
samdanbury 1:1f187285667c 311 connect();
samdanbury 1:1f187285667c 312
samdanbury 1:1f187285667c 313 if (!connected) {
samdanbury 1:1f187285667c 314 wait(connTimeout);
samdanbury 1:1f187285667c 315 } else {
samdanbury 1:1f187285667c 316 break;
samdanbury 1:1f187285667c 317 }
samdanbury 1:1f187285667c 318 }
samdanbury 1:1f187285667c 319 }
samdanbury 1:1f187285667c 320
samdanbury 1:1f187285667c 321 int getConnTimeout(int attemptNumber) {
samdanbury 1:1f187285667c 322 if (attemptNumber < 10) {
samdanbury 1:1f187285667c 323 return 3; //First 10 attempts try within 3 seconds
samdanbury 1:1f187285667c 324 } else if (attemptNumber < 20) {
samdanbury 1:1f187285667c 325 return 60; //Next 10 attempts retry after every 1 minute
samdanbury 1:1f187285667c 326 } else {
samdanbury 1:1f187285667c 327 return 600; //After 20 attempts, retry every 10 minutes
samdanbury 0:cae064bcbe5e 328 }
samdanbury 0:cae064bcbe5e 329 }
samdanbury 0:cae064bcbe5e 330
samdanbury 1:1f187285667c 331 void connect() {
samdanbury 1:1f187285667c 332 ipstack = MQTTSocket();
samdanbury 1:1f187285667c 333 client = new MQTT::Client<MQTTSocket, Countdown, 250>(ipstack);
samdanbury 1:1f187285667c 334
samdanbury 1:1f187285667c 335 //TCP Connect
samdanbury 1:1f187285667c 336 string ip = org + ".messaging.internetofthings.ibmcloud.com";
samdanbury 1:1f187285667c 337
samdanbury 1:1f187285667c 338 char* hostname = new char[ip.length() + 1];
samdanbury 1:1f187285667c 339 strcpy(hostname, ip.c_str());
samdanbury 1:1f187285667c 340
samdanbury 1:1f187285667c 341 int port = 1883;
samdanbury 1:1f187285667c 342 int rc = ipstack.connect(hostname, port);
samdanbury 1:1f187285667c 343 if (rc != 0) {
samdanbury 1:1f187285667c 344 lcd.printf("TCP connect failed");
samdanbury 1:1f187285667c 345 }
samdanbury 1:1f187285667c 346
samdanbury 1:1f187285667c 347 //Construct clientId based on config
samdanbury 1:1f187285667c 348 string str = string("d:") + org + ":" + type + ":" + id;
samdanbury 1:1f187285667c 349 char clientId[str.size()];
samdanbury 1:1f187285667c 350 memcpy(clientId, str.c_str(), str.size() + 1);
samdanbury 1:1f187285667c 351
samdanbury 1:1f187285667c 352 //MQTT Connect
samdanbury 1:1f187285667c 353 MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
samdanbury 1:1f187285667c 354 data.MQTTVersion = 3;
samdanbury 1:1f187285667c 355 data.clientID.cstring = clientId;
samdanbury 1:1f187285667c 356
samdanbury 1:1f187285667c 357 if (!quickstartMode) {
samdanbury 1:1f187285667c 358 char* password = new char[auth_token.length() + 1];
samdanbury 1:1f187285667c 359 strcpy(password, auth_token.c_str());
samdanbury 1:1f187285667c 360
samdanbury 1:1f187285667c 361 data.username.cstring = "use-token-auth";
samdanbury 1:1f187285667c 362 data.password.cstring = password;
samdanbury 1:1f187285667c 363 }
samdanbury 1:1f187285667c 364
samdanbury 1:1f187285667c 365 if ((rc = client->connect(&data)) != 0) {
samdanbury 1:1f187285667c 366 lcd.printf("rc from MQTT connect is %d\n", rc);
samdanbury 1:1f187285667c 367 } else {
samdanbury 1:1f187285667c 368 connected = true;
samdanbury 1:1f187285667c 369
samdanbury 1:1f187285667c 370 //RGB: green
samdanbury 1:1f187285667c 371 r = 1;
samdanbury 1:1f187285667c 372 g = 0;
samdanbury 1:1f187285667c 373 b = 1;
samdanbury 1:1f187285667c 374
samdanbury 1:1f187285667c 375 lcd.locate(0,0);
samdanbury 1:1f187285667c 376 lcd.printf("IBM IoT Cloud");
samdanbury 1:1f187285667c 377 lcd.locate(0,16);
samdanbury 1:1f187285667c 378 lcd.printf("Connected");
samdanbury 1:1f187285667c 379
samdanbury 1:1f187285667c 380 wait(2);
samdanbury 1:1f187285667c 381
samdanbury 1:1f187285667c 382 lcd.locate(0,0);
samdanbury 1:1f187285667c 383 lcd.printf("IBM IoT Cloud");
samdanbury 1:1f187285667c 384 lcd.locate(0,16);
samdanbury 1:1f187285667c 385 lcd.printf("Scroll with joystick");
samdanbury 1:1f187285667c 386
samdanbury 1:1f187285667c 387 menuActivated = true;
samdanbury 1:1f187285667c 388 }
samdanbury 1:1f187285667c 389 }
samdanbury 1:1f187285667c 390
samdanbury 1:1f187285667c 391 void subscribe() {
samdanbury 1:1f187285667c 392 char* subTopic = "iot-2/cmd/+/fmt/json";
samdanbury 1:1f187285667c 393 int rc = 0;
samdanbury 1:1f187285667c 394 if ((rc = client->subscribe(subTopic, MQTT::QOS1, messageArrived)) != 0)
samdanbury 1:1f187285667c 395 lcd.printf("rc from MQTT subscribe is %d\n", rc);
samdanbury 1:1f187285667c 396 }
samdanbury 1:1f187285667c 397
samdanbury 0:cae064bcbe5e 398 void messageArrived(MQTT::MessageData& md) {
samdanbury 0:cae064bcbe5e 399 MQTT::Message &message = md.message;
samdanbury 0:cae064bcbe5e 400
samdanbury 0:cae064bcbe5e 401 char* topic = new char[md.topicName.lenstring.len + 1];
samdanbury 0:cae064bcbe5e 402 sprintf(topic, "%.*s", md.topicName.lenstring.len, md.topicName.lenstring.data);
samdanbury 0:cae064bcbe5e 403
samdanbury 0:cae064bcbe5e 404 char* payload = new char[message.payloadlen + 1];
samdanbury 0:cae064bcbe5e 405 sprintf(payload, "%.*s", message.payloadlen, (char*)message.payload);
samdanbury 0:cae064bcbe5e 406
samdanbury 0:cae064bcbe5e 407 string topicStr = topic;
samdanbury 0:cae064bcbe5e 408 string payloadStr = payload;
samdanbury 0:cae064bcbe5e 409
samdanbury 0:cae064bcbe5e 410 //Command topic: iot-2/cmd/blink/fmt/json
samdanbury 0:cae064bcbe5e 411 string cmd = topicStr.substr(10, topicStr.find("/fmt/") - 10);
samdanbury 0:cae064bcbe5e 412
samdanbury 0:cae064bcbe5e 413 switch(getCommand(cmd)) {
samdanbury 0:cae064bcbe5e 414 case blink: {
samdanbury 0:cae064bcbe5e 415 string str = payloadStr.substr(8, payloadStr.find("}") - 8);
samdanbury 0:cae064bcbe5e 416 int rate = atoi(str.c_str());
samdanbury 0:cae064bcbe5e 417
samdanbury 0:cae064bcbe5e 418 if (rate == 0) {
samdanbury 0:cae064bcbe5e 419 interval = 0;
samdanbury 0:cae064bcbe5e 420 } else if (rate > 50) {
samdanbury 0:cae064bcbe5e 421 interval = 1;
samdanbury 0:cae064bcbe5e 422 } else if (rate > 0) {
samdanbury 0:cae064bcbe5e 423 interval = 50/rate;
samdanbury 0:cae064bcbe5e 424 }
samdanbury 0:cae064bcbe5e 425
samdanbury 0:cae064bcbe5e 426 break;
samdanbury 0:cae064bcbe5e 427 }
samdanbury 0:cae064bcbe5e 428 default:
samdanbury 0:cae064bcbe5e 429 lcd.printf("Unsupported command: %s\n", cmd);
samdanbury 0:cae064bcbe5e 430 }
samdanbury 0:cae064bcbe5e 431
samdanbury 0:cae064bcbe5e 432 if (topic) {
samdanbury 0:cae064bcbe5e 433 delete[] topic;
samdanbury 0:cae064bcbe5e 434 }
samdanbury 0:cae064bcbe5e 435 if (payload) {
samdanbury 0:cae064bcbe5e 436 delete[] payload;
samdanbury 0:cae064bcbe5e 437 }
samdanbury 0:cae064bcbe5e 438
samdanbury 0:cae064bcbe5e 439 }
samdanbury 0:cae064bcbe5e 440
samdanbury 0:cae064bcbe5e 441 command getCommand (string const& command) {
samdanbury 0:cae064bcbe5e 442 if (command == "blink")
samdanbury 0:cae064bcbe5e 443 return blink;
samdanbury 0:cae064bcbe5e 444 }
samdanbury 0:cae064bcbe5e 445
samdanbury 0:cae064bcbe5e 446 void joystickThread(void const *args) {
samdanbury 0:cae064bcbe5e 447 while (true) {
samdanbury 1:1f187285667c 448
samdanbury 1:1f187285667c 449 if (!menuActivated) {
samdanbury 1:1f187285667c 450 menu = 0;
samdanbury 1:1f187285667c 451 }
samdanbury 1:1f187285667c 452
samdanbury 1:1f187285667c 453 if (Down) {
samdanbury 0:cae064bcbe5e 454 joystickPos = "DOWN";
samdanbury 1:1f187285667c 455 if (menu >= 0 && menu < 3) {
samdanbury 1:1f187285667c 456 menu++;
samdanbury 1:1f187285667c 457 printMenu();
samdanbury 1:1f187285667c 458 }
samdanbury 1:1f187285667c 459 } else if (Left) {
samdanbury 0:cae064bcbe5e 460 joystickPos = "LEFT";
samdanbury 1:1f187285667c 461 } else if (Click) {
samdanbury 0:cae064bcbe5e 462 joystickPos = "CLICK";
samdanbury 1:1f187285667c 463 } else if (Up) {
samdanbury 0:cae064bcbe5e 464 joystickPos = "UP";
samdanbury 1:1f187285667c 465 if (menu <= 3 && menu > 0) {
samdanbury 1:1f187285667c 466 menu--;
samdanbury 1:1f187285667c 467 printMenu();
samdanbury 1:1f187285667c 468 }
samdanbury 1:1f187285667c 469 } else if (Right) {
samdanbury 0:cae064bcbe5e 470 joystickPos = "RIGHT";
samdanbury 1:1f187285667c 471 } else {
samdanbury 0:cae064bcbe5e 472 joystickPos = "CENTRE";
samdanbury 1:1f187285667c 473 }
samdanbury 1:1f187285667c 474 wait(0.2);
samdanbury 1:1f187285667c 475 }
samdanbury 1:1f187285667c 476 }
samdanbury 1:1f187285667c 477
samdanbury 1:1f187285667c 478 void printMenu() {
samdanbury 1:1f187285667c 479 if (menuActivated) {
samdanbury 1:1f187285667c 480 lcd.cls();
samdanbury 1:1f187285667c 481 lcd.locate(0,0);
samdanbury 1:1f187285667c 482
samdanbury 1:1f187285667c 483 switch(menu) {
samdanbury 1:1f187285667c 484 case 0:
samdanbury 1:1f187285667c 485 lcd.printf("IBM IoT Cloud");
samdanbury 1:1f187285667c 486 lcd.locate(0,16);
samdanbury 1:1f187285667c 487 lcd.printf("Scroll with joystick");
samdanbury 1:1f187285667c 488 break;
samdanbury 1:1f187285667c 489 case 1:
samdanbury 1:1f187285667c 490 lcd.printf("Go to:");
samdanbury 1:1f187285667c 491 lcd.locate(0,16);
samdanbury 1:1f187285667c 492 lcd.printf("http://ibm.biz/iotqstart");
samdanbury 1:1f187285667c 493 break;
samdanbury 1:1f187285667c 494 case 2:
samdanbury 1:1f187285667c 495 lcd.printf("Device Identity:");
samdanbury 1:1f187285667c 496 lcd.locate(0,16);
samdanbury 1:1f187285667c 497 lcd.printf("%s", mac);
samdanbury 1:1f187285667c 498 break;
samdanbury 1:1f187285667c 499 case 3:
samdanbury 1:1f187285667c 500 lcd.printf("Status:");
samdanbury 1:1f187285667c 501 lcd.locate(0,16);
samdanbury 1:1f187285667c 502 lcd.printf("Connected");
samdanbury 1:1f187285667c 503 break;
samdanbury 1:1f187285667c 504 }
samdanbury 1:1f187285667c 505 } else {
samdanbury 1:1f187285667c 506 menu = 0;
samdanbury 0:cae064bcbe5e 507 }
samdanbury 0:cae064bcbe5e 508 }
samdanbury 0:cae064bcbe5e 509
samdanbury 0:cae064bcbe5e 510 string getUUID48 () {
samdanbury 0:cae064bcbe5e 511
samdanbury 0:cae064bcbe5e 512 unsigned int UUID_LOC_WORD0 = 0x40048060;
samdanbury 0:cae064bcbe5e 513 unsigned int UUID_LOC_WORD1 = 0x4004805C;
samdanbury 0:cae064bcbe5e 514
samdanbury 0:cae064bcbe5e 515 // Fetch word 0
samdanbury 0:cae064bcbe5e 516 uint32_t Word0 = *(uint32_t *)UUID_LOC_WORD0;
samdanbury 0:cae064bcbe5e 517
samdanbury 0:cae064bcbe5e 518 // Fetch word 1
samdanbury 0:cae064bcbe5e 519 // we only want bottom 16 bits of word1 (MAC bits 32-47)
samdanbury 0:cae064bcbe5e 520 // and bit 9 forced to 1, bit 8 forced to 0
samdanbury 0:cae064bcbe5e 521 // Locally administered MAC, reduced conflicts
samdanbury 0:cae064bcbe5e 522 // http://en.wikipedia.org/wiki/MAC_address
samdanbury 0:cae064bcbe5e 523 uint32_t Word1 = *(uint32_t *)UUID_LOC_WORD1;
samdanbury 0:cae064bcbe5e 524 Word1 |= 0x00000200;
samdanbury 0:cae064bcbe5e 525 Word1 &= 0x0000FEFF;
samdanbury 0:cae064bcbe5e 526
samdanbury 0:cae064bcbe5e 527 string sd;
samdanbury 0:cae064bcbe5e 528 char stemp[100] = "";
samdanbury 0:cae064bcbe5e 529 snprintf(stemp, 100, "%4X%08X", Word1,Word0); // I use the safer version of sprintf() -- snprintf()
samdanbury 0:cae064bcbe5e 530 sd = stemp; // the contents of sd are now "This is a string!"
samdanbury 0:cae064bcbe5e 531
samdanbury 0:cae064bcbe5e 532 return (sd);
samdanbury 0:cae064bcbe5e 533 }