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