![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
IoT based security system that detects suspicious movements through a motion detector and alerts the user on their gmail. In the presence of motion sensed between 7 to 9 times, the Grove PIR sensor sends an input to the board which is connected to internet via Ethernet. The board publishes the sensor data on IBM IoT foundation, which is known as IBM Watson. The data is then sent to IBM Bluemix which provides real time analysis and the remote time data management and monitoring. For more information : https://developer.ibm.com/recipes/tutorials/mbed-c-client-library-for-ibm-iot-foundation/
Dependencies: C12832 EthernetInterface LM75B MMA7660 MQTT mbed-rtos mbed
Fork of IBMIoTClientEthernetExample by
main.cpp@12:8b480eb8a496, 2015-07-09 (annotated)
- Committer:
- chris
- Date:
- Thu Jul 09 14:35:57 2015 +0000
- Revision:
- 12:8b480eb8a496
- Parent:
- 11:7a6df9a2dcdc
- Child:
- 13:85801e3b83d3
Updated mbed-RTOS, Ethernet Interface and mbed library. Updates main.cpp to add threaded LED control and removed conditional compilation
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
samdanbury | 6:37b6d0d56190 | 1 | /******************************************************************************* |
samdanbury | 6:37b6d0d56190 | 2 | * Copyright (c) 2014 IBM Corp. |
samdanbury | 6:37b6d0d56190 | 3 | * |
samdanbury | 6:37b6d0d56190 | 4 | * All rights reserved. This program and the accompanying materials |
samdanbury | 6:37b6d0d56190 | 5 | * are made available under the terms of the Eclipse Public License v1.0 |
samdanbury | 6:37b6d0d56190 | 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. |
samdanbury | 6:37b6d0d56190 | 7 | * |
samdanbury | 6:37b6d0d56190 | 8 | * The Eclipse Public License is available at |
samdanbury | 6:37b6d0d56190 | 9 | * http://www.eclipse.org/legal/epl-v10.html |
samdanbury | 6:37b6d0d56190 | 10 | * and the Eclipse Distribution License is available at |
samdanbury | 6:37b6d0d56190 | 11 | * http://www.eclipse.org/org/documents/edl-v10.php. |
samdanbury | 6:37b6d0d56190 | 12 | * |
samdanbury | 6:37b6d0d56190 | 13 | * Contributors: |
samdanbury | 6:37b6d0d56190 | 14 | * Sam Danbury - initial implementation |
samdanbury | 6:37b6d0d56190 | 15 | * Ian Craggs - refactoring to remove STL and other changes |
icraggs | 8:80d49dd91542 | 16 | * Sam Grove - added check for Ethernet cable. |
chris | 10:0b5e0dfee08e | 17 | * Chris Styles - Added additional menu screen for software revision |
chris | 10:0b5e0dfee08e | 18 | * |
chris | 10:0b5e0dfee08e | 19 | * To do : |
chris | 10:0b5e0dfee08e | 20 | * Add magnetometer sensor output to IoT data stream |
chris | 10:0b5e0dfee08e | 21 | * |
samdanbury | 6:37b6d0d56190 | 22 | *******************************************************************************/ |
samdanbury | 6:37b6d0d56190 | 23 | |
samdanbury | 6:37b6d0d56190 | 24 | #include "LM75B.h" |
samdanbury | 6:37b6d0d56190 | 25 | #include "MMA7660.h" |
samdanbury | 6:37b6d0d56190 | 26 | #include "MQTTClient.h" |
samdanbury | 6:37b6d0d56190 | 27 | #include "MQTTEthernet.h" |
samdanbury | 6:37b6d0d56190 | 28 | #include "C12832.h" |
samdanbury | 6:37b6d0d56190 | 29 | #include "Arial12x12.h" |
samdanbury | 6:37b6d0d56190 | 30 | #include "rtos.h" |
samdanbury | 6:37b6d0d56190 | 31 | |
chris | 10:0b5e0dfee08e | 32 | // Update this to the next number *before* a commit |
chris | 12:8b480eb8a496 | 33 | #define __APP_SW_REVISION__ "11" |
chris | 10:0b5e0dfee08e | 34 | |
samdanbury | 6:37b6d0d56190 | 35 | // Configuration values needed to connect to IBM IoT Cloud |
icraggs | 8:80d49dd91542 | 36 | #define ORG "quickstart" // For a registered connection, replace with your org |
icraggs | 8:80d49dd91542 | 37 | #define ID "" // For a registered connection, replace with your id |
icraggs | 8:80d49dd91542 | 38 | #define AUTH_TOKEN "" // For a registered connection, replace with your auth-token |
icraggs | 8:80d49dd91542 | 39 | #define TYPE DEFAULT_TYPE_NAME // For a registered connection, replace with your type |
samdanbury | 6:37b6d0d56190 | 40 | |
samdanbury | 6:37b6d0d56190 | 41 | #define MQTT_PORT 1883 |
samdanbury | 6:37b6d0d56190 | 42 | #define MQTT_TLS_PORT 8883 |
samdanbury | 6:37b6d0d56190 | 43 | #define IBM_IOT_PORT MQTT_PORT |
samdanbury | 6:37b6d0d56190 | 44 | |
samdanbury | 6:37b6d0d56190 | 45 | #define MQTT_MAX_PACKET_SIZE 250 |
samdanbury | 6:37b6d0d56190 | 46 | |
mazgch | 11:7a6df9a2dcdc | 47 | #if defined(TARGET_UBLOX_C027) |
mazgch | 11:7a6df9a2dcdc | 48 | #warning "Compiling for mbed C027" |
mazgch | 11:7a6df9a2dcdc | 49 | #include "C027.h" |
mazgch | 11:7a6df9a2dcdc | 50 | #elif defined(TARGET_LPC1768) |
samdanbury | 6:37b6d0d56190 | 51 | #warning "Compiling for mbed LPC1768" |
samdanbury | 6:37b6d0d56190 | 52 | #include "LPC1768.h" |
samdanbury | 6:37b6d0d56190 | 53 | #elif defined(TARGET_K64F) |
samdanbury | 6:37b6d0d56190 | 54 | #warning "Compiling for mbed K64F" |
samdanbury | 6:37b6d0d56190 | 55 | #include "K64F.h" |
samdanbury | 6:37b6d0d56190 | 56 | #endif |
samdanbury | 6:37b6d0d56190 | 57 | |
icraggs | 8:80d49dd91542 | 58 | bool quickstartMode = true; |
samdanbury | 6:37b6d0d56190 | 59 | char org[11] = ORG; |
samdanbury | 6:37b6d0d56190 | 60 | char type[30] = TYPE; |
samdanbury | 6:37b6d0d56190 | 61 | char id[30] = ID; // mac without colons |
samdanbury | 6:37b6d0d56190 | 62 | char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode |
samdanbury | 6:37b6d0d56190 | 63 | |
samdanbury | 6:37b6d0d56190 | 64 | bool connected = false; |
samdanbury | 6:37b6d0d56190 | 65 | char* joystickPos = "CENTRE"; |
samdanbury | 6:37b6d0d56190 | 66 | int blink_interval = 0; |
samdanbury | 6:37b6d0d56190 | 67 | |
samdanbury | 6:37b6d0d56190 | 68 | |
samdanbury | 6:37b6d0d56190 | 69 | void off() |
samdanbury | 6:37b6d0d56190 | 70 | { |
samdanbury | 6:37b6d0d56190 | 71 | r = g = b = 1.0; // 1 is off, 0 is full brightness |
samdanbury | 6:37b6d0d56190 | 72 | } |
samdanbury | 6:37b6d0d56190 | 73 | |
samdanbury | 6:37b6d0d56190 | 74 | void red() |
samdanbury | 6:37b6d0d56190 | 75 | { |
samdanbury | 6:37b6d0d56190 | 76 | r = 0.7; g = 1.0; b = 1.0; // 1 is off, 0 is full brightness |
samdanbury | 6:37b6d0d56190 | 77 | } |
samdanbury | 6:37b6d0d56190 | 78 | |
samdanbury | 6:37b6d0d56190 | 79 | void yellow() |
samdanbury | 6:37b6d0d56190 | 80 | { |
samdanbury | 6:37b6d0d56190 | 81 | r = 0.7; g = 0.7; b = 1.0; // 1 is off, 0 is full brightness |
samdanbury | 6:37b6d0d56190 | 82 | } |
samdanbury | 6:37b6d0d56190 | 83 | |
samdanbury | 6:37b6d0d56190 | 84 | void green() |
samdanbury | 6:37b6d0d56190 | 85 | { |
samdanbury | 6:37b6d0d56190 | 86 | r = 1.0; g = 0.7; b = 1.0; // 1 is off, 0 is full brightness |
samdanbury | 6:37b6d0d56190 | 87 | } |
samdanbury | 6:37b6d0d56190 | 88 | |
samdanbury | 6:37b6d0d56190 | 89 | |
samdanbury | 6:37b6d0d56190 | 90 | void flashing_yellow(void const *args) |
samdanbury | 6:37b6d0d56190 | 91 | { |
samdanbury | 6:37b6d0d56190 | 92 | bool on = false; |
samdanbury | 6:37b6d0d56190 | 93 | while (!connected) // flashing yellow only while connecting |
samdanbury | 6:37b6d0d56190 | 94 | { |
samdanbury | 6:37b6d0d56190 | 95 | on = !on; |
samdanbury | 6:37b6d0d56190 | 96 | if (on) |
samdanbury | 6:37b6d0d56190 | 97 | yellow(); |
samdanbury | 6:37b6d0d56190 | 98 | else |
samdanbury | 6:37b6d0d56190 | 99 | off(); |
samdanbury | 6:37b6d0d56190 | 100 | wait(0.5); |
samdanbury | 6:37b6d0d56190 | 101 | } |
samdanbury | 6:37b6d0d56190 | 102 | } |
samdanbury | 6:37b6d0d56190 | 103 | |
samdanbury | 6:37b6d0d56190 | 104 | |
samdanbury | 6:37b6d0d56190 | 105 | void flashing_red(void const *args) // to be used when the connection is lost |
samdanbury | 6:37b6d0d56190 | 106 | { |
samdanbury | 6:37b6d0d56190 | 107 | bool on = false; |
samdanbury | 6:37b6d0d56190 | 108 | while (!connected) |
samdanbury | 6:37b6d0d56190 | 109 | { |
samdanbury | 6:37b6d0d56190 | 110 | on = !on; |
samdanbury | 6:37b6d0d56190 | 111 | if (on) |
samdanbury | 6:37b6d0d56190 | 112 | red(); |
samdanbury | 6:37b6d0d56190 | 113 | else |
samdanbury | 6:37b6d0d56190 | 114 | off(); |
samdanbury | 6:37b6d0d56190 | 115 | wait(2.0); |
samdanbury | 6:37b6d0d56190 | 116 | } |
samdanbury | 6:37b6d0d56190 | 117 | } |
samdanbury | 6:37b6d0d56190 | 118 | |
samdanbury | 6:37b6d0d56190 | 119 | |
samdanbury | 6:37b6d0d56190 | 120 | void printMenu(int menuItem) |
samdanbury | 6:37b6d0d56190 | 121 | { |
samdanbury | 6:37b6d0d56190 | 122 | lcd.cls(); |
samdanbury | 6:37b6d0d56190 | 123 | lcd.locate(0,0); |
samdanbury | 6:37b6d0d56190 | 124 | switch (menuItem) |
samdanbury | 6:37b6d0d56190 | 125 | { |
samdanbury | 6:37b6d0d56190 | 126 | case 0: |
samdanbury | 6:37b6d0d56190 | 127 | lcd.printf("IBM IoT Cloud"); |
samdanbury | 6:37b6d0d56190 | 128 | lcd.locate(0,16); |
samdanbury | 6:37b6d0d56190 | 129 | lcd.printf("Scroll with joystick"); |
samdanbury | 6:37b6d0d56190 | 130 | break; |
samdanbury | 6:37b6d0d56190 | 131 | case 1: |
samdanbury | 6:37b6d0d56190 | 132 | lcd.printf("Go to:"); |
samdanbury | 6:37b6d0d56190 | 133 | lcd.locate(0,16); |
samdanbury | 6:37b6d0d56190 | 134 | lcd.printf("http://ibm.biz/iotqstart"); |
samdanbury | 6:37b6d0d56190 | 135 | break; |
samdanbury | 6:37b6d0d56190 | 136 | case 2: |
samdanbury | 6:37b6d0d56190 | 137 | lcd.printf("Device Identity:"); |
samdanbury | 6:37b6d0d56190 | 138 | lcd.locate(0,16); |
samdanbury | 6:37b6d0d56190 | 139 | lcd.printf("%s", id); |
samdanbury | 6:37b6d0d56190 | 140 | break; |
samdanbury | 6:37b6d0d56190 | 141 | case 3: |
samdanbury | 6:37b6d0d56190 | 142 | lcd.printf("Status:"); |
samdanbury | 6:37b6d0d56190 | 143 | lcd.locate(0,16); |
samdanbury | 6:37b6d0d56190 | 144 | lcd.printf(connected ? "Connected" : "Disconnected"); |
samdanbury | 6:37b6d0d56190 | 145 | break; |
chris | 10:0b5e0dfee08e | 146 | case 4: |
chris | 10:0b5e0dfee08e | 147 | lcd.printf("App version:"); |
chris | 10:0b5e0dfee08e | 148 | lcd.locate(0,16); |
chris | 10:0b5e0dfee08e | 149 | lcd.printf("%s",__APP_SW_REVISION__); |
chris | 10:0b5e0dfee08e | 150 | break; |
samdanbury | 6:37b6d0d56190 | 151 | } |
samdanbury | 6:37b6d0d56190 | 152 | } |
samdanbury | 6:37b6d0d56190 | 153 | |
samdanbury | 6:37b6d0d56190 | 154 | |
samdanbury | 6:37b6d0d56190 | 155 | void setMenu() |
samdanbury | 6:37b6d0d56190 | 156 | { |
samdanbury | 6:37b6d0d56190 | 157 | static int menuItem = 0; |
samdanbury | 6:37b6d0d56190 | 158 | if (Down) |
samdanbury | 6:37b6d0d56190 | 159 | { |
samdanbury | 6:37b6d0d56190 | 160 | joystickPos = "DOWN"; |
chris | 10:0b5e0dfee08e | 161 | if (menuItem >= 0 && menuItem < 4) |
samdanbury | 6:37b6d0d56190 | 162 | printMenu(++menuItem); |
samdanbury | 6:37b6d0d56190 | 163 | } |
samdanbury | 6:37b6d0d56190 | 164 | else if (Left) |
samdanbury | 6:37b6d0d56190 | 165 | joystickPos = "LEFT"; |
samdanbury | 6:37b6d0d56190 | 166 | else if (Click) |
samdanbury | 6:37b6d0d56190 | 167 | joystickPos = "CLICK"; |
samdanbury | 6:37b6d0d56190 | 168 | else if (Up) |
samdanbury | 6:37b6d0d56190 | 169 | { |
samdanbury | 6:37b6d0d56190 | 170 | joystickPos = "UP"; |
chris | 10:0b5e0dfee08e | 171 | if (menuItem <= 4 && menuItem > 0) |
samdanbury | 6:37b6d0d56190 | 172 | printMenu(--menuItem); |
samdanbury | 6:37b6d0d56190 | 173 | } |
samdanbury | 6:37b6d0d56190 | 174 | else if (Right) |
samdanbury | 6:37b6d0d56190 | 175 | joystickPos = "RIGHT"; |
samdanbury | 6:37b6d0d56190 | 176 | else |
samdanbury | 6:37b6d0d56190 | 177 | joystickPos = "CENTRE"; |
samdanbury | 6:37b6d0d56190 | 178 | } |
samdanbury | 6:37b6d0d56190 | 179 | |
samdanbury | 6:37b6d0d56190 | 180 | |
samdanbury | 6:37b6d0d56190 | 181 | /** |
samdanbury | 6:37b6d0d56190 | 182 | * Display a message on the LCD screen prefixed with IBM IoT Cloud |
samdanbury | 6:37b6d0d56190 | 183 | */ |
samdanbury | 6:37b6d0d56190 | 184 | void displayMessage(char* message) |
samdanbury | 6:37b6d0d56190 | 185 | { |
samdanbury | 6:37b6d0d56190 | 186 | lcd.cls(); |
samdanbury | 6:37b6d0d56190 | 187 | lcd.locate(0,0); |
samdanbury | 6:37b6d0d56190 | 188 | lcd.printf("IBM IoT Cloud"); |
samdanbury | 6:37b6d0d56190 | 189 | lcd.locate(0,16); |
samdanbury | 6:37b6d0d56190 | 190 | lcd.printf(message); |
samdanbury | 6:37b6d0d56190 | 191 | } |
samdanbury | 6:37b6d0d56190 | 192 | |
samdanbury | 6:37b6d0d56190 | 193 | |
samdanbury | 6:37b6d0d56190 | 194 | int connect(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack) |
samdanbury | 6:37b6d0d56190 | 195 | { |
samdanbury | 6:37b6d0d56190 | 196 | const char* iot_ibm = ".messaging.internetofthings.ibmcloud.com"; |
samdanbury | 6:37b6d0d56190 | 197 | |
samdanbury | 6:37b6d0d56190 | 198 | char hostname[strlen(org) + strlen(iot_ibm) + 1]; |
samdanbury | 6:37b6d0d56190 | 199 | sprintf(hostname, "%s%s", org, iot_ibm); |
mazgch | 11:7a6df9a2dcdc | 200 | DEBUG("hostname is %s\n", hostname); |
samdanbury | 6:37b6d0d56190 | 201 | int rc = ipstack->connect(hostname, IBM_IOT_PORT); |
samdanbury | 6:37b6d0d56190 | 202 | if (rc != 0) |
samdanbury | 6:37b6d0d56190 | 203 | return rc; |
samdanbury | 6:37b6d0d56190 | 204 | |
samdanbury | 6:37b6d0d56190 | 205 | // Construct clientId - d:org:type:id |
samdanbury | 6:37b6d0d56190 | 206 | char clientId[strlen(org) + strlen(type) + strlen(id) + 5]; |
samdanbury | 6:37b6d0d56190 | 207 | sprintf(clientId, "d:%s:%s:%s", org, type, id); |
samdanbury | 6:37b6d0d56190 | 208 | DEBUG("clientid is %s\n", clientId); |
samdanbury | 6:37b6d0d56190 | 209 | |
samdanbury | 6:37b6d0d56190 | 210 | // MQTT Connect |
samdanbury | 6:37b6d0d56190 | 211 | MQTTPacket_connectData data = MQTTPacket_connectData_initializer; |
samdanbury | 6:37b6d0d56190 | 212 | data.MQTTVersion = 3; |
samdanbury | 6:37b6d0d56190 | 213 | data.clientID.cstring = clientId; |
samdanbury | 6:37b6d0d56190 | 214 | |
samdanbury | 6:37b6d0d56190 | 215 | if (!quickstartMode) |
samdanbury | 6:37b6d0d56190 | 216 | { |
samdanbury | 6:37b6d0d56190 | 217 | data.username.cstring = "use-token-auth"; |
samdanbury | 6:37b6d0d56190 | 218 | data.password.cstring = auth_token; |
samdanbury | 6:37b6d0d56190 | 219 | } |
samdanbury | 6:37b6d0d56190 | 220 | |
icraggs | 8:80d49dd91542 | 221 | if ((rc = client->connect(data)) == 0) |
samdanbury | 6:37b6d0d56190 | 222 | { |
samdanbury | 6:37b6d0d56190 | 223 | connected = true; |
samdanbury | 6:37b6d0d56190 | 224 | green(); |
samdanbury | 6:37b6d0d56190 | 225 | displayMessage("Connected"); |
samdanbury | 6:37b6d0d56190 | 226 | wait(2); |
samdanbury | 6:37b6d0d56190 | 227 | displayMessage("Scroll with joystick"); |
samdanbury | 6:37b6d0d56190 | 228 | } |
samdanbury | 6:37b6d0d56190 | 229 | return rc; |
samdanbury | 6:37b6d0d56190 | 230 | } |
samdanbury | 6:37b6d0d56190 | 231 | |
samdanbury | 6:37b6d0d56190 | 232 | |
samdanbury | 6:37b6d0d56190 | 233 | int getConnTimeout(int attemptNumber) |
samdanbury | 6:37b6d0d56190 | 234 | { // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute |
samdanbury | 6:37b6d0d56190 | 235 | // after 20 attempts, retry every 10 minutes |
samdanbury | 6:37b6d0d56190 | 236 | return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600; |
samdanbury | 6:37b6d0d56190 | 237 | } |
samdanbury | 6:37b6d0d56190 | 238 | |
samdanbury | 6:37b6d0d56190 | 239 | |
samdanbury | 6:37b6d0d56190 | 240 | void attemptConnect(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack) |
samdanbury | 6:37b6d0d56190 | 241 | { |
samdanbury | 6:37b6d0d56190 | 242 | int retryAttempt = 0; |
samdanbury | 6:37b6d0d56190 | 243 | connected = false; |
icraggs | 8:80d49dd91542 | 244 | |
icraggs | 8:80d49dd91542 | 245 | // make sure a cable is connected before starting to connect |
icraggs | 8:80d49dd91542 | 246 | while (!linkStatus()) { |
icraggs | 8:80d49dd91542 | 247 | wait(1.0f); |
icraggs | 8:80d49dd91542 | 248 | WARN("Ethernet link not present. Check cable connection\n"); |
icraggs | 8:80d49dd91542 | 249 | } |
samdanbury | 6:37b6d0d56190 | 250 | |
samdanbury | 6:37b6d0d56190 | 251 | while (connect(client, ipstack) != 0) |
samdanbury | 6:37b6d0d56190 | 252 | { |
samdanbury | 6:37b6d0d56190 | 253 | Thread red_thread(flashing_red); |
chris | 12:8b480eb8a496 | 254 | |
samdanbury | 6:37b6d0d56190 | 255 | int timeout = getConnTimeout(++retryAttempt); |
samdanbury | 6:37b6d0d56190 | 256 | WARN("Retry attempt number %d waiting %d\n", retryAttempt, timeout); |
icraggs | 8:80d49dd91542 | 257 | |
icraggs | 8:80d49dd91542 | 258 | // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed |
icraggs | 8:80d49dd91542 | 259 | // or maybe just add the proper members to do this disconnect and call attemptConnect(...) |
icraggs | 8:80d49dd91542 | 260 | |
icraggs | 8:80d49dd91542 | 261 | // this works - reset the system when the retry count gets to a threshold |
icraggs | 8:80d49dd91542 | 262 | if (retryAttempt == 5) |
icraggs | 8:80d49dd91542 | 263 | NVIC_SystemReset(); |
icraggs | 8:80d49dd91542 | 264 | else |
icraggs | 8:80d49dd91542 | 265 | wait(timeout); |
samdanbury | 6:37b6d0d56190 | 266 | } |
samdanbury | 6:37b6d0d56190 | 267 | } |
samdanbury | 6:37b6d0d56190 | 268 | |
samdanbury | 6:37b6d0d56190 | 269 | |
samdanbury | 6:37b6d0d56190 | 270 | int publish(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack) |
samdanbury | 6:37b6d0d56190 | 271 | { |
samdanbury | 6:37b6d0d56190 | 272 | MQTT::Message message; |
samdanbury | 6:37b6d0d56190 | 273 | char* pubTopic = "iot-2/evt/status/fmt/json"; |
samdanbury | 6:37b6d0d56190 | 274 | |
samdanbury | 6:37b6d0d56190 | 275 | char buf[250]; |
samdanbury | 6:37b6d0d56190 | 276 | sprintf(buf, |
samdanbury | 6:37b6d0d56190 | 277 | "{\"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 | 6:37b6d0d56190 | 278 | MMA.x(), MMA.y(), MMA.z(), sensor.temp(), joystickPos, ain1.read(), ain2.read()); |
samdanbury | 6:37b6d0d56190 | 279 | message.qos = MQTT::QOS0; |
samdanbury | 6:37b6d0d56190 | 280 | message.retained = false; |
samdanbury | 6:37b6d0d56190 | 281 | message.dup = false; |
samdanbury | 6:37b6d0d56190 | 282 | message.payload = (void*)buf; |
samdanbury | 6:37b6d0d56190 | 283 | message.payloadlen = strlen(buf); |
samdanbury | 6:37b6d0d56190 | 284 | |
samdanbury | 6:37b6d0d56190 | 285 | LOG("Publishing %s\n", buf); |
icraggs | 8:80d49dd91542 | 286 | return client->publish(pubTopic, message); |
samdanbury | 6:37b6d0d56190 | 287 | } |
samdanbury | 6:37b6d0d56190 | 288 | |
samdanbury | 6:37b6d0d56190 | 289 | |
chris | 12:8b480eb8a496 | 290 | |
samdanbury | 6:37b6d0d56190 | 291 | char* getMac(EthernetInterface& eth, char* buf, int buflen) // Obtain MAC address |
samdanbury | 6:37b6d0d56190 | 292 | { |
samdanbury | 6:37b6d0d56190 | 293 | strncpy(buf, eth.getMACAddress(), buflen); |
samdanbury | 6:37b6d0d56190 | 294 | |
samdanbury | 6:37b6d0d56190 | 295 | char* pos; // Remove colons from mac address |
samdanbury | 6:37b6d0d56190 | 296 | while ((pos = strchr(buf, ':')) != NULL) |
samdanbury | 6:37b6d0d56190 | 297 | memmove(pos, pos + 1, strlen(pos) + 1); |
samdanbury | 6:37b6d0d56190 | 298 | return buf; |
samdanbury | 6:37b6d0d56190 | 299 | } |
chris | 12:8b480eb8a496 | 300 | |
samdanbury | 6:37b6d0d56190 | 301 | |
samdanbury | 6:37b6d0d56190 | 302 | |
samdanbury | 6:37b6d0d56190 | 303 | void messageArrived(MQTT::MessageData& md) |
samdanbury | 6:37b6d0d56190 | 304 | { |
samdanbury | 6:37b6d0d56190 | 305 | MQTT::Message &message = md.message; |
samdanbury | 6:37b6d0d56190 | 306 | char topic[md.topicName.lenstring.len + 1]; |
samdanbury | 6:37b6d0d56190 | 307 | |
samdanbury | 6:37b6d0d56190 | 308 | sprintf(topic, "%.*s", md.topicName.lenstring.len, md.topicName.lenstring.data); |
samdanbury | 6:37b6d0d56190 | 309 | |
samdanbury | 6:37b6d0d56190 | 310 | LOG("Message arrived on topic %s: %.*s\n", topic, message.payloadlen, message.payload); |
samdanbury | 6:37b6d0d56190 | 311 | |
samdanbury | 6:37b6d0d56190 | 312 | // Command topic: iot-2/cmd/blink/fmt/json - cmd is the string between cmd/ and /fmt/ |
samdanbury | 6:37b6d0d56190 | 313 | char* start = strstr(topic, "/cmd/") + 5; |
samdanbury | 6:37b6d0d56190 | 314 | int len = strstr(topic, "/fmt/") - start; |
samdanbury | 6:37b6d0d56190 | 315 | |
samdanbury | 6:37b6d0d56190 | 316 | if (memcmp(start, "blink", len) == 0) |
samdanbury | 6:37b6d0d56190 | 317 | { |
samdanbury | 6:37b6d0d56190 | 318 | char payload[message.payloadlen + 1]; |
samdanbury | 6:37b6d0d56190 | 319 | sprintf(payload, "%.*s", message.payloadlen, (char*)message.payload); |
samdanbury | 6:37b6d0d56190 | 320 | |
samdanbury | 6:37b6d0d56190 | 321 | char* pos = strchr(payload, '}'); |
samdanbury | 6:37b6d0d56190 | 322 | if (pos != NULL) |
samdanbury | 6:37b6d0d56190 | 323 | { |
samdanbury | 6:37b6d0d56190 | 324 | *pos = '\0'; |
samdanbury | 6:37b6d0d56190 | 325 | if ((pos = strchr(payload, ':')) != NULL) |
samdanbury | 6:37b6d0d56190 | 326 | { |
samdanbury | 6:37b6d0d56190 | 327 | int blink_rate = atoi(pos + 1); |
samdanbury | 6:37b6d0d56190 | 328 | blink_interval = (blink_rate <= 0) ? 0 : (blink_rate > 50 ? 1 : 50/blink_rate); |
samdanbury | 6:37b6d0d56190 | 329 | } |
samdanbury | 6:37b6d0d56190 | 330 | } |
samdanbury | 6:37b6d0d56190 | 331 | } |
samdanbury | 6:37b6d0d56190 | 332 | else |
samdanbury | 6:37b6d0d56190 | 333 | WARN("Unsupported command: %.*s\n", len, start); |
samdanbury | 6:37b6d0d56190 | 334 | } |
samdanbury | 6:37b6d0d56190 | 335 | |
samdanbury | 6:37b6d0d56190 | 336 | |
samdanbury | 6:37b6d0d56190 | 337 | int main() |
samdanbury | 6:37b6d0d56190 | 338 | { |
icraggs | 8:80d49dd91542 | 339 | quickstartMode = (strcmp(org, "quickstart") == 0); |
icraggs | 8:80d49dd91542 | 340 | |
samdanbury | 6:37b6d0d56190 | 341 | lcd.set_font((unsigned char*) Arial12x12); // Set a nice font for the LCD screen |
samdanbury | 6:37b6d0d56190 | 342 | |
samdanbury | 6:37b6d0d56190 | 343 | led2 = LED2_OFF; // K64F: turn off the main board LED |
samdanbury | 6:37b6d0d56190 | 344 | |
samdanbury | 6:37b6d0d56190 | 345 | displayMessage("Connecting"); |
samdanbury | 6:37b6d0d56190 | 346 | Thread yellow_thread(flashing_yellow); |
chris | 12:8b480eb8a496 | 347 | printf("connecting..."); |
samdanbury | 6:37b6d0d56190 | 348 | MQTTEthernet ipstack; |
samdanbury | 6:37b6d0d56190 | 349 | MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE> client(ipstack); |
samdanbury | 6:37b6d0d56190 | 350 | |
samdanbury | 6:37b6d0d56190 | 351 | if (quickstartMode) |
samdanbury | 6:37b6d0d56190 | 352 | { |
samdanbury | 6:37b6d0d56190 | 353 | getMac(ipstack.getEth(), id, sizeof(id)); |
samdanbury | 6:37b6d0d56190 | 354 | } |
samdanbury | 6:37b6d0d56190 | 355 | |
samdanbury | 6:37b6d0d56190 | 356 | attemptConnect(&client, &ipstack); |
samdanbury | 6:37b6d0d56190 | 357 | |
samdanbury | 6:37b6d0d56190 | 358 | if (!quickstartMode) |
samdanbury | 6:37b6d0d56190 | 359 | { |
samdanbury | 6:37b6d0d56190 | 360 | int rc = 0; |
samdanbury | 6:37b6d0d56190 | 361 | if ((rc = client.subscribe("iot-2/cmd/+/fmt/json", MQTT::QOS1, messageArrived)) != 0) |
samdanbury | 6:37b6d0d56190 | 362 | WARN("rc from MQTT subscribe is %d\n", rc); |
samdanbury | 6:37b6d0d56190 | 363 | } |
samdanbury | 6:37b6d0d56190 | 364 | |
samdanbury | 6:37b6d0d56190 | 365 | blink_interval = 0; |
samdanbury | 6:37b6d0d56190 | 366 | int count = 0; |
samdanbury | 6:37b6d0d56190 | 367 | while (true) |
samdanbury | 6:37b6d0d56190 | 368 | { |
samdanbury | 6:37b6d0d56190 | 369 | if (++count == 100) |
samdanbury | 6:37b6d0d56190 | 370 | { // Publish a message every second |
samdanbury | 6:37b6d0d56190 | 371 | if (publish(&client, &ipstack) != 0) |
samdanbury | 6:37b6d0d56190 | 372 | attemptConnect(&client, &ipstack); // if we have lost the connection |
samdanbury | 6:37b6d0d56190 | 373 | count = 0; |
samdanbury | 6:37b6d0d56190 | 374 | } |
samdanbury | 6:37b6d0d56190 | 375 | |
samdanbury | 6:37b6d0d56190 | 376 | if (blink_interval == 0) |
samdanbury | 6:37b6d0d56190 | 377 | led2 = LED2_OFF; |
samdanbury | 6:37b6d0d56190 | 378 | else if (count % blink_interval == 0) |
samdanbury | 6:37b6d0d56190 | 379 | led2 = !led2; |
samdanbury | 6:37b6d0d56190 | 380 | if (count % 20 == 0) |
samdanbury | 6:37b6d0d56190 | 381 | setMenu(); |
samdanbury | 6:37b6d0d56190 | 382 | client.yield(10); // allow the MQTT client to receive messages |
samdanbury | 6:37b6d0d56190 | 383 | } |
samdanbury | 6:37b6d0d56190 | 384 | } |