Contains example code to connect the mbed LPC1768 or FRDM-K64F devices to the IBM Internet of Things Cloud service via ethernet.

Dependencies:   C12832 MQTT LM75B MMA7660

Dependents:   MFT_IoT_demo_USB400 IBM_RFID

Committer:
samdanbury
Date:
Fri Jul 18 09:27:32 2014 +0000
Revision:
2:d8fddda78c38
Parent:
1:1f187285667c
Child:
3:69ef39823eef
Delete MQTTEthernetIoT class that is no longer required, change device type of K64F when running in QuickStart mode

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 2:d8fddda78c38 19 #include "EthernetInterface.h"
samdanbury 2:d8fddda78c38 20 #include "MQTTSocket.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 2:d8fddda78c38 166 #ifdef TARGET_K64F
samdanbury 2:d8fddda78c38 167 type = "iotsample-mbed-k64f";
samdanbury 2:d8fddda78c38 168 #else
samdanbury 2:d8fddda78c38 169 type = "iotsample-mbed-lpc1768";
samdanbury 2:d8fddda78c38 170 #endif
samdanbury 0:cae064bcbe5e 171 id = mac;
samdanbury 0:cae064bcbe5e 172 }
samdanbury 0:cae064bcbe5e 173
samdanbury 0:cae064bcbe5e 174 #ifdef TARGET_K64F
samdanbury 0:cae064bcbe5e 175 #ifdef ORGANISATION
samdanbury 0:cae064bcbe5e 176 quickstartMode = false;
samdanbury 0:cae064bcbe5e 177 org = ORGANISATION;
samdanbury 0:cae064bcbe5e 178
samdanbury 0:cae064bcbe5e 179 #ifdef TYPE
samdanbury 0:cae064bcbe5e 180 type = TYPE;
samdanbury 0:cae064bcbe5e 181 #else
samdanbury 0:cae064bcbe5e 182 lcd.printf("Type is not defined");
samdanbury 0:cae064bcbe5e 183 #endif
samdanbury 0:cae064bcbe5e 184
samdanbury 0:cae064bcbe5e 185 #ifdef ID
samdanbury 0:cae064bcbe5e 186 id = ID;
samdanbury 0:cae064bcbe5e 187 #else
samdanbury 0:cae064bcbe5e 188 lcd.printf("ID is not defined");
samdanbury 0:cae064bcbe5e 189 #endif
samdanbury 0:cae064bcbe5e 190
samdanbury 0:cae064bcbe5e 191 #ifdef AUTHMETHOD
samdanbury 0:cae064bcbe5e 192 auth_method = AUTHMETHOD;
samdanbury 0:cae064bcbe5e 193 #else
samdanbury 0:cae064bcbe5e 194 lcd.printf("Auth method is not defined");
samdanbury 0:cae064bcbe5e 195 #endif
samdanbury 0:cae064bcbe5e 196
samdanbury 0:cae064bcbe5e 197 #ifdef AUTHTOKEN
samdanbury 0:cae064bcbe5e 198 auth_token = AUTHTOKEN;
samdanbury 0:cae064bcbe5e 199 #else
samdanbury 0:cae064bcbe5e 200 lcd.printf("Auth token is not defined");
samdanbury 0:cae064bcbe5e 201 #endif
samdanbury 0:cae064bcbe5e 202 #endif
samdanbury 0:cae064bcbe5e 203 #endif
samdanbury 0:cae064bcbe5e 204 }
samdanbury 0:cae064bcbe5e 205
samdanbury 0:cae064bcbe5e 206 int main()
samdanbury 0:cae064bcbe5e 207 {
samdanbury 1:1f187285667c 208 //RGB: yellow
samdanbury 1:1f187285667c 209 r = 0;
samdanbury 1:1f187285667c 210 g = 0;
samdanbury 1:1f187285667c 211 b = 1;
samdanbury 1:1f187285667c 212
samdanbury 1:1f187285667c 213 lcd.cls();
samdanbury 1:1f187285667c 214 lcd.set_font((unsigned char*) Arial12x12);
samdanbury 1:1f187285667c 215 lcd.locate(0,0);
samdanbury 1:1f187285667c 216 lcd.printf("IBM IoT Cloud");
samdanbury 1:1f187285667c 217 lcd.locate(0,16);
samdanbury 1:1f187285667c 218 lcd.printf("Connecting");
samdanbury 0:cae064bcbe5e 219
samdanbury 0:cae064bcbe5e 220 //Connect to network
samdanbury 1:1f187285667c 221 EthernetInterface eth;
samdanbury 1:1f187285667c 222 eth.init();
samdanbury 1:1f187285667c 223 eth.connect();
samdanbury 0:cae064bcbe5e 224
samdanbury 0:cae064bcbe5e 225 //Obtain mac address of mbed
samdanbury 0:cae064bcbe5e 226 #ifdef TARGET_K64F
samdanbury 0:cae064bcbe5e 227 mac = getUUID48();
samdanbury 0:cae064bcbe5e 228 #else
samdanbury 1:1f187285667c 229 mac = eth.getMACAddress();
samdanbury 0:cae064bcbe5e 230
samdanbury 0:cae064bcbe5e 231 //Remove colons from mac address
samdanbury 0:cae064bcbe5e 232 mac.erase(remove(mac.begin(), mac.end(), ':'), mac.end());
samdanbury 0:cae064bcbe5e 233 #endif
samdanbury 0:cae064bcbe5e 234
samdanbury 0:cae064bcbe5e 235 //Parse config file if present
samdanbury 0:cae064bcbe5e 236 parseConfig();
samdanbury 0:cae064bcbe5e 237
samdanbury 1:1f187285667c 238 attemptConnect();
samdanbury 0:cae064bcbe5e 239
samdanbury 0:cae064bcbe5e 240 if (!quickstartMode) {
samdanbury 1:1f187285667c 241 subscribe();
samdanbury 0:cae064bcbe5e 242 }
samdanbury 0:cae064bcbe5e 243
samdanbury 0:cae064bcbe5e 244 //Start thread to read data from joystick
samdanbury 0:cae064bcbe5e 245 joystickPos = "CENTRE";
samdanbury 0:cae064bcbe5e 246 Thread jThd(joystickThread);
samdanbury 0:cae064bcbe5e 247
samdanbury 0:cae064bcbe5e 248 interval = 0;
samdanbury 0:cae064bcbe5e 249 int i = 0;
samdanbury 0:cae064bcbe5e 250
samdanbury 0:cae064bcbe5e 251 while(1)
samdanbury 0:cae064bcbe5e 252 {
samdanbury 0:cae064bcbe5e 253 //Message published every second
samdanbury 0:cae064bcbe5e 254 if (i == 100) {
samdanbury 0:cae064bcbe5e 255 //MQTT Publish
samdanbury 0:cae064bcbe5e 256 MQTT::Message message;
samdanbury 0:cae064bcbe5e 257 char* pubTopic = "iot-2/evt/status/fmt/json";
samdanbury 0:cae064bcbe5e 258
samdanbury 0:cae064bcbe5e 259 char buf[250];
samdanbury 0:cae064bcbe5e 260 sprintf(buf,
samdanbury 0:cae064bcbe5e 261 "{\"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 262 MMA.x(), MMA.y(), MMA.z(),
samdanbury 0:cae064bcbe5e 263 sensor.temp(),
samdanbury 0:cae064bcbe5e 264 joystickPos,
samdanbury 0:cae064bcbe5e 265 ain1.read(),
samdanbury 0:cae064bcbe5e 266 ain2.read());
samdanbury 0:cae064bcbe5e 267 message.qos = MQTT::QOS0;
samdanbury 0:cae064bcbe5e 268 message.retained = false;
samdanbury 0:cae064bcbe5e 269 message.dup = false;
samdanbury 0:cae064bcbe5e 270 message.payload = (void*)buf;
samdanbury 0:cae064bcbe5e 271 message.payloadlen = strlen(buf);
samdanbury 0:cae064bcbe5e 272
samdanbury 1:1f187285667c 273 int rc = 0;
samdanbury 1:1f187285667c 274 if ((rc = client->publish(pubTopic, &message)) != 0) {
samdanbury 1:1f187285667c 275 connected = false;
samdanbury 1:1f187285667c 276 attemptConnect();
samdanbury 1:1f187285667c 277 }
samdanbury 0:cae064bcbe5e 278
samdanbury 0:cae064bcbe5e 279 i = 0;
samdanbury 0:cae064bcbe5e 280 }
samdanbury 0:cae064bcbe5e 281
samdanbury 0:cae064bcbe5e 282 if (interval == 0) {
samdanbury 1:1f187285667c 283 //led2 = 0;
samdanbury 0:cae064bcbe5e 284 } else {
samdanbury 0:cae064bcbe5e 285 if (i%(interval)==0) {
samdanbury 1:1f187285667c 286 //led2 = !led2;
samdanbury 0:cae064bcbe5e 287 }
samdanbury 0:cae064bcbe5e 288 }
samdanbury 0:cae064bcbe5e 289
samdanbury 0:cae064bcbe5e 290 wait(0.01);
samdanbury 0:cae064bcbe5e 291 i++;
samdanbury 1:1f187285667c 292 client->yield(1);
samdanbury 1:1f187285667c 293 }
samdanbury 1:1f187285667c 294 }
samdanbury 1:1f187285667c 295
samdanbury 1:1f187285667c 296 void attemptConnect() {
samdanbury 1:1f187285667c 297 int retryAttempt = 0;
samdanbury 1:1f187285667c 298 menuActivated = false;
samdanbury 1:1f187285667c 299
samdanbury 1:1f187285667c 300 //RGB: yellow
samdanbury 1:1f187285667c 301 r = 0;
samdanbury 1:1f187285667c 302 g = 0;
samdanbury 1:1f187285667c 303 b = 1;
samdanbury 1:1f187285667c 304
samdanbury 1:1f187285667c 305 lcd.cls();
samdanbury 1:1f187285667c 306 lcd.locate(0,0);
samdanbury 1:1f187285667c 307 lcd.printf("IBM IoT Cloud");
samdanbury 1:1f187285667c 308 lcd.locate(0,16);
samdanbury 1:1f187285667c 309 lcd.printf("Connecting");
samdanbury 1:1f187285667c 310
samdanbury 1:1f187285667c 311 while (!connected) {
samdanbury 1:1f187285667c 312
samdanbury 1:1f187285667c 313 int connTimeout = getConnTimeout(++retryAttempt);
samdanbury 1:1f187285667c 314
samdanbury 1:1f187285667c 315 connect();
samdanbury 1:1f187285667c 316
samdanbury 1:1f187285667c 317 if (!connected) {
samdanbury 1:1f187285667c 318 wait(connTimeout);
samdanbury 1:1f187285667c 319 } else {
samdanbury 1:1f187285667c 320 break;
samdanbury 1:1f187285667c 321 }
samdanbury 1:1f187285667c 322 }
samdanbury 1:1f187285667c 323 }
samdanbury 1:1f187285667c 324
samdanbury 1:1f187285667c 325 int getConnTimeout(int attemptNumber) {
samdanbury 1:1f187285667c 326 if (attemptNumber < 10) {
samdanbury 1:1f187285667c 327 return 3; //First 10 attempts try within 3 seconds
samdanbury 1:1f187285667c 328 } else if (attemptNumber < 20) {
samdanbury 1:1f187285667c 329 return 60; //Next 10 attempts retry after every 1 minute
samdanbury 1:1f187285667c 330 } else {
samdanbury 1:1f187285667c 331 return 600; //After 20 attempts, retry every 10 minutes
samdanbury 0:cae064bcbe5e 332 }
samdanbury 0:cae064bcbe5e 333 }
samdanbury 0:cae064bcbe5e 334
samdanbury 1:1f187285667c 335 void connect() {
samdanbury 1:1f187285667c 336 ipstack = MQTTSocket();
samdanbury 1:1f187285667c 337 client = new MQTT::Client<MQTTSocket, Countdown, 250>(ipstack);
samdanbury 1:1f187285667c 338
samdanbury 1:1f187285667c 339 //TCP Connect
samdanbury 1:1f187285667c 340 string ip = org + ".messaging.internetofthings.ibmcloud.com";
samdanbury 1:1f187285667c 341
samdanbury 1:1f187285667c 342 char* hostname = new char[ip.length() + 1];
samdanbury 1:1f187285667c 343 strcpy(hostname, ip.c_str());
samdanbury 1:1f187285667c 344
samdanbury 1:1f187285667c 345 int port = 1883;
samdanbury 1:1f187285667c 346 int rc = ipstack.connect(hostname, port);
samdanbury 1:1f187285667c 347 if (rc != 0) {
samdanbury 1:1f187285667c 348 lcd.printf("TCP connect failed");
samdanbury 1:1f187285667c 349 }
samdanbury 1:1f187285667c 350
samdanbury 1:1f187285667c 351 //Construct clientId based on config
samdanbury 1:1f187285667c 352 string str = string("d:") + org + ":" + type + ":" + id;
samdanbury 1:1f187285667c 353 char clientId[str.size()];
samdanbury 1:1f187285667c 354 memcpy(clientId, str.c_str(), str.size() + 1);
samdanbury 1:1f187285667c 355
samdanbury 1:1f187285667c 356 //MQTT Connect
samdanbury 1:1f187285667c 357 MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
samdanbury 1:1f187285667c 358 data.MQTTVersion = 3;
samdanbury 1:1f187285667c 359 data.clientID.cstring = clientId;
samdanbury 1:1f187285667c 360
samdanbury 1:1f187285667c 361 if (!quickstartMode) {
samdanbury 1:1f187285667c 362 char* password = new char[auth_token.length() + 1];
samdanbury 1:1f187285667c 363 strcpy(password, auth_token.c_str());
samdanbury 1:1f187285667c 364
samdanbury 1:1f187285667c 365 data.username.cstring = "use-token-auth";
samdanbury 1:1f187285667c 366 data.password.cstring = password;
samdanbury 1:1f187285667c 367 }
samdanbury 1:1f187285667c 368
samdanbury 1:1f187285667c 369 if ((rc = client->connect(&data)) != 0) {
samdanbury 1:1f187285667c 370 lcd.printf("rc from MQTT connect is %d\n", rc);
samdanbury 1:1f187285667c 371 } else {
samdanbury 1:1f187285667c 372 connected = true;
samdanbury 1:1f187285667c 373
samdanbury 1:1f187285667c 374 //RGB: green
samdanbury 1:1f187285667c 375 r = 1;
samdanbury 1:1f187285667c 376 g = 0;
samdanbury 1:1f187285667c 377 b = 1;
samdanbury 1:1f187285667c 378
samdanbury 1:1f187285667c 379 lcd.locate(0,0);
samdanbury 1:1f187285667c 380 lcd.printf("IBM IoT Cloud");
samdanbury 1:1f187285667c 381 lcd.locate(0,16);
samdanbury 1:1f187285667c 382 lcd.printf("Connected");
samdanbury 1:1f187285667c 383
samdanbury 1:1f187285667c 384 wait(2);
samdanbury 1:1f187285667c 385
samdanbury 1:1f187285667c 386 lcd.locate(0,0);
samdanbury 1:1f187285667c 387 lcd.printf("IBM IoT Cloud");
samdanbury 1:1f187285667c 388 lcd.locate(0,16);
samdanbury 1:1f187285667c 389 lcd.printf("Scroll with joystick");
samdanbury 1:1f187285667c 390
samdanbury 1:1f187285667c 391 menuActivated = true;
samdanbury 1:1f187285667c 392 }
samdanbury 1:1f187285667c 393 }
samdanbury 1:1f187285667c 394
samdanbury 1:1f187285667c 395 void subscribe() {
samdanbury 1:1f187285667c 396 char* subTopic = "iot-2/cmd/+/fmt/json";
samdanbury 1:1f187285667c 397 int rc = 0;
samdanbury 1:1f187285667c 398 if ((rc = client->subscribe(subTopic, MQTT::QOS1, messageArrived)) != 0)
samdanbury 1:1f187285667c 399 lcd.printf("rc from MQTT subscribe is %d\n", rc);
samdanbury 1:1f187285667c 400 }
samdanbury 1:1f187285667c 401
samdanbury 0:cae064bcbe5e 402 void messageArrived(MQTT::MessageData& md) {
samdanbury 0:cae064bcbe5e 403 MQTT::Message &message = md.message;
samdanbury 0:cae064bcbe5e 404
samdanbury 0:cae064bcbe5e 405 char* topic = new char[md.topicName.lenstring.len + 1];
samdanbury 0:cae064bcbe5e 406 sprintf(topic, "%.*s", md.topicName.lenstring.len, md.topicName.lenstring.data);
samdanbury 0:cae064bcbe5e 407
samdanbury 0:cae064bcbe5e 408 char* payload = new char[message.payloadlen + 1];
samdanbury 0:cae064bcbe5e 409 sprintf(payload, "%.*s", message.payloadlen, (char*)message.payload);
samdanbury 0:cae064bcbe5e 410
samdanbury 0:cae064bcbe5e 411 string topicStr = topic;
samdanbury 0:cae064bcbe5e 412 string payloadStr = payload;
samdanbury 0:cae064bcbe5e 413
samdanbury 0:cae064bcbe5e 414 //Command topic: iot-2/cmd/blink/fmt/json
samdanbury 0:cae064bcbe5e 415 string cmd = topicStr.substr(10, topicStr.find("/fmt/") - 10);
samdanbury 0:cae064bcbe5e 416
samdanbury 0:cae064bcbe5e 417 switch(getCommand(cmd)) {
samdanbury 0:cae064bcbe5e 418 case blink: {
samdanbury 0:cae064bcbe5e 419 string str = payloadStr.substr(8, payloadStr.find("}") - 8);
samdanbury 0:cae064bcbe5e 420 int rate = atoi(str.c_str());
samdanbury 0:cae064bcbe5e 421
samdanbury 0:cae064bcbe5e 422 if (rate == 0) {
samdanbury 0:cae064bcbe5e 423 interval = 0;
samdanbury 0:cae064bcbe5e 424 } else if (rate > 50) {
samdanbury 0:cae064bcbe5e 425 interval = 1;
samdanbury 0:cae064bcbe5e 426 } else if (rate > 0) {
samdanbury 0:cae064bcbe5e 427 interval = 50/rate;
samdanbury 0:cae064bcbe5e 428 }
samdanbury 0:cae064bcbe5e 429
samdanbury 0:cae064bcbe5e 430 break;
samdanbury 0:cae064bcbe5e 431 }
samdanbury 0:cae064bcbe5e 432 default:
samdanbury 0:cae064bcbe5e 433 lcd.printf("Unsupported command: %s\n", cmd);
samdanbury 0:cae064bcbe5e 434 }
samdanbury 0:cae064bcbe5e 435
samdanbury 0:cae064bcbe5e 436 if (topic) {
samdanbury 0:cae064bcbe5e 437 delete[] topic;
samdanbury 0:cae064bcbe5e 438 }
samdanbury 0:cae064bcbe5e 439 if (payload) {
samdanbury 0:cae064bcbe5e 440 delete[] payload;
samdanbury 0:cae064bcbe5e 441 }
samdanbury 0:cae064bcbe5e 442
samdanbury 0:cae064bcbe5e 443 }
samdanbury 0:cae064bcbe5e 444
samdanbury 0:cae064bcbe5e 445 command getCommand (string const& command) {
samdanbury 0:cae064bcbe5e 446 if (command == "blink")
samdanbury 0:cae064bcbe5e 447 return blink;
samdanbury 0:cae064bcbe5e 448 }
samdanbury 0:cae064bcbe5e 449
samdanbury 0:cae064bcbe5e 450 void joystickThread(void const *args) {
samdanbury 0:cae064bcbe5e 451 while (true) {
samdanbury 1:1f187285667c 452
samdanbury 1:1f187285667c 453 if (!menuActivated) {
samdanbury 1:1f187285667c 454 menu = 0;
samdanbury 1:1f187285667c 455 }
samdanbury 1:1f187285667c 456
samdanbury 1:1f187285667c 457 if (Down) {
samdanbury 0:cae064bcbe5e 458 joystickPos = "DOWN";
samdanbury 1:1f187285667c 459 if (menu >= 0 && menu < 3) {
samdanbury 1:1f187285667c 460 menu++;
samdanbury 1:1f187285667c 461 printMenu();
samdanbury 1:1f187285667c 462 }
samdanbury 1:1f187285667c 463 } else if (Left) {
samdanbury 0:cae064bcbe5e 464 joystickPos = "LEFT";
samdanbury 1:1f187285667c 465 } else if (Click) {
samdanbury 0:cae064bcbe5e 466 joystickPos = "CLICK";
samdanbury 1:1f187285667c 467 } else if (Up) {
samdanbury 0:cae064bcbe5e 468 joystickPos = "UP";
samdanbury 1:1f187285667c 469 if (menu <= 3 && menu > 0) {
samdanbury 1:1f187285667c 470 menu--;
samdanbury 1:1f187285667c 471 printMenu();
samdanbury 1:1f187285667c 472 }
samdanbury 1:1f187285667c 473 } else if (Right) {
samdanbury 0:cae064bcbe5e 474 joystickPos = "RIGHT";
samdanbury 1:1f187285667c 475 } else {
samdanbury 0:cae064bcbe5e 476 joystickPos = "CENTRE";
samdanbury 1:1f187285667c 477 }
samdanbury 1:1f187285667c 478 wait(0.2);
samdanbury 1:1f187285667c 479 }
samdanbury 1:1f187285667c 480 }
samdanbury 1:1f187285667c 481
samdanbury 1:1f187285667c 482 void printMenu() {
samdanbury 1:1f187285667c 483 if (menuActivated) {
samdanbury 1:1f187285667c 484 lcd.cls();
samdanbury 1:1f187285667c 485 lcd.locate(0,0);
samdanbury 1:1f187285667c 486
samdanbury 1:1f187285667c 487 switch(menu) {
samdanbury 1:1f187285667c 488 case 0:
samdanbury 1:1f187285667c 489 lcd.printf("IBM IoT Cloud");
samdanbury 1:1f187285667c 490 lcd.locate(0,16);
samdanbury 1:1f187285667c 491 lcd.printf("Scroll with joystick");
samdanbury 1:1f187285667c 492 break;
samdanbury 1:1f187285667c 493 case 1:
samdanbury 1:1f187285667c 494 lcd.printf("Go to:");
samdanbury 1:1f187285667c 495 lcd.locate(0,16);
samdanbury 1:1f187285667c 496 lcd.printf("http://ibm.biz/iotqstart");
samdanbury 1:1f187285667c 497 break;
samdanbury 1:1f187285667c 498 case 2:
samdanbury 1:1f187285667c 499 lcd.printf("Device Identity:");
samdanbury 1:1f187285667c 500 lcd.locate(0,16);
samdanbury 1:1f187285667c 501 lcd.printf("%s", mac);
samdanbury 1:1f187285667c 502 break;
samdanbury 1:1f187285667c 503 case 3:
samdanbury 1:1f187285667c 504 lcd.printf("Status:");
samdanbury 1:1f187285667c 505 lcd.locate(0,16);
samdanbury 1:1f187285667c 506 lcd.printf("Connected");
samdanbury 1:1f187285667c 507 break;
samdanbury 1:1f187285667c 508 }
samdanbury 1:1f187285667c 509 } else {
samdanbury 1:1f187285667c 510 menu = 0;
samdanbury 0:cae064bcbe5e 511 }
samdanbury 0:cae064bcbe5e 512 }
samdanbury 0:cae064bcbe5e 513
samdanbury 0:cae064bcbe5e 514 string getUUID48 () {
samdanbury 0:cae064bcbe5e 515
samdanbury 0:cae064bcbe5e 516 unsigned int UUID_LOC_WORD0 = 0x40048060;
samdanbury 0:cae064bcbe5e 517 unsigned int UUID_LOC_WORD1 = 0x4004805C;
samdanbury 0:cae064bcbe5e 518
samdanbury 0:cae064bcbe5e 519 // Fetch word 0
samdanbury 0:cae064bcbe5e 520 uint32_t Word0 = *(uint32_t *)UUID_LOC_WORD0;
samdanbury 0:cae064bcbe5e 521
samdanbury 0:cae064bcbe5e 522 // Fetch word 1
samdanbury 0:cae064bcbe5e 523 // we only want bottom 16 bits of word1 (MAC bits 32-47)
samdanbury 0:cae064bcbe5e 524 // and bit 9 forced to 1, bit 8 forced to 0
samdanbury 0:cae064bcbe5e 525 // Locally administered MAC, reduced conflicts
samdanbury 0:cae064bcbe5e 526 // http://en.wikipedia.org/wiki/MAC_address
samdanbury 0:cae064bcbe5e 527 uint32_t Word1 = *(uint32_t *)UUID_LOC_WORD1;
samdanbury 0:cae064bcbe5e 528 Word1 |= 0x00000200;
samdanbury 0:cae064bcbe5e 529 Word1 &= 0x0000FEFF;
samdanbury 0:cae064bcbe5e 530
samdanbury 0:cae064bcbe5e 531 string sd;
samdanbury 0:cae064bcbe5e 532 char stemp[100] = "";
samdanbury 0:cae064bcbe5e 533 snprintf(stemp, 100, "%4X%08X", Word1,Word0); // I use the safer version of sprintf() -- snprintf()
samdanbury 0:cae064bcbe5e 534 sd = stemp; // the contents of sd are now "This is a string!"
samdanbury 0:cae064bcbe5e 535
samdanbury 0:cae064bcbe5e 536 return (sd);
samdanbury 0:cae064bcbe5e 537 }