GDP group 24 node core

Dependencies:   EthernetInterface SDFileSystem mbed-rtos mbed snail MbedJSONValue

Committer:
Trumple
Date:
Tue Jan 13 23:51:35 2015 +0000
Revision:
21:a32666afce7a
Parent:
15:1d98f45717bc
Child:
23:b57a47c7862a
Fix payload size parameter used when sending sensordata messages

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