GDP group 24 node core
Dependencies: EthernetInterface SDFileSystem mbed-rtos mbed snail MbedJSONValue
main.cpp
- Committer:
- jakehodges
- Date:
- 2015-01-27
- Revision:
- 23:b57a47c7862a
- Parent:
- 21:a32666afce7a
- Child:
- 25:fe273397ebb2
File content as of revision 23:b57a47c7862a:
#include "mbed.h" #include "snail.h" #include "sensorinterface.h" #include "sdcard.h" #include "http.h" #include "MbedJSONValue.h" #include <map> #define DEBUG time_t lastPollTime = 0; time_t pollInterval = 30; bool isBasenode = false; string fieldID = "testfield"; http h = http(); sensorinterface* sif; char localAddress[8]; char baseNodeAddress[8]; bool networkParametersUpdated = false; bool networkParametersTimedOut = false; Serial pc(USBTX, USBRX); snail xbee = snail(); Ticker networkParametersTimeout; queue<snail::sensordata> messageQueue; string addressToString(char address[8]) { string address_str; for(int i = 0; i < 8; i++) { char addressBuffer[2]; sprintf(addressBuffer, "%.2X", address[i]); address_str += string(addressBuffer, 2); } return address_str; } void handleJoinNetworkReply(snail::message& message) { pc.printf("[MAIN] Got join network reply...\r\n"); snail::joinnetworkreply& reply = static_cast<snail::joinnetworkreply&>(message); set_time(reply.timestamp); memcpy(baseNodeAddress, reply.baseNodeAddress, sizeof(baseNodeAddress)); networkParametersUpdated = true; } void handleJoinNetworkRequest(snail::message& message) { pc.printf("[MAIN] Got join network request...\r\n"); if (isBasenode) { snail::joinnetworkrequest& request = static_cast<snail::joinnetworkrequest&>(message); //report connected sensors to server MbedJSONValue j; j["sensors"]; for (int i = 0; i < request.sensorCount; i++) { char sensorIDBuffer[3]; sprintf(sensorIDBuffer, "%i", request.sensors[i].id); char fBuffer[3]; sprintf(fBuffer, "%i", request.sensors[i].type); j["sensors"][i]["sensorID"] = string(sensorIDBuffer); j["sensors"][i]["sensortype"] = string(fBuffer); } string address = addressToString(request.source); #ifdef DEBUG pc.printf( ("[MAIN] POSTing startup information: " + j.serialize() + "\r\n").c_str() ); #endif h.post("178.62.84.55", 8888, "/field/" + fieldID + "/" + address + "/startup/", j.serialize()).c_str(); snail::joinnetworkreply reply(request.source, time(NULL), localAddress); xbee.send(reply, sizeof(reply)); } } void handleSensorData(snail::message& message) { pc.printf("[MAIN] Got sensor data...\r\n"); snail::sensordata& d = static_cast<snail::sensordata&>(message); char sensorID[3]; sprintf(sensorID, "%i", d.i2cAddress); MbedJSONValue j; j["timestamp"] = (int)time(NULL); for (int i = 0; i < d.payloadSize; i++) j["value"][i] = d.payload[i]; #ifdef DEBUG pc.printf( ("[MAIN] POSTing sensor reading: " + j.serialize() + "\r\n").c_str() ); #endif h.post("178.62.84.55", 8888, "/field/" + fieldID + "/" + addressToString(d.source) + "/" + sensorID + "/", j.serialize()).c_str(); } void handleNetworkParametersTimeout() { networkParametersTimedOut = true; } void getLocalAddress() { pc.printf("[MAIN] Requesting lower address bits...\r\n"); xbee.ATCommand("SL"); while (!xbee.isATCommandResponseWaiting()) xbee.processIncomingData(); snail::atcommandresponse SLr = xbee.getATCommandResponse(); pc.printf("[MAIN] Requesting upper address bits...\r\n"); xbee.ATCommand("SH"); while (!xbee.isATCommandResponseWaiting()) xbee.processIncomingData(); snail::atcommandresponse SHr = xbee.getATCommandResponse(); string address(SHr.response); address += SLr.response; pc.printf("[MAIN] Got local address: "); for (int i = 0; i < address.size(); i++) pc.printf("%.2X", address[i]); pc.printf("\r\n"); memcpy(localAddress, address.c_str(), sizeof(localAddress)); } void getNetworkParameters() { #ifdef DEBUG pc.printf("[MAIN] Requesting to join network...\r\n"); #endif //prepare for response from basenode xbee.registerMessageCallback(MESSAGE_JOIN_NETWORK_REPLY, handleJoinNetworkReply); //handle retrying after timeout networkParametersTimeout.attach(&handleNetworkParametersTimeout, 30.0); //generate list of sensors attached snail::joinnetworkrequest::sensor localSensors[32]; map<char, sensor>::iterator cs = sif->sensors.begin(); int i = 0; //either loop until we reach the end of the sensors or until we hit the max while (cs != sif->sensors.end() && i < 32) { localSensors[i].type = cs->second.type; localSensors[i].id = cs->second.type; i++; cs++; } #ifdef DEBUG pc.printf("[MAIN] Informing basenode of %i attached devices\r\n", i); #endif //construct joinnetworkrequest, including the number of sensors attached snail::joinnetworkrequest request(localSensors, i); xbee.send(request, sizeof(request)); while(!networkParametersUpdated) { if (networkParametersTimedOut) { #ifdef DEBUG pc.printf("[MAIN] Timed out, retrying...\r\n"); #endif xbee.send(request, sizeof(request)); networkParametersTimedOut = false; } xbee.processIncomingData(); } #ifdef DEBUG pc.printf("[MAIN] Got network parameters. Time: %i, base node address: ", time(NULL)); for (int i = 0; i < sizeof(baseNodeAddress); i++) pc.printf("%.2X", baseNodeAddress[i]); pc.printf("\r\n"); #endif //no longer need to handle timeout networkParametersTimeout.detach(); } int main() { #ifdef DEBUG pc.printf("[MAIN] Starting up...\r\n"); pc.printf(" . .\r\n"); pc.printf(" / `. .' \\\r\n"); pc.printf(" .---. < > < > .---.\r\n"); pc.printf(" | \\ \\ - ~ ~ - / / |\r\n"); pc.printf(" ~-..-~ ~-..-~\r\n"); pc.printf(" \\~~~\\.' `./~~~/\r\n"); pc.printf(" .-~~^-. \\__/ \\__/\r\n"); pc.printf(" .' O \\ / / \\ \\\r\n"); pc.printf("(_____, `._.' | } \\/~~~/\r\n"); pc.printf(" `----. / } | / \\__/\r\n"); pc.printf(" `-. | / | / `. ,~~|\r\n"); pc.printf(" ~-.__| /_ - ~ ^| /- _ `..-' f: f:\r\n"); pc.printf(" | / | / ~-. `-. _||_||_\r\n"); pc.printf(" |_____| |_____| ~ - . _ _ _ _ _>\r\n"); pc.printf("\r\n"); pc.printf("\r\n"); pc.printf(" Sensorsaurus | Team 24 GDP | Southampton | 2014\r\n"); pc.printf("\r\n"); pc.printf("\r\n"); #endif sdcard sd = sdcard(); //TODO: read basenode pin #ifdef DEBUG pc.printf("[MAIN] Basenode switch: %i\r\n", isBasenode); #endif //TODO: load configuration from SD getLocalAddress(); if (isBasenode) { h.connect(); string timestampStr = h.get("time.bitnode.co.uk", 80, "/"); time_t timestamp = atoi(timestampStr.c_str()); set_time(timestamp); pc.printf("[MAIN] Got time: %i\r\n", timestamp); xbee.registerMessageCallback(MESSAGE_JOIN_NETWORK_REQUEST, handleJoinNetworkRequest); xbee.registerMessageCallback(MESSAGE_SENSOR_DATA, handleSensorData); while(1) { #ifdef DEBUG pc.printf("[MAIN] Basenode is idle\r\n"); #endif wait(1); xbee.processIncomingData(); } } else { sensorinterface sensors = sensorinterface(); sif = &sensors; getNetworkParameters(); while(1) { xbee.processIncomingData(); //TODO: if message queue exceeds MAX_QUEUE SIZE, write older readings to SD card. //if xbee is awake send contents of message queue if (xbee.isCTS()) { while(!messageQueue.empty()) { snail::sensordata message = messageQueue.front(); xbee.send(message, sizeof(message)); messageQueue.pop(); } } //check if it's time to poll if (time(NULL) - lastPollTime > pollInterval) { #ifdef DEBUG pc.printf("[MAIN] Requesting data...\r\n"); #endif sensors.requestData(); lastPollTime = time(NULL); } //if there is data waiting for us... if (sensors.isDataWaiting()) { #ifdef DEBUG pc.printf("[MAIN] Data waiting, reading data...\r\n"); #endif d_reply data = sensors.readData(); #ifdef DEBUG pc.printf("[MAIN] Got data: "); for (int i = 0; i < data.readings.size(); i++) pc.printf("0x%.4X|", data.readings[i]); pc.printf("\r\n"); #endif int readings[16]; for (int i = 0; i < data.readings.size(); i++) readings[i] = data.readings[i]; //TODO: Get real I2C address snail::sensordata message(baseNodeAddress, data.type, data.type, time(NULL), readings, data.readings.size()); messageQueue.push(message); //log sd.write(static_cast<long int>(time(NULL)), data); } } } }