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 IBM Watson IoT

Committer:
AryanVarma
Date:
Tue Mar 29 03:46:17 2016 +0000
Revision:
19:ee5e5c9573e5
Parent:
18:94da9de96d54
IoT based security system that detects suspicious movements through a Grove PIR motion sensor and alerts  the user on their email if the motion detected is between 7 to 9 times.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
samdanbury 6:37b6d0d56190 1 #include "LM75B.h"
samdanbury 6:37b6d0d56190 2 #include "MMA7660.h"
samdanbury 6:37b6d0d56190 3 #include "MQTTClient.h"
samdanbury 6:37b6d0d56190 4 #include "MQTTEthernet.h"
samdanbury 6:37b6d0d56190 5 #include "C12832.h"
samdanbury 6:37b6d0d56190 6 #include "Arial12x12.h"
samdanbury 6:37b6d0d56190 7 #include "rtos.h"
samdanbury 6:37b6d0d56190 8
chris 10:0b5e0dfee08e 9 // Update this to the next number *before* a commit
icraggs 18:94da9de96d54 10 #define __APP_SW_REVISION__ "18"
chris 10:0b5e0dfee08e 11
samdanbury 6:37b6d0d56190 12 // Configuration values needed to connect to IBM IoT Cloud
AryanVarma 19:ee5e5c9573e5 13 #define ORG "" // For a registered connection, replace with your org
icraggs 8:80d49dd91542 14 #define ID "" // For a registered connection, replace with your id
icraggs 8:80d49dd91542 15 #define AUTH_TOKEN "" // For a registered connection, replace with your auth-token
AryanVarma 19:ee5e5c9573e5 16 #define TYPE "" // For a registered connection, replace with your type
samdanbury 6:37b6d0d56190 17
samdanbury 6:37b6d0d56190 18 #define MQTT_PORT 1883
samdanbury 6:37b6d0d56190 19 #define MQTT_TLS_PORT 8883
samdanbury 6:37b6d0d56190 20 #define IBM_IOT_PORT MQTT_PORT
samdanbury 6:37b6d0d56190 21
samdanbury 6:37b6d0d56190 22 #define MQTT_MAX_PACKET_SIZE 250
AryanVarma 19:ee5e5c9573e5 23 #include "K64F.h"
AryanVarma 19:ee5e5c9573e5 24 InterruptIn motion(D2);
samdanbury 6:37b6d0d56190 25
AryanVarma 19:ee5e5c9573e5 26 int motion_detected = 0;
samdanbury 6:37b6d0d56190 27
AryanVarma 19:ee5e5c9573e5 28 void irq_handler(void)
AryanVarma 19:ee5e5c9573e5 29 {
AryanVarma 19:ee5e5c9573e5 30 motion_detected = 1;
AryanVarma 19:ee5e5c9573e5 31 }
AryanVarma 19:ee5e5c9573e5 32 int cnt = 0;
jsutton 14:1f961d19f3cf 33
icraggs 8:80d49dd91542 34 bool quickstartMode = true;
samdanbury 6:37b6d0d56190 35 char org[11] = ORG;
samdanbury 6:37b6d0d56190 36 char type[30] = TYPE;
samdanbury 6:37b6d0d56190 37 char id[30] = ID; // mac without colons
samdanbury 6:37b6d0d56190 38 char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode
samdanbury 6:37b6d0d56190 39
samdanbury 6:37b6d0d56190 40 bool connected = false;
jsutton 14:1f961d19f3cf 41 bool mqttConnecting = false;
jsutton 14:1f961d19f3cf 42 bool netConnected = false;
jsutton 14:1f961d19f3cf 43 bool netConnecting = false;
jsutton 14:1f961d19f3cf 44 bool ethernetInitialising = true;
icraggs 16:2420bfbf5f1c 45 int connack_rc = 0; // MQTT connack return code
jsutton 14:1f961d19f3cf 46 int retryAttempt = 0;
jsutton 14:1f961d19f3cf 47 int menuItem = 0;
jsutton 14:1f961d19f3cf 48
samdanbury 6:37b6d0d56190 49 char* joystickPos = "CENTRE";
samdanbury 6:37b6d0d56190 50 int blink_interval = 0;
samdanbury 6:37b6d0d56190 51
jsutton 13:85801e3b83d3 52 char* ip_addr = "";
jsutton 13:85801e3b83d3 53 char* gateway_addr = "";
jsutton 14:1f961d19f3cf 54 char* host_addr = "";
jsutton 14:1f961d19f3cf 55 int connectTimeout = 1000;
jsutton 14:1f961d19f3cf 56
jsutton 14:1f961d19f3cf 57 // If we wanted to manually set the MAC address,
jsutton 14:1f961d19f3cf 58 // this is how to do it. In this example, we take
jsutton 14:1f961d19f3cf 59 // the original Mbed Set MAC address and combine it
jsutton 14:1f961d19f3cf 60 // with a prefix of our choosing.
jsutton 14:1f961d19f3cf 61 /*
jsutton 14:1f961d19f3cf 62 extern "C" void $Super$$mbed_mac_address(char *s);
jsutton 14:1f961d19f3cf 63 extern "C" void $Sub$$mbed_mac_address(char *s)
jsutton 14:1f961d19f3cf 64 {
jsutton 15:09458079f4bb 65 char originalMAC[6] = "";
jsutton 15:09458079f4bb 66 $Super$$mbed_mac_address(originalMAC);
jsutton 14:1f961d19f3cf 67
jsutton 14:1f961d19f3cf 68 char mac[6];
jsutton 14:1f961d19f3cf 69 mac[0] = 0x00;
jsutton 14:1f961d19f3cf 70 mac[1] = 0x08;
jsutton 14:1f961d19f3cf 71 mac[2] = 0xdc;
jsutton 15:09458079f4bb 72 mac[3] = originalMAC[3];
jsutton 15:09458079f4bb 73 mac[4] = originalMAC[4];
jsutton 15:09458079f4bb 74 mac[5] = originalMAC[5];
jsutton 14:1f961d19f3cf 75 memcpy(s, mac, 6);
jsutton 14:1f961d19f3cf 76 }
jsutton 14:1f961d19f3cf 77 */
jsutton 13:85801e3b83d3 78
samdanbury 6:37b6d0d56190 79
samdanbury 6:37b6d0d56190 80 void off()
samdanbury 6:37b6d0d56190 81 {
samdanbury 6:37b6d0d56190 82 r = g = b = 1.0; // 1 is off, 0 is full brightness
samdanbury 6:37b6d0d56190 83 }
samdanbury 6:37b6d0d56190 84
samdanbury 6:37b6d0d56190 85 void red()
samdanbury 6:37b6d0d56190 86 {
samdanbury 6:37b6d0d56190 87 r = 0.7; g = 1.0; b = 1.0; // 1 is off, 0 is full brightness
samdanbury 6:37b6d0d56190 88 }
samdanbury 6:37b6d0d56190 89
samdanbury 6:37b6d0d56190 90 void yellow()
samdanbury 6:37b6d0d56190 91 {
samdanbury 6:37b6d0d56190 92 r = 0.7; g = 0.7; b = 1.0; // 1 is off, 0 is full brightness
samdanbury 6:37b6d0d56190 93 }
samdanbury 6:37b6d0d56190 94
samdanbury 6:37b6d0d56190 95 void green()
samdanbury 6:37b6d0d56190 96 {
samdanbury 6:37b6d0d56190 97 r = 1.0; g = 0.7; b = 1.0; // 1 is off, 0 is full brightness
samdanbury 6:37b6d0d56190 98 }
samdanbury 6:37b6d0d56190 99
samdanbury 6:37b6d0d56190 100
samdanbury 6:37b6d0d56190 101 void flashing_yellow(void const *args)
samdanbury 6:37b6d0d56190 102 {
samdanbury 6:37b6d0d56190 103 bool on = false;
icraggs 16:2420bfbf5f1c 104 while (!connected && connack_rc != MQTT_NOT_AUTHORIZED && connack_rc != MQTT_BAD_USERNAME_OR_PASSWORD) // flashing yellow only while connecting
samdanbury 6:37b6d0d56190 105 {
samdanbury 6:37b6d0d56190 106 on = !on;
samdanbury 6:37b6d0d56190 107 if (on)
samdanbury 6:37b6d0d56190 108 yellow();
samdanbury 6:37b6d0d56190 109 else
samdanbury 6:37b6d0d56190 110 off();
samdanbury 6:37b6d0d56190 111 wait(0.5);
samdanbury 6:37b6d0d56190 112 }
samdanbury 6:37b6d0d56190 113 }
samdanbury 6:37b6d0d56190 114
samdanbury 6:37b6d0d56190 115
samdanbury 6:37b6d0d56190 116 void flashing_red(void const *args) // to be used when the connection is lost
samdanbury 6:37b6d0d56190 117 {
samdanbury 6:37b6d0d56190 118 bool on = false;
samdanbury 6:37b6d0d56190 119 while (!connected)
samdanbury 6:37b6d0d56190 120 {
samdanbury 6:37b6d0d56190 121 on = !on;
samdanbury 6:37b6d0d56190 122 if (on)
samdanbury 6:37b6d0d56190 123 red();
samdanbury 6:37b6d0d56190 124 else
samdanbury 6:37b6d0d56190 125 off();
samdanbury 6:37b6d0d56190 126 wait(2.0);
samdanbury 6:37b6d0d56190 127 }
samdanbury 6:37b6d0d56190 128 }
samdanbury 6:37b6d0d56190 129
samdanbury 6:37b6d0d56190 130
samdanbury 6:37b6d0d56190 131 void printMenu(int menuItem)
samdanbury 6:37b6d0d56190 132 {
icraggs 18:94da9de96d54 133 static char last_line1[30] = "", last_line2[30] = "";
icraggs 18:94da9de96d54 134 char line1[30] = "", line2[30] = "";
icraggs 18:94da9de96d54 135
samdanbury 6:37b6d0d56190 136 switch (menuItem)
samdanbury 6:37b6d0d56190 137 {
samdanbury 6:37b6d0d56190 138 case 0:
icraggs 18:94da9de96d54 139 sprintf(line1, "IBM IoT Cloud");
icraggs 18:94da9de96d54 140 sprintf(line2, "Scroll with joystick");
samdanbury 6:37b6d0d56190 141 break;
samdanbury 6:37b6d0d56190 142 case 1:
icraggs 18:94da9de96d54 143 sprintf(line1, "Go to:");
icraggs 18:94da9de96d54 144 sprintf(line2, "http://ibm.biz/iotqstart");
samdanbury 6:37b6d0d56190 145 break;
samdanbury 6:37b6d0d56190 146 case 2:
icraggs 18:94da9de96d54 147 sprintf(line1, "Device Identity:");
icraggs 18:94da9de96d54 148 sprintf(line2, "%s", id);
samdanbury 6:37b6d0d56190 149 break;
samdanbury 6:37b6d0d56190 150 case 3:
icraggs 18:94da9de96d54 151 sprintf(line1, "MQTT Status:");
icraggs 16:2420bfbf5f1c 152 if (mqttConnecting)
icraggs 18:94da9de96d54 153 sprintf(line2, "Connecting... %d/5", retryAttempt);
icraggs 16:2420bfbf5f1c 154 else
icraggs 16:2420bfbf5f1c 155 {
icraggs 16:2420bfbf5f1c 156 if (connected)
icraggs 18:94da9de96d54 157 sprintf(line2, "Connected");
icraggs 16:2420bfbf5f1c 158 else
icraggs 16:2420bfbf5f1c 159 {
icraggs 16:2420bfbf5f1c 160 switch (connack_rc)
icraggs 16:2420bfbf5f1c 161 {
icraggs 16:2420bfbf5f1c 162 case MQTT_CLIENTID_REJECTED:
icraggs 18:94da9de96d54 163 sprintf(line2, "Clientid rejected");
icraggs 16:2420bfbf5f1c 164 break;
icraggs 16:2420bfbf5f1c 165 case MQTT_BAD_USERNAME_OR_PASSWORD:
icraggs 18:94da9de96d54 166 sprintf(line2, "Invalid username or password");
icraggs 16:2420bfbf5f1c 167 break;
icraggs 16:2420bfbf5f1c 168 case MQTT_NOT_AUTHORIZED:
icraggs 18:94da9de96d54 169 sprintf(line2, "Not authorized");
icraggs 16:2420bfbf5f1c 170 break;
icraggs 16:2420bfbf5f1c 171 default:
icraggs 18:94da9de96d54 172 sprintf(line2, "Disconnected");
icraggs 16:2420bfbf5f1c 173 }
icraggs 16:2420bfbf5f1c 174 }
jsutton 14:1f961d19f3cf 175 }
samdanbury 6:37b6d0d56190 176 break;
chris 10:0b5e0dfee08e 177 case 4:
icraggs 18:94da9de96d54 178 sprintf(line1, "Ethernet State:");
icraggs 18:94da9de96d54 179 sprintf(line2, ethernetInitialising ? "Initializing..." : "Initialized");
jsutton 14:1f961d19f3cf 180 break;
jsutton 14:1f961d19f3cf 181 case 5:
icraggs 18:94da9de96d54 182 sprintf(line1, "Socket State:");
icraggs 16:2420bfbf5f1c 183 if (netConnecting)
icraggs 18:94da9de96d54 184 sprintf(line2, "Connecting... %d/5", retryAttempt);
icraggs 16:2420bfbf5f1c 185 else
icraggs 18:94da9de96d54 186 sprintf(line2, netConnected ? "Connected" : "Disconnected");
jsutton 13:85801e3b83d3 187 break;
jsutton 14:1f961d19f3cf 188 case 6:
icraggs 18:94da9de96d54 189 sprintf(line1, "IP Address:");
icraggs 18:94da9de96d54 190 sprintf(line2, "%s", ip_addr);
jsutton 13:85801e3b83d3 191 break;
jsutton 14:1f961d19f3cf 192 case 7:
icraggs 18:94da9de96d54 193 sprintf(line1, "Gateway:");
icraggs 18:94da9de96d54 194 sprintf(line2, "%s", gateway_addr);
jsutton 13:85801e3b83d3 195 break;
jsutton 14:1f961d19f3cf 196 case 8:
icraggs 18:94da9de96d54 197 sprintf(line1, "App version:");
icraggs 18:94da9de96d54 198 sprintf(line2, "%s", __APP_SW_REVISION__);
chris 10:0b5e0dfee08e 199 break;
jsutton 14:1f961d19f3cf 200 case 9:
icraggs 18:94da9de96d54 201 sprintf(line1, "Current Timeout:");
icraggs 18:94da9de96d54 202 sprintf(line2, "%d ms", connectTimeout);
jsutton 14:1f961d19f3cf 203 break;
samdanbury 6:37b6d0d56190 204 }
icraggs 18:94da9de96d54 205
icraggs 18:94da9de96d54 206 if (strcmp(line1, last_line1) != 0 || strcmp(line2, last_line2) != 0)
icraggs 18:94da9de96d54 207 {
icraggs 18:94da9de96d54 208 lcd.cls();
icraggs 18:94da9de96d54 209 lcd.locate(0, 0);
icraggs 18:94da9de96d54 210 lcd.printf(line1);
icraggs 18:94da9de96d54 211 strncpy(last_line1, line1, sizeof(last_line1));
icraggs 18:94da9de96d54 212
icraggs 18:94da9de96d54 213 lcd.locate(0,16);
icraggs 18:94da9de96d54 214 lcd.printf(line2);
icraggs 18:94da9de96d54 215 strncpy(last_line2, line2, sizeof(last_line2));
icraggs 18:94da9de96d54 216 }
samdanbury 6:37b6d0d56190 217 }
samdanbury 6:37b6d0d56190 218
samdanbury 6:37b6d0d56190 219
samdanbury 6:37b6d0d56190 220 void setMenu()
samdanbury 6:37b6d0d56190 221 {
jsutton 14:1f961d19f3cf 222
samdanbury 6:37b6d0d56190 223 if (Down)
samdanbury 6:37b6d0d56190 224 {
samdanbury 6:37b6d0d56190 225 joystickPos = "DOWN";
jsutton 14:1f961d19f3cf 226 if (menuItem >= 0 && menuItem < 9)
samdanbury 6:37b6d0d56190 227 printMenu(++menuItem);
samdanbury 6:37b6d0d56190 228 }
samdanbury 6:37b6d0d56190 229 else if (Left)
samdanbury 6:37b6d0d56190 230 joystickPos = "LEFT";
samdanbury 6:37b6d0d56190 231 else if (Click)
samdanbury 6:37b6d0d56190 232 joystickPos = "CLICK";
samdanbury 6:37b6d0d56190 233 else if (Up)
samdanbury 6:37b6d0d56190 234 {
samdanbury 6:37b6d0d56190 235 joystickPos = "UP";
jsutton 14:1f961d19f3cf 236 if (menuItem <= 9 && menuItem > 0)
samdanbury 6:37b6d0d56190 237 printMenu(--menuItem);
samdanbury 6:37b6d0d56190 238 }
samdanbury 6:37b6d0d56190 239 else if (Right)
samdanbury 6:37b6d0d56190 240 joystickPos = "RIGHT";
samdanbury 6:37b6d0d56190 241 else
samdanbury 6:37b6d0d56190 242 joystickPos = "CENTRE";
samdanbury 6:37b6d0d56190 243 }
samdanbury 6:37b6d0d56190 244
jsutton 13:85801e3b83d3 245 void menu_loop(void const *args)
jsutton 13:85801e3b83d3 246 {
jsutton 14:1f961d19f3cf 247 int count = 0;
icraggs 16:2420bfbf5f1c 248 while(true)
icraggs 16:2420bfbf5f1c 249 {
jsutton 13:85801e3b83d3 250 setMenu();
icraggs 16:2420bfbf5f1c 251 if (++count % 10 == 0)
jsutton 14:1f961d19f3cf 252 printMenu(menuItem);
jsutton 14:1f961d19f3cf 253 Thread::wait(100);
jsutton 13:85801e3b83d3 254 }
jsutton 13:85801e3b83d3 255 }
jsutton 13:85801e3b83d3 256
samdanbury 6:37b6d0d56190 257
samdanbury 6:37b6d0d56190 258 /**
samdanbury 6:37b6d0d56190 259 * Display a message on the LCD screen prefixed with IBM IoT Cloud
samdanbury 6:37b6d0d56190 260 */
samdanbury 6:37b6d0d56190 261 void displayMessage(char* message)
samdanbury 6:37b6d0d56190 262 {
samdanbury 6:37b6d0d56190 263 lcd.cls();
samdanbury 6:37b6d0d56190 264 lcd.locate(0,0);
samdanbury 6:37b6d0d56190 265 lcd.printf("IBM IoT Cloud");
samdanbury 6:37b6d0d56190 266 lcd.locate(0,16);
samdanbury 6:37b6d0d56190 267 lcd.printf(message);
samdanbury 6:37b6d0d56190 268 }
samdanbury 6:37b6d0d56190 269
samdanbury 6:37b6d0d56190 270
samdanbury 6:37b6d0d56190 271 int connect(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack)
samdanbury 6:37b6d0d56190 272 {
samdanbury 6:37b6d0d56190 273 const char* iot_ibm = ".messaging.internetofthings.ibmcloud.com";
samdanbury 6:37b6d0d56190 274
samdanbury 6:37b6d0d56190 275 char hostname[strlen(org) + strlen(iot_ibm) + 1];
samdanbury 6:37b6d0d56190 276 sprintf(hostname, "%s%s", org, iot_ibm);
jsutton 13:85801e3b83d3 277 EthernetInterface& eth = ipstack->getEth();
jsutton 13:85801e3b83d3 278 ip_addr = eth.getIPAddress();
jsutton 13:85801e3b83d3 279 gateway_addr = eth.getGateway();
jsutton 14:1f961d19f3cf 280
jsutton 14:1f961d19f3cf 281 // Construct clientId - d:org:type:id
jsutton 14:1f961d19f3cf 282 char clientId[strlen(org) + strlen(type) + strlen(id) + 5];
jsutton 14:1f961d19f3cf 283 sprintf(clientId, "d:%s:%s:%s", org, type, id);
jsutton 14:1f961d19f3cf 284
icraggs 16:2420bfbf5f1c 285 // Network debug statements
jsutton 14:1f961d19f3cf 286 LOG("=====================================\n");
jsutton 14:1f961d19f3cf 287 LOG("Connecting Ethernet.\n");
jsutton 14:1f961d19f3cf 288 LOG("IP ADDRESS: %s\n", eth.getIPAddress());
jsutton 14:1f961d19f3cf 289 LOG("MAC ADDRESS: %s\n", eth.getMACAddress());
jsutton 14:1f961d19f3cf 290 LOG("Gateway: %s\n", eth.getGateway());
jsutton 14:1f961d19f3cf 291 LOG("Network Mask: %s\n", eth.getNetworkMask());
jsutton 14:1f961d19f3cf 292 LOG("Server Hostname: %s\n", hostname);
jsutton 14:1f961d19f3cf 293 LOG("Client ID: %s\n", clientId);
jsutton 14:1f961d19f3cf 294 LOG("=====================================\n");
jsutton 14:1f961d19f3cf 295
jsutton 14:1f961d19f3cf 296 netConnecting = true;
jsutton 14:1f961d19f3cf 297 int rc = ipstack->connect(hostname, IBM_IOT_PORT, connectTimeout);
icraggs 16:2420bfbf5f1c 298 if (rc != 0)
icraggs 16:2420bfbf5f1c 299 {
icraggs 18:94da9de96d54 300 WARN("IP Stack connect returned: %d\n", rc);
samdanbury 6:37b6d0d56190 301 return rc;
jsutton 13:85801e3b83d3 302 }
jsutton 13:85801e3b83d3 303 netConnected = true;
jsutton 14:1f961d19f3cf 304 netConnecting = false;
jsutton 14:1f961d19f3cf 305
samdanbury 6:37b6d0d56190 306 // MQTT Connect
jsutton 14:1f961d19f3cf 307 mqttConnecting = true;
samdanbury 6:37b6d0d56190 308 MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
samdanbury 6:37b6d0d56190 309 data.MQTTVersion = 3;
samdanbury 6:37b6d0d56190 310 data.clientID.cstring = clientId;
samdanbury 6:37b6d0d56190 311
samdanbury 6:37b6d0d56190 312 if (!quickstartMode)
samdanbury 6:37b6d0d56190 313 {
samdanbury 6:37b6d0d56190 314 data.username.cstring = "use-token-auth";
samdanbury 6:37b6d0d56190 315 data.password.cstring = auth_token;
samdanbury 6:37b6d0d56190 316 }
samdanbury 6:37b6d0d56190 317
icraggs 8:80d49dd91542 318 if ((rc = client->connect(data)) == 0)
samdanbury 6:37b6d0d56190 319 {
samdanbury 6:37b6d0d56190 320 connected = true;
samdanbury 6:37b6d0d56190 321 green();
samdanbury 6:37b6d0d56190 322 displayMessage("Connected");
jsutton 13:85801e3b83d3 323 wait(1);
samdanbury 6:37b6d0d56190 324 displayMessage("Scroll with joystick");
samdanbury 6:37b6d0d56190 325 }
icraggs 16:2420bfbf5f1c 326 else
icraggs 16:2420bfbf5f1c 327 WARN("MQTT connect returned %d\n", rc);
icraggs 16:2420bfbf5f1c 328 if (rc >= 0)
icraggs 16:2420bfbf5f1c 329 connack_rc = rc;
jsutton 14:1f961d19f3cf 330 mqttConnecting = false;
samdanbury 6:37b6d0d56190 331 return rc;
samdanbury 6:37b6d0d56190 332 }
samdanbury 6:37b6d0d56190 333
samdanbury 6:37b6d0d56190 334
samdanbury 6:37b6d0d56190 335 int getConnTimeout(int attemptNumber)
samdanbury 6:37b6d0d56190 336 { // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute
samdanbury 6:37b6d0d56190 337 // after 20 attempts, retry every 10 minutes
samdanbury 6:37b6d0d56190 338 return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600;
samdanbury 6:37b6d0d56190 339 }
samdanbury 6:37b6d0d56190 340
samdanbury 6:37b6d0d56190 341
samdanbury 6:37b6d0d56190 342 void attemptConnect(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack)
samdanbury 6:37b6d0d56190 343 {
samdanbury 6:37b6d0d56190 344 connected = false;
icraggs 16:2420bfbf5f1c 345
icraggs 8:80d49dd91542 346 // make sure a cable is connected before starting to connect
icraggs 16:2420bfbf5f1c 347 while (!linkStatus())
icraggs 16:2420bfbf5f1c 348 {
icraggs 8:80d49dd91542 349 wait(1.0f);
icraggs 8:80d49dd91542 350 WARN("Ethernet link not present. Check cable connection\n");
icraggs 8:80d49dd91542 351 }
samdanbury 6:37b6d0d56190 352
icraggs 16:2420bfbf5f1c 353 while (connect(client, ipstack) != MQTT_CONNECTION_ACCEPTED)
samdanbury 6:37b6d0d56190 354 {
icraggs 16:2420bfbf5f1c 355 if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD)
icraggs 16:2420bfbf5f1c 356 return; // don't reattempt to connect if credentials are wrong
icraggs 16:2420bfbf5f1c 357
samdanbury 6:37b6d0d56190 358 Thread red_thread(flashing_red);
chris 12:8b480eb8a496 359
samdanbury 6:37b6d0d56190 360 int timeout = getConnTimeout(++retryAttempt);
samdanbury 6:37b6d0d56190 361 WARN("Retry attempt number %d waiting %d\n", retryAttempt, timeout);
icraggs 8:80d49dd91542 362
icraggs 8:80d49dd91542 363 // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed
icraggs 8:80d49dd91542 364 // or maybe just add the proper members to do this disconnect and call attemptConnect(...)
icraggs 8:80d49dd91542 365
icraggs 8:80d49dd91542 366 // this works - reset the system when the retry count gets to a threshold
icraggs 8:80d49dd91542 367 if (retryAttempt == 5)
icraggs 8:80d49dd91542 368 NVIC_SystemReset();
icraggs 8:80d49dd91542 369 else
icraggs 8:80d49dd91542 370 wait(timeout);
samdanbury 6:37b6d0d56190 371 }
samdanbury 6:37b6d0d56190 372 }
samdanbury 6:37b6d0d56190 373
samdanbury 6:37b6d0d56190 374
samdanbury 6:37b6d0d56190 375 int publish(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack)
samdanbury 6:37b6d0d56190 376 {
samdanbury 6:37b6d0d56190 377 MQTT::Message message;
samdanbury 6:37b6d0d56190 378 char* pubTopic = "iot-2/evt/status/fmt/json";
AryanVarma 19:ee5e5c9573e5 379 motion.rise(&irq_handler);
AryanVarma 19:ee5e5c9573e5 380 if(motion_detected){
AryanVarma 19:ee5e5c9573e5 381 cnt++;
AryanVarma 19:ee5e5c9573e5 382 motion_detected = 0;
AryanVarma 19:ee5e5c9573e5 383 }
samdanbury 6:37b6d0d56190 384 char buf[250];
AryanVarma 19:ee5e5c9573e5 385
AryanVarma 19:ee5e5c9573e5 386 if(cnt > 7 && cnt<10)
AryanVarma 19:ee5e5c9573e5 387 {
AryanVarma 19:ee5e5c9573e5 388 sprintf(buf,"{\"Motion\":\"%s\"}","md");
AryanVarma 19:ee5e5c9573e5 389 }
AryanVarma 19:ee5e5c9573e5 390
samdanbury 6:37b6d0d56190 391 message.qos = MQTT::QOS0;
samdanbury 6:37b6d0d56190 392 message.retained = false;
samdanbury 6:37b6d0d56190 393 message.dup = false;
samdanbury 6:37b6d0d56190 394 message.payload = (void*)buf;
samdanbury 6:37b6d0d56190 395 message.payloadlen = strlen(buf);
samdanbury 6:37b6d0d56190 396
samdanbury 6:37b6d0d56190 397 LOG("Publishing %s\n", buf);
icraggs 8:80d49dd91542 398 return client->publish(pubTopic, message);
samdanbury 6:37b6d0d56190 399 }
samdanbury 6:37b6d0d56190 400
samdanbury 6:37b6d0d56190 401
samdanbury 6:37b6d0d56190 402 char* getMac(EthernetInterface& eth, char* buf, int buflen) // Obtain MAC address
samdanbury 6:37b6d0d56190 403 {
samdanbury 6:37b6d0d56190 404 strncpy(buf, eth.getMACAddress(), buflen);
samdanbury 6:37b6d0d56190 405
samdanbury 6:37b6d0d56190 406 char* pos; // Remove colons from mac address
samdanbury 6:37b6d0d56190 407 while ((pos = strchr(buf, ':')) != NULL)
samdanbury 6:37b6d0d56190 408 memmove(pos, pos + 1, strlen(pos) + 1);
samdanbury 6:37b6d0d56190 409 return buf;
samdanbury 6:37b6d0d56190 410 }
chris 12:8b480eb8a496 411
samdanbury 6:37b6d0d56190 412
samdanbury 6:37b6d0d56190 413 void messageArrived(MQTT::MessageData& md)
samdanbury 6:37b6d0d56190 414 {
samdanbury 6:37b6d0d56190 415 MQTT::Message &message = md.message;
samdanbury 6:37b6d0d56190 416 char topic[md.topicName.lenstring.len + 1];
samdanbury 6:37b6d0d56190 417
samdanbury 6:37b6d0d56190 418 sprintf(topic, "%.*s", md.topicName.lenstring.len, md.topicName.lenstring.data);
samdanbury 6:37b6d0d56190 419
samdanbury 6:37b6d0d56190 420 LOG("Message arrived on topic %s: %.*s\n", topic, message.payloadlen, message.payload);
samdanbury 6:37b6d0d56190 421
samdanbury 6:37b6d0d56190 422 // Command topic: iot-2/cmd/blink/fmt/json - cmd is the string between cmd/ and /fmt/
samdanbury 6:37b6d0d56190 423 char* start = strstr(topic, "/cmd/") + 5;
samdanbury 6:37b6d0d56190 424 int len = strstr(topic, "/fmt/") - start;
samdanbury 6:37b6d0d56190 425
samdanbury 6:37b6d0d56190 426 if (memcmp(start, "blink", len) == 0)
samdanbury 6:37b6d0d56190 427 {
samdanbury 6:37b6d0d56190 428 char payload[message.payloadlen + 1];
samdanbury 6:37b6d0d56190 429 sprintf(payload, "%.*s", message.payloadlen, (char*)message.payload);
samdanbury 6:37b6d0d56190 430
samdanbury 6:37b6d0d56190 431 char* pos = strchr(payload, '}');
samdanbury 6:37b6d0d56190 432 if (pos != NULL)
samdanbury 6:37b6d0d56190 433 {
samdanbury 6:37b6d0d56190 434 *pos = '\0';
samdanbury 6:37b6d0d56190 435 if ((pos = strchr(payload, ':')) != NULL)
samdanbury 6:37b6d0d56190 436 {
samdanbury 6:37b6d0d56190 437 int blink_rate = atoi(pos + 1);
samdanbury 6:37b6d0d56190 438 blink_interval = (blink_rate <= 0) ? 0 : (blink_rate > 50 ? 1 : 50/blink_rate);
samdanbury 6:37b6d0d56190 439 }
samdanbury 6:37b6d0d56190 440 }
samdanbury 6:37b6d0d56190 441 }
samdanbury 6:37b6d0d56190 442 else
samdanbury 6:37b6d0d56190 443 WARN("Unsupported command: %.*s\n", len, start);
samdanbury 6:37b6d0d56190 444 }
samdanbury 6:37b6d0d56190 445
samdanbury 6:37b6d0d56190 446
samdanbury 6:37b6d0d56190 447 int main()
samdanbury 6:37b6d0d56190 448 {
icraggs 8:80d49dd91542 449 quickstartMode = (strcmp(org, "quickstart") == 0);
icraggs 8:80d49dd91542 450
samdanbury 6:37b6d0d56190 451 lcd.set_font((unsigned char*) Arial12x12); // Set a nice font for the LCD screen
samdanbury 6:37b6d0d56190 452
samdanbury 6:37b6d0d56190 453 led2 = LED2_OFF; // K64F: turn off the main board LED
samdanbury 6:37b6d0d56190 454
samdanbury 6:37b6d0d56190 455 displayMessage("Connecting");
jsutton 13:85801e3b83d3 456 Thread yellow_thread(flashing_yellow);
jsutton 13:85801e3b83d3 457 Thread menu_thread(menu_loop);
jsutton 13:85801e3b83d3 458
jsutton 14:1f961d19f3cf 459 LOG("***** IBM IoT Client Ethernet Example *****\n");
samdanbury 6:37b6d0d56190 460 MQTTEthernet ipstack;
jsutton 14:1f961d19f3cf 461 ethernetInitialising = false;
samdanbury 6:37b6d0d56190 462 MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE> client(ipstack);
icraggs 18:94da9de96d54 463 LOG("Ethernet Initialized\n");
jsutton 13:85801e3b83d3 464
samdanbury 6:37b6d0d56190 465 if (quickstartMode)
icraggs 16:2420bfbf5f1c 466 getMac(ipstack.getEth(), id, sizeof(id));
icraggs 16:2420bfbf5f1c 467
icraggs 16:2420bfbf5f1c 468 attemptConnect(&client, &ipstack);
icraggs 16:2420bfbf5f1c 469
icraggs 16:2420bfbf5f1c 470 if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD)
samdanbury 6:37b6d0d56190 471 {
icraggs 16:2420bfbf5f1c 472 red();
icraggs 16:2420bfbf5f1c 473 while (true)
icraggs 16:2420bfbf5f1c 474 wait(1.0); // Permanent failures - don't retry
samdanbury 6:37b6d0d56190 475 }
icraggs 16:2420bfbf5f1c 476
samdanbury 6:37b6d0d56190 477 if (!quickstartMode)
samdanbury 6:37b6d0d56190 478 {
samdanbury 6:37b6d0d56190 479 int rc = 0;
samdanbury 6:37b6d0d56190 480 if ((rc = client.subscribe("iot-2/cmd/+/fmt/json", MQTT::QOS1, messageArrived)) != 0)
samdanbury 6:37b6d0d56190 481 WARN("rc from MQTT subscribe is %d\n", rc);
samdanbury 6:37b6d0d56190 482 }
samdanbury 6:37b6d0d56190 483
samdanbury 6:37b6d0d56190 484 blink_interval = 0;
samdanbury 6:37b6d0d56190 485 int count = 0;
samdanbury 6:37b6d0d56190 486 while (true)
samdanbury 6:37b6d0d56190 487 {
samdanbury 6:37b6d0d56190 488 if (++count == 100)
samdanbury 6:37b6d0d56190 489 { // Publish a message every second
samdanbury 6:37b6d0d56190 490 if (publish(&client, &ipstack) != 0)
samdanbury 6:37b6d0d56190 491 attemptConnect(&client, &ipstack); // if we have lost the connection
samdanbury 6:37b6d0d56190 492 count = 0;
samdanbury 6:37b6d0d56190 493 }
samdanbury 6:37b6d0d56190 494
samdanbury 6:37b6d0d56190 495 if (blink_interval == 0)
samdanbury 6:37b6d0d56190 496 led2 = LED2_OFF;
samdanbury 6:37b6d0d56190 497 else if (count % blink_interval == 0)
samdanbury 6:37b6d0d56190 498 led2 = !led2;
samdanbury 6:37b6d0d56190 499 client.yield(10); // allow the MQTT client to receive messages
samdanbury 6:37b6d0d56190 500 }
samdanbury 6:37b6d0d56190 501 }