GDP group 24 node core

Dependencies:   EthernetInterface SDFileSystem mbed-rtos mbed snail MbedJSONValue

Committer:
jakehodges
Date:
Tue Jan 27 22:20:46 2015 +0000
Revision:
23:b57a47c7862a
Parent:
21:a32666afce7a
Child:
25:fe273397ebb2
Update JSON message to server to include int array. Update sensordata message to reflect changes in SNAIL. Fix SD card location string. Fix I2C id conflict.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Trumple 0:fcab3b154e49 1 #include "mbed.h"
Trumple 0:fcab3b154e49 2 #include "snail.h"
Trumple 0:fcab3b154e49 3 #include "sensorinterface.h"
Trumple 0:fcab3b154e49 4 #include "sdcard.h"
Trumple 1:27b35752c5d0 5 #include "http.h"
Trumple 2:1cbb20dd1733 6 #include "MbedJSONValue.h"
Trumple 8:fd531fe7637b 7 #include <map>
Trumple 0:fcab3b154e49 8
Trumple 0:fcab3b154e49 9 #define DEBUG
Trumple 0:fcab3b154e49 10
Trumple 0:fcab3b154e49 11 time_t lastPollTime = 0;
Trumple 0:fcab3b154e49 12 time_t pollInterval = 30;
Trumple 2:1cbb20dd1733 13
Trumple 0:fcab3b154e49 14
jakehodges 23:b57a47c7862a 15 bool isBasenode = false;
Trumple 10:13176e7bd4c8 16 string fieldID = "testfield";
Trumple 10:13176e7bd4c8 17
Trumple 2:1cbb20dd1733 18 http h = http();
Trumple 8:fd531fe7637b 19 sensorinterface* sif;
Trumple 8:fd531fe7637b 20
Trumple 1:27b35752c5d0 21 char localAddress[8];
Trumple 2:1cbb20dd1733 22 char baseNodeAddress[8];
Trumple 1:27b35752c5d0 23 bool networkParametersUpdated = false;
Trumple 1:27b35752c5d0 24 bool networkParametersTimedOut = false;
Trumple 0:fcab3b154e49 25
Trumple 0:fcab3b154e49 26 Serial pc(USBTX, USBRX);
Trumple 1:27b35752c5d0 27 snail xbee = snail();
Trumple 1:27b35752c5d0 28 Ticker networkParametersTimeout;
Trumple 0:fcab3b154e49 29
jakehodges 6:92ddc620a78f 30 queue<snail::sensordata> messageQueue;
jakehodges 6:92ddc620a78f 31
Trumple 10:13176e7bd4c8 32 string addressToString(char address[8])
Trumple 10:13176e7bd4c8 33 {
Trumple 10:13176e7bd4c8 34 string address_str;
Trumple 10:13176e7bd4c8 35 for(int i = 0; i < 8; i++)
Trumple 10:13176e7bd4c8 36 {
Trumple 10:13176e7bd4c8 37 char addressBuffer[2];
Trumple 10:13176e7bd4c8 38 sprintf(addressBuffer, "%.2X", address[i]);
Trumple 10:13176e7bd4c8 39 address_str += string(addressBuffer, 2);
Trumple 10:13176e7bd4c8 40 }
Trumple 10:13176e7bd4c8 41
Trumple 10:13176e7bd4c8 42 return address_str;
Trumple 10:13176e7bd4c8 43 }
Trumple 10:13176e7bd4c8 44
Trumple 2:1cbb20dd1733 45 void handleJoinNetworkReply(snail::message& message)
Trumple 1:27b35752c5d0 46 {
Trumple 2:1cbb20dd1733 47 pc.printf("[MAIN] Got join network reply...\r\n");
Trumple 2:1cbb20dd1733 48 snail::joinnetworkreply& reply = static_cast<snail::joinnetworkreply&>(message);
Trumple 2:1cbb20dd1733 49 set_time(reply.timestamp);
Trumple 2:1cbb20dd1733 50 memcpy(baseNodeAddress, reply.baseNodeAddress, sizeof(baseNodeAddress));
Trumple 2:1cbb20dd1733 51
Trumple 1:27b35752c5d0 52 networkParametersUpdated = true;
Trumple 1:27b35752c5d0 53 }
Trumple 1:27b35752c5d0 54
Trumple 2:1cbb20dd1733 55 void handleJoinNetworkRequest(snail::message& message)
Trumple 0:fcab3b154e49 56 {
Trumple 2:1cbb20dd1733 57 pc.printf("[MAIN] Got join network request...\r\n");
Trumple 1:27b35752c5d0 58 if (isBasenode)
Trumple 1:27b35752c5d0 59 {
Trumple 2:1cbb20dd1733 60 snail::joinnetworkrequest& request = static_cast<snail::joinnetworkrequest&>(message);
Trumple 2:1cbb20dd1733 61
Trumple 10:13176e7bd4c8 62 //report connected sensors to server
Trumple 10:13176e7bd4c8 63 MbedJSONValue j;
Trumple 10:13176e7bd4c8 64 j["sensors"];
Trumple 10:13176e7bd4c8 65 for (int i = 0; i < request.sensorCount; i++)
Trumple 10:13176e7bd4c8 66 {
Trumple 10:13176e7bd4c8 67 char sensorIDBuffer[3];
Trumple 10:13176e7bd4c8 68 sprintf(sensorIDBuffer, "%i", request.sensors[i].id);
Trumple 10:13176e7bd4c8 69 char fBuffer[3];
Trumple 10:13176e7bd4c8 70 sprintf(fBuffer, "%i", request.sensors[i].type);
Trumple 10:13176e7bd4c8 71 j["sensors"][i]["sensorID"] = string(sensorIDBuffer);
Trumple 10:13176e7bd4c8 72 j["sensors"][i]["sensortype"] = string(fBuffer);
Trumple 10:13176e7bd4c8 73 }
Trumple 10:13176e7bd4c8 74
Trumple 10:13176e7bd4c8 75 string address = addressToString(request.source);
Trumple 10:13176e7bd4c8 76 #ifdef DEBUG
Trumple 10:13176e7bd4c8 77 pc.printf( ("[MAIN] POSTing startup information: " + j.serialize() + "\r\n").c_str() );
Trumple 10:13176e7bd4c8 78 #endif
Trumple 10:13176e7bd4c8 79 h.post("178.62.84.55", 8888, "/field/" + fieldID + "/" + address + "/startup/", j.serialize()).c_str();
Trumple 10:13176e7bd4c8 80
Trumple 2:1cbb20dd1733 81 snail::joinnetworkreply reply(request.source, time(NULL), localAddress);
Trumple 1:27b35752c5d0 82 xbee.send(reply, sizeof(reply));
Trumple 1:27b35752c5d0 83 }
Trumple 1:27b35752c5d0 84 }
Trumple 1:27b35752c5d0 85
Trumple 2:1cbb20dd1733 86 void handleSensorData(snail::message& message)
Trumple 2:1cbb20dd1733 87 {
Trumple 2:1cbb20dd1733 88 pc.printf("[MAIN] Got sensor data...\r\n");
Trumple 2:1cbb20dd1733 89 snail::sensordata& d = static_cast<snail::sensordata&>(message);
Trumple 2:1cbb20dd1733 90
Trumple 10:13176e7bd4c8 91 char sensorID[3];
Trumple 10:13176e7bd4c8 92 sprintf(sensorID, "%i", d.i2cAddress);
Trumple 10:13176e7bd4c8 93
Trumple 4:0bab12a0cc9a 94 MbedJSONValue j;
Trumple 4:0bab12a0cc9a 95 j["timestamp"] = (int)time(NULL);
jakehodges 23:b57a47c7862a 96
jakehodges 23:b57a47c7862a 97 for (int i = 0; i < d.payloadSize; i++)
jakehodges 23:b57a47c7862a 98 j["value"][i] = d.payload[i];
Trumple 10:13176e7bd4c8 99
Trumple 10:13176e7bd4c8 100 #ifdef DEBUG
Trumple 10:13176e7bd4c8 101 pc.printf( ("[MAIN] POSTing sensor reading: " + j.serialize() + "\r\n").c_str() );
Trumple 10:13176e7bd4c8 102 #endif
Trumple 10:13176e7bd4c8 103
Trumple 10:13176e7bd4c8 104 h.post("178.62.84.55", 8888, "/field/" + fieldID + "/" + addressToString(d.source) + "/" + sensorID + "/", j.serialize()).c_str();
Trumple 2:1cbb20dd1733 105 }
Trumple 2:1cbb20dd1733 106
Trumple 1:27b35752c5d0 107 void handleNetworkParametersTimeout()
Trumple 1:27b35752c5d0 108 {
Trumple 1:27b35752c5d0 109 networkParametersTimedOut = true;
Trumple 1:27b35752c5d0 110 }
Trumple 1:27b35752c5d0 111
Trumple 1:27b35752c5d0 112 void getLocalAddress()
Trumple 1:27b35752c5d0 113 {
Trumple 2:1cbb20dd1733 114 pc.printf("[MAIN] Requesting lower address bits...\r\n");
Trumple 2:1cbb20dd1733 115 xbee.ATCommand("SL");
Trumple 2:1cbb20dd1733 116
Trumple 2:1cbb20dd1733 117 while (!xbee.isATCommandResponseWaiting())
Trumple 2:1cbb20dd1733 118 xbee.processIncomingData();
Trumple 2:1cbb20dd1733 119
Trumple 2:1cbb20dd1733 120 snail::atcommandresponse SLr = xbee.getATCommandResponse();
Trumple 2:1cbb20dd1733 121
Trumple 2:1cbb20dd1733 122 pc.printf("[MAIN] Requesting upper address bits...\r\n");
Trumple 2:1cbb20dd1733 123 xbee.ATCommand("SH");
Trumple 2:1cbb20dd1733 124
Trumple 2:1cbb20dd1733 125 while (!xbee.isATCommandResponseWaiting())
Trumple 2:1cbb20dd1733 126 xbee.processIncomingData();
Trumple 2:1cbb20dd1733 127
Trumple 2:1cbb20dd1733 128 snail::atcommandresponse SHr = xbee.getATCommandResponse();
Trumple 2:1cbb20dd1733 129
Trumple 2:1cbb20dd1733 130 string address(SHr.response);
Trumple 2:1cbb20dd1733 131 address += SLr.response;
Trumple 2:1cbb20dd1733 132
Trumple 2:1cbb20dd1733 133 pc.printf("[MAIN] Got local address: ");
Trumple 2:1cbb20dd1733 134
Trumple 2:1cbb20dd1733 135 for (int i = 0; i < address.size(); i++)
Trumple 2:1cbb20dd1733 136 pc.printf("%.2X", address[i]);
Trumple 2:1cbb20dd1733 137
Trumple 2:1cbb20dd1733 138 pc.printf("\r\n");
Trumple 2:1cbb20dd1733 139
Trumple 2:1cbb20dd1733 140 memcpy(localAddress, address.c_str(), sizeof(localAddress));
Trumple 1:27b35752c5d0 141 }
Trumple 1:27b35752c5d0 142
Trumple 1:27b35752c5d0 143 void getNetworkParameters()
Trumple 1:27b35752c5d0 144 {
Trumple 1:27b35752c5d0 145 #ifdef DEBUG
Trumple 2:1cbb20dd1733 146 pc.printf("[MAIN] Requesting to join network...\r\n");
Trumple 1:27b35752c5d0 147 #endif
Trumple 0:fcab3b154e49 148
Trumple 8:fd531fe7637b 149 //prepare for response from basenode
Trumple 2:1cbb20dd1733 150 xbee.registerMessageCallback(MESSAGE_JOIN_NETWORK_REPLY, handleJoinNetworkReply);
Trumple 2:1cbb20dd1733 151
Trumple 8:fd531fe7637b 152 //handle retrying after timeout
Trumple 2:1cbb20dd1733 153 networkParametersTimeout.attach(&handleNetworkParametersTimeout, 30.0);
Trumple 1:27b35752c5d0 154
Trumple 8:fd531fe7637b 155 //generate list of sensors attached
Trumple 8:fd531fe7637b 156 snail::joinnetworkrequest::sensor localSensors[32];
Trumple 8:fd531fe7637b 157 map<char, sensor>::iterator cs = sif->sensors.begin();
Trumple 8:fd531fe7637b 158 int i = 0;
Trumple 8:fd531fe7637b 159
Trumple 8:fd531fe7637b 160 //either loop until we reach the end of the sensors or until we hit the max
Trumple 8:fd531fe7637b 161 while (cs != sif->sensors.end() && i < 32)
Trumple 8:fd531fe7637b 162 {
Trumple 8:fd531fe7637b 163 localSensors[i].type = cs->second.type;
jakehodges 23:b57a47c7862a 164 localSensors[i].id = cs->second.type;
Trumple 8:fd531fe7637b 165 i++;
Trumple 8:fd531fe7637b 166 cs++;
Trumple 8:fd531fe7637b 167 }
Trumple 8:fd531fe7637b 168
Trumple 8:fd531fe7637b 169 #ifdef DEBUG
Trumple 8:fd531fe7637b 170 pc.printf("[MAIN] Informing basenode of %i attached devices\r\n", i);
Trumple 8:fd531fe7637b 171 #endif
Trumple 8:fd531fe7637b 172
Trumple 8:fd531fe7637b 173 //construct joinnetworkrequest, including the number of sensors attached
Trumple 8:fd531fe7637b 174 snail::joinnetworkrequest request(localSensors, i);
Trumple 1:27b35752c5d0 175
Trumple 1:27b35752c5d0 176 xbee.send(request, sizeof(request));
Trumple 0:fcab3b154e49 177
Trumple 1:27b35752c5d0 178 while(!networkParametersUpdated)
Trumple 1:27b35752c5d0 179 {
Trumple 1:27b35752c5d0 180 if (networkParametersTimedOut)
Trumple 1:27b35752c5d0 181 {
Trumple 1:27b35752c5d0 182 #ifdef DEBUG
Trumple 1:27b35752c5d0 183 pc.printf("[MAIN] Timed out, retrying...\r\n");
Trumple 1:27b35752c5d0 184 #endif
Trumple 1:27b35752c5d0 185 xbee.send(request, sizeof(request));
Trumple 1:27b35752c5d0 186 networkParametersTimedOut = false;
Trumple 1:27b35752c5d0 187 }
Trumple 2:1cbb20dd1733 188 xbee.processIncomingData();
Trumple 1:27b35752c5d0 189 }
Trumple 0:fcab3b154e49 190
Trumple 1:27b35752c5d0 191 #ifdef DEBUG
Trumple 2:1cbb20dd1733 192 pc.printf("[MAIN] Got network parameters. Time: %i, base node address: ", time(NULL));
Trumple 2:1cbb20dd1733 193
Trumple 2:1cbb20dd1733 194 for (int i = 0; i < sizeof(baseNodeAddress); i++)
Trumple 2:1cbb20dd1733 195 pc.printf("%.2X", baseNodeAddress[i]);
Trumple 2:1cbb20dd1733 196 pc.printf("\r\n");
Trumple 1:27b35752c5d0 197 #endif
Trumple 8:fd531fe7637b 198 //no longer need to handle timeout
Trumple 1:27b35752c5d0 199 networkParametersTimeout.detach();
Trumple 0:fcab3b154e49 200 }
Trumple 0:fcab3b154e49 201
Trumple 0:fcab3b154e49 202 int main()
Trumple 0:fcab3b154e49 203 {
Trumple 0:fcab3b154e49 204 #ifdef DEBUG
Trumple 0:fcab3b154e49 205 pc.printf("[MAIN] Starting up...\r\n");
Trumple 2:1cbb20dd1733 206 pc.printf(" . .\r\n");
Trumple 2:1cbb20dd1733 207 pc.printf(" / `. .' \\\r\n");
Trumple 2:1cbb20dd1733 208 pc.printf(" .---. < > < > .---.\r\n");
Trumple 2:1cbb20dd1733 209 pc.printf(" | \\ \\ - ~ ~ - / / |\r\n");
Trumple 2:1cbb20dd1733 210 pc.printf(" ~-..-~ ~-..-~\r\n");
Trumple 2:1cbb20dd1733 211 pc.printf(" \\~~~\\.' `./~~~/\r\n");
Trumple 2:1cbb20dd1733 212 pc.printf(" .-~~^-. \\__/ \\__/\r\n");
Trumple 2:1cbb20dd1733 213 pc.printf(" .' O \\ / / \\ \\\r\n");
Trumple 2:1cbb20dd1733 214 pc.printf("(_____, `._.' | } \\/~~~/\r\n");
Trumple 2:1cbb20dd1733 215 pc.printf(" `----. / } | / \\__/\r\n");
Trumple 2:1cbb20dd1733 216 pc.printf(" `-. | / | / `. ,~~|\r\n");
Trumple 2:1cbb20dd1733 217 pc.printf(" ~-.__| /_ - ~ ^| /- _ `..-' f: f:\r\n");
Trumple 2:1cbb20dd1733 218 pc.printf(" | / | / ~-. `-. _||_||_\r\n");
Trumple 2:1cbb20dd1733 219 pc.printf(" |_____| |_____| ~ - . _ _ _ _ _>\r\n");
Trumple 2:1cbb20dd1733 220 pc.printf("\r\n");
Trumple 2:1cbb20dd1733 221 pc.printf("\r\n");
Trumple 2:1cbb20dd1733 222 pc.printf(" Sensorsaurus | Team 24 GDP | Southampton | 2014\r\n");
Trumple 2:1cbb20dd1733 223 pc.printf("\r\n");
Trumple 2:1cbb20dd1733 224 pc.printf("\r\n");
Trumple 0:fcab3b154e49 225 #endif
jakehodges 23:b57a47c7862a 226 sdcard sd = sdcard();
Trumple 0:fcab3b154e49 227
Trumple 0:fcab3b154e49 228 //TODO: read basenode pin
Trumple 0:fcab3b154e49 229 #ifdef DEBUG
Trumple 0:fcab3b154e49 230 pc.printf("[MAIN] Basenode switch: %i\r\n", isBasenode);
Trumple 0:fcab3b154e49 231 #endif
Trumple 0:fcab3b154e49 232
Trumple 0:fcab3b154e49 233 //TODO: load configuration from SD
Trumple 0:fcab3b154e49 234
Trumple 2:1cbb20dd1733 235 getLocalAddress();
Trumple 2:1cbb20dd1733 236
Trumple 0:fcab3b154e49 237 if (isBasenode)
Trumple 1:27b35752c5d0 238 {
Trumple 2:1cbb20dd1733 239 h.connect();
Trumple 2:1cbb20dd1733 240
Trumple 2:1cbb20dd1733 241 string timestampStr = h.get("time.bitnode.co.uk", 80, "/");
Trumple 2:1cbb20dd1733 242 time_t timestamp = atoi(timestampStr.c_str());
Trumple 2:1cbb20dd1733 243
Trumple 1:27b35752c5d0 244 set_time(timestamp);
Trumple 1:27b35752c5d0 245
Trumple 2:1cbb20dd1733 246 pc.printf("[MAIN] Got time: %i\r\n", timestamp);
Trumple 2:1cbb20dd1733 247
Trumple 2:1cbb20dd1733 248 xbee.registerMessageCallback(MESSAGE_JOIN_NETWORK_REQUEST, handleJoinNetworkRequest);
Trumple 2:1cbb20dd1733 249 xbee.registerMessageCallback(MESSAGE_SENSOR_DATA, handleSensorData);
Trumple 1:27b35752c5d0 250
Trumple 0:fcab3b154e49 251 while(1)
Trumple 0:fcab3b154e49 252 {
Trumple 0:fcab3b154e49 253 #ifdef DEBUG
Trumple 0:fcab3b154e49 254 pc.printf("[MAIN] Basenode is idle\r\n");
Trumple 0:fcab3b154e49 255 #endif
Trumple 0:fcab3b154e49 256
Trumple 2:1cbb20dd1733 257 wait(1);
Trumple 2:1cbb20dd1733 258 xbee.processIncomingData();
Trumple 0:fcab3b154e49 259 }
Trumple 1:27b35752c5d0 260 }
Trumple 0:fcab3b154e49 261 else
Trumple 8:fd531fe7637b 262 {
Trumple 1:27b35752c5d0 263 sensorinterface sensors = sensorinterface();
Trumple 8:fd531fe7637b 264 sif = &sensors;
Trumple 1:27b35752c5d0 265 getNetworkParameters();
Trumple 1:27b35752c5d0 266
Trumple 0:fcab3b154e49 267 while(1)
Trumple 0:fcab3b154e49 268 {
Trumple 2:1cbb20dd1733 269 xbee.processIncomingData();
jakehodges 6:92ddc620a78f 270
jakehodges 6:92ddc620a78f 271 //TODO: if message queue exceeds MAX_QUEUE SIZE, write older readings to SD card.
jakehodges 6:92ddc620a78f 272
jakehodges 6:92ddc620a78f 273 //if xbee is awake send contents of message queue
jakehodges 6:92ddc620a78f 274 if (xbee.isCTS())
jakehodges 6:92ddc620a78f 275 {
jakehodges 6:92ddc620a78f 276 while(!messageQueue.empty())
jakehodges 6:92ddc620a78f 277 {
jakehodges 6:92ddc620a78f 278 snail::sensordata message = messageQueue.front();
jakehodges 6:92ddc620a78f 279 xbee.send(message, sizeof(message));
jakehodges 6:92ddc620a78f 280 messageQueue.pop();
jakehodges 6:92ddc620a78f 281 }
jakehodges 6:92ddc620a78f 282 }
Trumple 0:fcab3b154e49 283
Trumple 4:0bab12a0cc9a 284 //check if it's time to poll
Trumple 2:1cbb20dd1733 285 if (time(NULL) - lastPollTime > pollInterval)
Trumple 0:fcab3b154e49 286 {
Trumple 0:fcab3b154e49 287 #ifdef DEBUG
Trumple 0:fcab3b154e49 288 pc.printf("[MAIN] Requesting data...\r\n");
Trumple 0:fcab3b154e49 289 #endif
Trumple 0:fcab3b154e49 290 sensors.requestData();
Trumple 0:fcab3b154e49 291 lastPollTime = time(NULL);
Trumple 0:fcab3b154e49 292 }
Trumple 0:fcab3b154e49 293
Trumple 0:fcab3b154e49 294 //if there is data waiting for us...
Trumple 0:fcab3b154e49 295 if (sensors.isDataWaiting())
Trumple 0:fcab3b154e49 296 {
Trumple 0:fcab3b154e49 297 #ifdef DEBUG
Trumple 0:fcab3b154e49 298 pc.printf("[MAIN] Data waiting, reading data...\r\n");
Trumple 0:fcab3b154e49 299 #endif
Trumple 1:27b35752c5d0 300
Trumple 0:fcab3b154e49 301 d_reply data = sensors.readData();
Trumple 1:27b35752c5d0 302
Trumple 0:fcab3b154e49 303 #ifdef DEBUG
Trumple 4:0bab12a0cc9a 304 pc.printf("[MAIN] Got data: ");
Trumple 2:1cbb20dd1733 305 for (int i = 0; i < data.readings.size(); i++)
Trumple 21:a32666afce7a 306 pc.printf("0x%.4X|", data.readings[i]);
Trumple 4:0bab12a0cc9a 307 pc.printf("\r\n");
Trumple 0:fcab3b154e49 308 #endif
Trumple 1:27b35752c5d0 309
jakehodges 23:b57a47c7862a 310 int readings[16];
jakehodges 23:b57a47c7862a 311 for (int i = 0; i < data.readings.size(); i++)
jakehodges 23:b57a47c7862a 312 readings[i] = data.readings[i];
Trumple 4:0bab12a0cc9a 313
Trumple 10:13176e7bd4c8 314 //TODO: Get real I2C address
jakehodges 23:b57a47c7862a 315 snail::sensordata message(baseNodeAddress, data.type, data.type, time(NULL), readings, data.readings.size());
Trumple 10:13176e7bd4c8 316
jakehodges 6:92ddc620a78f 317 messageQueue.push(message);
Trumple 4:0bab12a0cc9a 318
Trumple 0:fcab3b154e49 319 //log
jakehodges 23:b57a47c7862a 320 sd.write(static_cast<long int>(time(NULL)), data);
Trumple 0:fcab3b154e49 321 }
Trumple 0:fcab3b154e49 322 }
Trumple 1:27b35752c5d0 323 }
Trumple 0:fcab3b154e49 324 }