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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers measurementhandler.cpp Source File

measurementhandler.cpp

00001 #include "measurementhandler.h"
00002 #include "mbed.h"
00003 #include "SdHandler.h"
00004 #include "UsbComms.h"
00005 
00006 // declare led4 so we can flash it to reflect state of this handler
00007 extern DigitalOut myled4;
00008 
00009 // flags for the request register
00010 #define REQ_RESULT 0b00000001
00011 #define REQ_ERROR  0b00000010
00012 #ifdef ENABLE_GPRS_TESTING
00013 #define REQ_SMS    0b00000100
00014 #endif
00015 
00016 #ifdef ENABLE_GPRS_TESTING
00017 MeasurementHandler::MeasurementHandler(SdHandler *_sd, UsbComms *_usb, GprsHandler *_gprs, MyTimers *_timer)
00018     : AbstractHandler(_timer), m_sd(_sd), m_usb(_usb), m_gprs(_gprs)
00019 #else
00020 MeasurementHandler::MeasurementHandler(SdHandler *_sd, UsbComms *_usb, MyTimers *_timer)
00021     : AbstractHandler(_timer), m_sd(_sd), m_usb(_usb)
00022 #endif
00023 {
00024     m_lastError         = ERROR_NONE;
00025     mode                = meas_Start;
00026     m_lastRequest       = measreq_MeasReqNone;
00027     m_flashOn           = false;
00028     m_requestRegister   = 0;
00029 
00030 #ifdef ENABLE_GPRS_TESTING
00031     for (int i = 0; i < GPRS_RECIPIENTS_MAXLEN; i++) {
00032         m_lastSender[i] = 0;
00033     }
00034 #endif
00035 }
00036 
00037 void MeasurementHandler::run()
00038 {
00039     switch(mode) {
00040     case meas_Start:
00041         // start here, and come back here if an error has been flushed out and waited
00042         mode = meas_CheckRequest;
00043         break;
00044 
00045     case meas_CheckRequest:
00046         if (m_requestRegister) {
00047             // check what has been requested, starting from most highest priority
00048             
00049 #ifdef ENABLE_GPRS_TESTING
00050             if (m_requestRegister&REQ_SMS) {
00051                 // an SMS has been requested
00052                 mode = meas_PostStateSMS;
00053             }
00054             else if (m_requestRegister&REQ_RESULT) {
00055 #else
00056             if (m_requestRegister&REQ_RESULT) {
00057 #endif
00058                 // a result has been sent, we need to post it
00059                 mode = meas_PostResult;
00060             }
00061             else if (m_requestRegister&REQ_ERROR) {
00062                 // an error has been sent, we need to post it
00063                 mode = meas_PostError;
00064             }
00065             else {
00066                 // something went wrong, a flag was set that isn't defined
00067                 m_requestRegister = 0;
00068                 mode = meas_FlashTimer;
00069             }
00070         }
00071         else {
00072             // no requests, check if running led needs to be flashed
00073             mode = meas_FlashTimer;
00074         }
00075         break;
00076 
00077 #ifdef ENABLE_GPRS_TESTING
00078     case meas_PostStateSMS:
00079         if (m_requestRegister&REQ_SMS) {
00080             char s[64];
00081             // usb print
00082             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);
00083 
00084             GprsRequest req;
00085             strcpy(req.message, s);
00086             strcpy(req.recipients, m_lastSender);
00087             m_gprs->setRequest(GprsHandler::gprsreq_SmsSend, &req);
00088 
00089             // clear the request reqister's sms flag
00090             m_requestRegister &= ~REQ_SMS;
00091         }
00092         mode = meas_CheckRequest;
00093         break;
00094 #endif
00095 
00096     case meas_PostResult:
00097         if (m_requestRegister&REQ_RESULT) {
00098             // we have a result, post it
00099 
00100             // 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
00101 
00102             char s[50];
00103             // usb print
00104             sprintf(s, "Temperature is %4.2f degC", m_lastResult.lastCelcius);
00105             m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, s);
00106             sprintf(s, "Humidity is %4.2f pc",      m_lastResult.lastHumidity);
00107             m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, s);
00108             sprintf(s, "Dew point is %4.2f ",    m_lastResult.lastDewpoint);
00109             m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, s);
00110             
00111             // post to SD card
00112             m_sd->setRequest(SdHandler::sdreq_LogData, &m_lastResult);
00113 
00114             // clear the request
00115             m_requestRegister &= ~REQ_RESULT;
00116         }
00117 
00118         // go back to check if there are more requests
00119         mode = meas_CheckRequest;
00120         break;
00121 
00122 
00123     case meas_PostError:
00124         if (m_requestRegister&REQ_ERROR) {
00125             // there is an error, check the value of it and post the corresponding string to USB
00126             // TODO: post to SD syslog
00127             switch (m_lastError)
00128             {
00129             case BUS_BUSY:
00130                 m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, (char*)"BUSY!");
00131                 break;
00132             case ERROR_NOT_PRESENT:
00133                 m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, (char*)"NOT PRESENT");
00134                 break;
00135             case ERROR_ACK_TOO_LONG:
00136                 m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, (char*)"TOO LONG");
00137                 break;
00138             case ERROR_SYNC_TIMEOUT:
00139                 m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, (char*)"SYNC TIMEOUTr\n");
00140                 break;
00141             case ERROR_DATA_TIMEOUT:
00142                 m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, (char*)"DATA TIMEOUT");
00143                 break;
00144             case ERROR_CHECKSUM:
00145                 m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, (char*)"CHECKSUM");
00146                 break;
00147             case ERROR_NO_PATIENCE:
00148                 m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, (char*)"NO PATIENCE!");
00149                 break;
00150             default:
00151                 m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, (char*)"UNKNOWN");
00152                 break;
00153             }
00154 
00155             // we have posted it, clear the flag
00156             m_requestRegister &= ~REQ_ERROR;
00157         }
00158         // check if there are any more requests
00159         mode = meas_CheckRequest;
00160         break;
00161         
00162     case meas_FlashTimer:
00163         // flash timer to know that we are still alive.        
00164         if (!m_timer->GetTimer(MyTimers::tmr_MeasFlash)) {      // wait until timer has elapsed
00165             if (m_flashOn) {
00166                 // turn off
00167                 myled4 = 0;
00168                 m_timer->SetTimer(MyTimers::tmr_MeasFlash, 2000); // stay off for 2 seconds
00169                 m_flashOn = false;
00170             }
00171             else {
00172                 // turn on
00173                 myled4 = 1;
00174                 m_timer->SetTimer(MyTimers::tmr_MeasFlash, 1000); // stay on for 1 second
00175                 m_flashOn = true;
00176             }
00177                 
00178         }
00179         mode = meas_CheckRequest;
00180         break;
00181 
00182     case meas_WaitError:
00183         // TODO: timer
00184         mode = meas_Start;
00185         break;
00186     }
00187 }
00188 
00189 void MeasurementHandler::setRequest(int request, void *data)
00190 {
00191     m_lastRequest = (request_t )request;
00192     switch(request) {
00193     case measreq_DhtResult:
00194         // this should contain time as well
00195         Dht22Result *result = (Dht22Result*)data;
00196 
00197         // copy the structure into our own structure
00198         m_lastResult = *result;
00199 
00200         // set the request
00201         m_requestRegister |= REQ_RESULT;
00202 
00203         break;
00204 
00205     case measreq_DhtError:
00206         int *iResult = (int*)data;
00207         m_lastError = *iResult;
00208         m_requestRegister |= REQ_ERROR;
00209 
00210         break;
00211 
00212 #ifdef ENABLE_GPRS_TESTING
00213     case measreq_Status:
00214         // need to send SMS of last result
00215         // the sender's number is the sent data
00216         char *sender = (char*)data;
00217 
00218         int i = 0;
00219         // copy the sender's number
00220         for (i = 0; (i < GPRS_RECIPIENTS_MAXLEN) && (sender[i] != 0); i++) {
00221             m_lastSender[i] = sender[i];
00222         }
00223 
00224         // set the rest of the destination array to null
00225         for (i; i < GPRS_RECIPIENTS_MAXLEN; i++) {
00226             m_lastSender[i] = 0;
00227         }
00228 
00229         // set the request
00230         m_requestRegister |= REQ_SMS;
00231         break;
00232 #endif
00233     }
00234 }