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