A simple WIP that logs data from a Grove sensor, and can send and receive information over USB and SMS.
Dependencies: DHT DS_1337 SDFileSystem USBDevice mbed
Diff: Handlers/measurementhandler.cpp
- Revision:
- 0:2df78a4443cd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Handlers/measurementhandler.cpp Sun Apr 10 15:47:33 2016 +1000 @@ -0,0 +1,234 @@ +#include "measurementhandler.h" +#include "mbed.h" +#include "SdHandler.h" +#include "UsbComms.h" + +// declare led4 so we can flash it to reflect state of this handler +extern DigitalOut myled4; + +// flags for the request register +#define REQ_RESULT 0b00000001 +#define REQ_ERROR 0b00000010 +#ifdef ENABLE_GPRS_TESTING +#define REQ_SMS 0b00000100 +#endif + +#ifdef ENABLE_GPRS_TESTING +MeasurementHandler::MeasurementHandler(SdHandler *_sd, UsbComms *_usb, GprsHandler *_gprs, MyTimers *_timer) + : AbstractHandler(_timer), m_sd(_sd), m_usb(_usb), m_gprs(_gprs) +#else +MeasurementHandler::MeasurementHandler(SdHandler *_sd, UsbComms *_usb, MyTimers *_timer) + : AbstractHandler(_timer), m_sd(_sd), m_usb(_usb) +#endif +{ + m_lastError = ERROR_NONE; + mode = meas_Start; + m_lastRequest = measreq_MeasReqNone; + m_flashOn = false; + m_requestRegister = 0; + +#ifdef ENABLE_GPRS_TESTING + for (int i = 0; i < GPRS_RECIPIENTS_MAXLEN; i++) { + m_lastSender[i] = 0; + } +#endif +} + +void MeasurementHandler::run() +{ + switch(mode) { + case meas_Start: + // start here, and come back here if an error has been flushed out and waited + mode = meas_CheckRequest; + break; + + case meas_CheckRequest: + if (m_requestRegister) { + // check what has been requested, starting from most highest priority + +#ifdef ENABLE_GPRS_TESTING + if (m_requestRegister&REQ_SMS) { + // an SMS has been requested + mode = meas_PostStateSMS; + } + else if (m_requestRegister&REQ_RESULT) { +#else + if (m_requestRegister&REQ_RESULT) { +#endif + // a result has been sent, we need to post it + mode = meas_PostResult; + } + else if (m_requestRegister&REQ_ERROR) { + // an error has been sent, we need to post it + mode = meas_PostError; + } + else { + // something went wrong, a flag was set that isn't defined + m_requestRegister = 0; + mode = meas_FlashTimer; + } + } + else { + // no requests, check if running led needs to be flashed + mode = meas_FlashTimer; + } + break; + +#ifdef ENABLE_GPRS_TESTING + case meas_PostStateSMS: + if (m_requestRegister&REQ_SMS) { + char s[64]; + // usb print + sprintf(s, "Temperature is %4.2f degC\nHumidity is %4.2f pc\nDew point is %4.2f", m_lastResult.lastCelcius, m_lastResult.lastHumidity, m_lastResult.lastDewpoint); + + GprsRequest req; + strcpy(req.message, s); + strcpy(req.recipients, m_lastSender); + m_gprs->setRequest(GprsHandler::gprsreq_SmsSend, &req); + + // clear the request reqister's sms flag + m_requestRegister &= ~REQ_SMS; + } + mode = meas_CheckRequest; + break; +#endif + + case meas_PostResult: + if (m_requestRegister&REQ_RESULT) { + // we have a result, post it + + // TODO: check when the last result came in. if it has not been very long (< 5s? < 1s?) avoid posting, so we don't hammer it + + char s[50]; + // usb print + sprintf(s, "Temperature is %4.2f degC", m_lastResult.lastCelcius); + m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, s); + sprintf(s, "Humidity is %4.2f pc", m_lastResult.lastHumidity); + m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, s); + sprintf(s, "Dew point is %4.2f ", m_lastResult.lastDewpoint); + m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, s); + + // post to SD card + m_sd->setRequest(SdHandler::sdreq_LogData, &m_lastResult); + + // clear the request + m_requestRegister &= ~REQ_RESULT; + } + + // go back to check if there are more requests + mode = meas_CheckRequest; + break; + + + case meas_PostError: + if (m_requestRegister&REQ_ERROR) { + // there is an error, check the value of it and post the corresponding string to USB + // TODO: post to SD syslog + switch (m_lastError) + { + case BUS_BUSY: + m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, (char*)"BUSY!"); + break; + case ERROR_NOT_PRESENT: + m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, (char*)"NOT PRESENT"); + break; + case ERROR_ACK_TOO_LONG: + m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, (char*)"TOO LONG"); + break; + case ERROR_SYNC_TIMEOUT: + m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, (char*)"SYNC TIMEOUTr\n"); + break; + case ERROR_DATA_TIMEOUT: + m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, (char*)"DATA TIMEOUT"); + break; + case ERROR_CHECKSUM: + m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, (char*)"CHECKSUM"); + break; + case ERROR_NO_PATIENCE: + m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, (char*)"NO PATIENCE!"); + break; + default: + m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, (char*)"UNKNOWN"); + break; + } + + // we have posted it, clear the flag + m_requestRegister &= ~REQ_ERROR; + } + // check if there are any more requests + mode = meas_CheckRequest; + break; + + case meas_FlashTimer: + // flash timer to know that we are still alive. + if (!m_timer->GetTimer(MyTimers::tmr_MeasFlash)) { // wait until timer has elapsed + if (m_flashOn) { + // turn off + myled4 = 0; + m_timer->SetTimer(MyTimers::tmr_MeasFlash, 2000); // stay off for 2 seconds + m_flashOn = false; + } + else { + // turn on + myled4 = 1; + m_timer->SetTimer(MyTimers::tmr_MeasFlash, 1000); // stay on for 1 second + m_flashOn = true; + } + + } + mode = meas_CheckRequest; + break; + + case meas_WaitError: + // TODO: timer + mode = meas_Start; + break; + } +} + +void MeasurementHandler::setRequest(int request, void *data) +{ + m_lastRequest = (request_t)request; + switch(request) { + case measreq_DhtResult: + // this should contain time as well + Dht22Result *result = (Dht22Result*)data; + + // copy the structure into our own structure + m_lastResult = *result; + + // set the request + m_requestRegister |= REQ_RESULT; + + break; + + case measreq_DhtError: + int *iResult = (int*)data; + m_lastError = *iResult; + m_requestRegister |= REQ_ERROR; + + break; + +#ifdef ENABLE_GPRS_TESTING + case measreq_Status: + // need to send SMS of last result + // the sender's number is the sent data + char *sender = (char*)data; + + int i = 0; + // copy the sender's number + for (i = 0; (i < GPRS_RECIPIENTS_MAXLEN) && (sender[i] != 0); i++) { + m_lastSender[i] = sender[i]; + } + + // set the rest of the destination array to null + for (i; i < GPRS_RECIPIENTS_MAXLEN; i++) { + m_lastSender[i] = 0; + } + + // set the request + m_requestRegister |= REQ_SMS; + break; +#endif + } +}