Example program to create IoT devices for a local network, which connect to a local server.

Dependencies:   WebSocketClient WiflyInterface mbed messages

This code is used in the second part of my Internet of Things (IoT) blog post available here. The code is fairly simple, but its real value is in its reliability. I have worked hard to try to make the wireless connection as reliable, and as fast, as possible. There are a few lines of code that must be modified before it will work correctly, and those are described in the following Wiki pages.

It is designed to work with a Python WebSocket Server running on a PC, the source code of which is available here.

Once operating with the server, each microcontroller, or IoT device, will broadcast a counter and its internal temperature to your WebSocket Server.

Committer:
defrost
Date:
Thu Oct 06 08:04:34 2016 +0000
Revision:
6:424e225d2a91
Parent:
5:0c7d131e6089
Child:
7:bd21c60b5dd2
- Updated comments

Who changed what in which revision?

UserRevisionLine numberNew contents of line
defrost 5:0c7d131e6089 1 /**
defrost 5:0c7d131e6089 2 * @author Damien Frost
defrost 5:0c7d131e6089 3 *
defrost 5:0c7d131e6089 4 * @section LICENSE
defrost 5:0c7d131e6089 5 *
defrost 5:0c7d131e6089 6 * Copyright (c) 2016 Damien Frost
defrost 5:0c7d131e6089 7 *
defrost 5:0c7d131e6089 8 * Permission is hereby granted, free of charge, to any person obtaining a copy
defrost 5:0c7d131e6089 9 * of this software and associated documentation files (the "Software"), to deal
defrost 5:0c7d131e6089 10 * in the Software without restriction, including without limitation the rights
defrost 5:0c7d131e6089 11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
defrost 5:0c7d131e6089 12 * copies of the Software, and to permit persons to whom the Software is
defrost 5:0c7d131e6089 13 * furnished to do so, subject to the following conditions:
defrost 5:0c7d131e6089 14 *
defrost 5:0c7d131e6089 15 * The above copyright notice and this permission notice shall be included in
defrost 5:0c7d131e6089 16 * all copies or substantial portions of the Software.
defrost 5:0c7d131e6089 17 *
defrost 5:0c7d131e6089 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
defrost 5:0c7d131e6089 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
defrost 5:0c7d131e6089 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
defrost 5:0c7d131e6089 21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
defrost 5:0c7d131e6089 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
defrost 5:0c7d131e6089 23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
defrost 5:0c7d131e6089 24 * THE SOFTWARE.
defrost 5:0c7d131e6089 25 *
defrost 5:0c7d131e6089 26 * @file "globals.cpp"
defrost 5:0c7d131e6089 27 *
defrost 5:0c7d131e6089 28 * @section DESCRIPTION
defrost 5:0c7d131e6089 29 * Global definitions for the IoT example program.
defrost 5:0c7d131e6089 30 *
defrost 5:0c7d131e6089 31 */
defrost 1:4403f2ed1c1f 32
defrost 1:4403f2ed1c1f 33 #include "mbed.h"
defrost 1:4403f2ed1c1f 34 #include "globals.h"
defrost 1:4403f2ed1c1f 35
defrost 1:4403f2ed1c1f 36 //#define DEBUG
defrost 1:4403f2ed1c1f 37 #define INFOMESSAGES
defrost 1:4403f2ed1c1f 38 #define WARNMESSAGES
defrost 1:4403f2ed1c1f 39 #define ERRMESSAGES
defrost 1:4403f2ed1c1f 40 #define FUNCNAME "GBL"
defrost 1:4403f2ed1c1f 41 #include "messages.h"
defrost 1:4403f2ed1c1f 42
defrost 5:0c7d131e6089 43 // Hardware declarations:
defrost 1:4403f2ed1c1f 44 Serial pc(USBTX, USBRX);
defrost 1:4403f2ed1c1f 45 InterruptIn UIBut1(USER_BUTTON);
defrost 1:4403f2ed1c1f 46 Timer DisplayTimer;
defrost 2:7abdaa5a9209 47 DigitalOut Led(LED1);
defrost 1:4403f2ed1c1f 48
defrost 5:0c7d131e6089 49 // Global variable declarations:
defrost 1:4403f2ed1c1f 50 int ReconnectAttempts = 0;
defrost 1:4403f2ed1c1f 51 int SendCounter = 0;
defrost 1:4403f2ed1c1f 52 extern int IoT_ID = 0;
defrost 1:4403f2ed1c1f 53 float TempSensor = 0.0f;
defrost 6:424e225d2a91 54 char* wifissid = "SC";
defrost 6:424e225d2a91 55 char* wifipassword = "smartcellshield";
defrost 1:4403f2ed1c1f 56
defrost 5:0c7d131e6089 57 // Wifily interface declaration:
defrost 5:0c7d131e6089 58 WiflyInterface eth(D8, D2, D6, D5, wifissid, wifipassword, WPA2);
defrost 5:0c7d131e6089 59 // WebSocket declaration:
defrost 1:4403f2ed1c1f 60 Websocket ws;
defrost 1:4403f2ed1c1f 61
defrost 1:4403f2ed1c1f 62
defrost 1:4403f2ed1c1f 63 int SetupNetwork(int Tries){
defrost 1:4403f2ed1c1f 64 // Initialize the interface.
defrost 1:4403f2ed1c1f 65 // If no param is passed to init() then DHCP will be used on connect()
defrost 1:4403f2ed1c1f 66 int s = eth.init();
defrost 1:4403f2ed1c1f 67 int attempts = 1;
defrost 1:4403f2ed1c1f 68
defrost 1:4403f2ed1c1f 69 wait(1);
defrost 1:4403f2ed1c1f 70 if (s != NULL) {
defrost 1:4403f2ed1c1f 71 ERR("Could not initialise. Halting!");
defrost 1:4403f2ed1c1f 72 exit(0);
defrost 1:4403f2ed1c1f 73 }
defrost 1:4403f2ed1c1f 74
defrost 1:4403f2ed1c1f 75 INFO("Connecting to: %s", wifissid);
defrost 1:4403f2ed1c1f 76 DBG("Getting IP address...");
defrost 1:4403f2ed1c1f 77
defrost 1:4403f2ed1c1f 78 while (1) {
defrost 1:4403f2ed1c1f 79 // Connect to network:
defrost 1:4403f2ed1c1f 80 s = eth.connect();
defrost 1:4403f2ed1c1f 81 // If connection fails, retry for 5 attempts:
defrost 1:4403f2ed1c1f 82 if (s == false || s < 0) {
defrost 1:4403f2ed1c1f 83 INFO("Could not connect to network. Retrying!");
defrost 1:4403f2ed1c1f 84 attempts++;
defrost 1:4403f2ed1c1f 85 wait(1);
defrost 1:4403f2ed1c1f 86 } else {
defrost 1:4403f2ed1c1f 87
defrost 1:4403f2ed1c1f 88 break;
defrost 1:4403f2ed1c1f 89 }
defrost 1:4403f2ed1c1f 90 if(attempts > Tries){
defrost 1:4403f2ed1c1f 91 ERR("Network connection failed after %d attempts", Tries);
defrost 1:4403f2ed1c1f 92 return 0;
defrost 1:4403f2ed1c1f 93 }
defrost 1:4403f2ed1c1f 94 }
defrost 1:4403f2ed1c1f 95 INFO("Connected to: %s", wifissid);
defrost 1:4403f2ed1c1f 96 INFO("Got IP address: %s", eth.getIPAddress());
defrost 1:4403f2ed1c1f 97 IotStatus.SetFlag(SF_WIRELESSCONNECTED);
defrost 1:4403f2ed1c1f 98 return 1;
defrost 1:4403f2ed1c1f 99
defrost 1:4403f2ed1c1f 100 }
defrost 1:4403f2ed1c1f 101
defrost 1:4403f2ed1c1f 102 void SendNetworkData(void){
defrost 1:4403f2ed1c1f 103 char msg_buffer[CHARMSGBUFF];
defrost 1:4403f2ed1c1f 104 int intresult;
defrost 1:4403f2ed1c1f 105
defrost 1:4403f2ed1c1f 106 if(IotStatus.CheckFlag(SF_SERVERCONNECTED)){
defrost 1:4403f2ed1c1f 107 sprintf(msg_buffer, "%d,%d,%.5f", IoT_ID, SendCounter,TempSensor);
defrost 1:4403f2ed1c1f 108 INFO("Sending: %s", msg_buffer); // When this line is commented out, the mbed never tries to reconnect to the server after one try. SUPER. Keeping this here also uses precious CPU time
defrost 1:4403f2ed1c1f 109 intresult = ws.send(msg_buffer);
defrost 1:4403f2ed1c1f 110 }else{
defrost 1:4403f2ed1c1f 111 intresult = -1;
defrost 1:4403f2ed1c1f 112 }
defrost 1:4403f2ed1c1f 113 DBG("intresult: %d", intresult);
defrost 1:4403f2ed1c1f 114
defrost 1:4403f2ed1c1f 115 if(intresult < 0){
defrost 1:4403f2ed1c1f 116 // Clear a status flag:
defrost 1:4403f2ed1c1f 117 IotStatus.ClearFlag(SF_SERVERCONNECTED);
defrost 1:4403f2ed1c1f 118 // Check to see if the wireless is still connected:
defrost 1:4403f2ed1c1f 119 DBG("Checking network status...");
defrost 1:4403f2ed1c1f 120 if(eth.checkNetworkStatus() != 3){
defrost 1:4403f2ed1c1f 121 IotStatus.ClearFlag(SF_WIRELESSCONNECTED);
defrost 1:4403f2ed1c1f 122 // Connect to the wireless network:
defrost 1:4403f2ed1c1f 123 if(IotStatus.CheckFlag(SF_AUTOCONNECT)){
defrost 1:4403f2ed1c1f 124 INFO("Reconnecting to Network...");
defrost 1:4403f2ed1c1f 125 if(SetupNetwork(1)>0){
defrost 1:4403f2ed1c1f 126 IotStatus.SetFlag(SF_WIRELESSCONNECTED);
defrost 1:4403f2ed1c1f 127 INFO("Connected to Network.");
defrost 1:4403f2ed1c1f 128 }else{
defrost 1:4403f2ed1c1f 129 WARN("Could not re-connect to the wireless network.");
defrost 1:4403f2ed1c1f 130 }
defrost 1:4403f2ed1c1f 131 }
defrost 1:4403f2ed1c1f 132 }else{
defrost 1:4403f2ed1c1f 133 DBG("Network connected.");
defrost 1:4403f2ed1c1f 134 }
defrost 1:4403f2ed1c1f 135
defrost 1:4403f2ed1c1f 136 if(IotStatus.CheckFlag(SF_AUTOCONNECT) && IotStatus.CheckFlag(SF_WIRELESSCONNECTED)){
defrost 1:4403f2ed1c1f 137 // Server connection was closed, try to reconnect:
defrost 1:4403f2ed1c1f 138 INFO("Reconnecting to Websocket Server on ws://%s:%d/ws...", SERVER_IP, WS_PORT);
defrost 1:4403f2ed1c1f 139 if(!ws.connect()){
defrost 1:4403f2ed1c1f 140 WARN("Could not connect to the server again...");
defrost 1:4403f2ed1c1f 141 IotStatus.ClearFlag(SF_SERVERCONNECTED);
defrost 1:4403f2ed1c1f 142 ReconnectAttempts++;
defrost 1:4403f2ed1c1f 143 if(ReconnectAttempts > 4){
defrost 1:4403f2ed1c1f 144 INFO("Failed after %d reconnect attempts. Resetting the Wifi Shield...", ReconnectAttempts);
defrost 1:4403f2ed1c1f 145 SetupNetwork(1);
defrost 1:4403f2ed1c1f 146 ReconnectAttempts = 0;
defrost 1:4403f2ed1c1f 147 }
defrost 1:4403f2ed1c1f 148 }else{
defrost 1:4403f2ed1c1f 149 INFO("Connected to ws://%s:%d/ws", SERVER_IP, WS_PORT);
defrost 1:4403f2ed1c1f 150 // Set a status flag:
defrost 1:4403f2ed1c1f 151 IotStatus.SetFlag(SF_SERVERCONNECTED);
defrost 1:4403f2ed1c1f 152 }
defrost 1:4403f2ed1c1f 153 }
defrost 1:4403f2ed1c1f 154 }
defrost 1:4403f2ed1c1f 155
defrost 1:4403f2ed1c1f 156 return;
defrost 1:4403f2ed1c1f 157 }
defrost 1:4403f2ed1c1f 158
defrost 5:0c7d131e6089 159 void ReceiveNetworkData(unsigned int * wifi_cmd, float * value){
defrost 1:4403f2ed1c1f 160 char msg_buffer[CHARMSGBUFF];
defrost 1:4403f2ed1c1f 161 char msg_buffer2[CHARMSGBUFF];
defrost 2:7abdaa5a9209 162 int resp;
defrost 2:7abdaa5a9209 163 if(IotStatus.CheckFlag(SF_SERVERCONNECTED)){
defrost 2:7abdaa5a9209 164 // Check for data on the websocket:
defrost 2:7abdaa5a9209 165 resp = ws.readmsg(msg_buffer);
defrost 2:7abdaa5a9209 166 if(resp == 1){
defrost 2:7abdaa5a9209 167 INFO("Received: %s", msg_buffer);
defrost 2:7abdaa5a9209 168 sscanf(msg_buffer, "%d,%s", wifi_cmd, msg_buffer2);
defrost 5:0c7d131e6089 169 if(*wifi_cmd == CV_LED_WIFI_CMD){
defrost 3:f20e114eb2ee 170 // Get one more value:
defrost 2:7abdaa5a9209 171 sscanf(msg_buffer2, "%f", value);
defrost 2:7abdaa5a9209 172 }
defrost 2:7abdaa5a9209 173 }else if(resp == -1){
defrost 2:7abdaa5a9209 174 // Connection to the server is lost:
defrost 2:7abdaa5a9209 175 IotStatus.ClearFlag(SF_SERVERCONNECTED);
defrost 1:4403f2ed1c1f 176 }else{
defrost 2:7abdaa5a9209 177 //DBG("Did not receive anything :(\n\r");
defrost 2:7abdaa5a9209 178 *wifi_cmd = NO_WIFI_CMD;
defrost 2:7abdaa5a9209 179 *value = 0.0f;
defrost 1:4403f2ed1c1f 180 }
defrost 1:4403f2ed1c1f 181 }
defrost 1:4403f2ed1c1f 182 return;
defrost 1:4403f2ed1c1f 183 }
defrost 1:4403f2ed1c1f 184
defrost 1:4403f2ed1c1f 185 void ModifyVariable(unsigned int wifi_var, float wifi_data){
defrost 1:4403f2ed1c1f 186 // modifies something in the SCS Controller:
defrost 1:4403f2ed1c1f 187 switch(wifi_var){
defrost 1:4403f2ed1c1f 188 case CV_LED:
defrost 3:f20e114eb2ee 189 if(wifi_data > 0){
defrost 3:f20e114eb2ee 190 Led = 1;
defrost 3:f20e114eb2ee 191 }else{
defrost 3:f20e114eb2ee 192 Led = 0;
defrost 3:f20e114eb2ee 193 }
defrost 1:4403f2ed1c1f 194 break;
defrost 1:4403f2ed1c1f 195
defrost 1:4403f2ed1c1f 196 default:
defrost 1:4403f2ed1c1f 197 break;
defrost 1:4403f2ed1c1f 198 }
defrost 1:4403f2ed1c1f 199 return;
defrost 1:4403f2ed1c1f 200 }
defrost 1:4403f2ed1c1f 201
defrost 1:4403f2ed1c1f 202
defrost 1:4403f2ed1c1f 203