Dependencies:   C12832 EthernetInterface LM75B MMA7660 MQTT mbed-rtos mbed

Fork of IoTClientEthernet by Zhengguo Sheng

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 }