GDP group 24 node core
Dependencies: EthernetInterface SDFileSystem mbed-rtos mbed snail MbedJSONValue
main.cpp
- Committer:
- Trumple
- Date:
- 2015-01-28
- Revision:
- 31:9cf3f1e5ad68
- Parent:
- 29:564b1eaf5b99
File content as of revision 31:9cf3f1e5ad68:
#include "mbed.h" #include "snail.h" #include "sensorinterface.h" #include "sdcard.h" #include "http.h" #include "MbedJSONValue.h" #include <map> #define DEBUG #define API_IP "178.62.84.55" #define API_PORT 8888 #define API_TIME_IP "81.4.121.72" #define API_TIME_PORT 80 time_t lastPollTime = 0; time_t pollInterval = 30; bool isBasenode = false; 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; //commissioning button DigitalOut commissioningOutput(p30); InterruptIn commissioningInput(p16); 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 typeBuffer[3]; sprintf(typeBuffer, "%i", request.sensors[i].type); j["sensors"][i]["sensorID"] = string(sensorIDBuffer); j["sensors"][i]["sensortype"] = string(typeBuffer); } string address = addressToString(request.source); #ifdef DEBUG pc.printf( ("[MAIN] POSTing startup information: " + j.serialize() + "\r\n").c_str() ); #endif h.post(API_IP, API_PORT, "/field/" + string(localAddress) + "/" + 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(API_IP, API_PORT, "/field/" + string(localAddress) + "/" + 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(); } void commissioningFall() { commissioningOutput = 0; } void commissioningRise() { commissioningOutput = 1; } 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 | 2015\r\n"); pc.printf("\r\n"); pc.printf("\r\n"); #endif sdcard sd = sdcard(); h.connect(); //commissioning button commissioningInput.fall(commissioningFall); commissioningInput.rise(commissioningRise); //check if local node is basenode isBasenode = h.isEthernetConnected(); #ifdef DEBUG pc.printf("[MAIN] Basenode status: %i\r\n", isBasenode); #endif getLocalAddress(); if (isBasenode) { string timestampStr = h.get(API_TIME_IP, API_TIME_PORT, "/"); 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(); //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]; 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); } } } }