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 SdHandler.cpp Source File

SdHandler.cpp

00001 #include "SdHandler.h"
00002 
00003 #include "GroveDht22.h" // for interpreting the result struct
00004 #include "circbuff.h"
00005 
00006 #define SD_BUFFER_LEN 256u   // length of circular buffers
00007 
00008 // define pins for communicating with SD card
00009 #define PIN_MOSI        P1_22
00010 #define PIN_MISO        P1_21
00011 #define PIN_SCK         P1_20
00012 #define PIN_CS          P1_23
00013 
00014 #define DATA_FILE_NAME   "/sd/data.csv"
00015 #define SYSLOG_FILE_NAME "/sd/log.txt"
00016 
00017 // declare led that will be used to express state of SD card
00018 extern DigitalOut myled2;
00019 
00020 SdHandler::SdHandler(MyTimers * _timer) : AbstractHandler(_timer)
00021 {
00022     // init file system and files
00023     m_sdfs = new SDFileSystem(PIN_MOSI, PIN_MISO, PIN_SCK, PIN_CS, "sd");
00024     m_data = NULL;
00025     m_syslog = NULL;
00026 
00027     // initialise circular buffers
00028     m_dataLogBuff = new CircBuff(SD_BUFFER_LEN);
00029     m_sysLogBuff  = new CircBuff(SD_BUFFER_LEN);
00030     
00031     mode = sd_Start;
00032     m_lastRequest = sdreq_SdNone;
00033 }
00034 
00035 SdHandler::~SdHandler()
00036 {
00037     delete m_dataLogBuff;
00038     delete m_sysLogBuff;
00039 }
00040 
00041 void SdHandler::run()
00042 {
00043     uint16_t tempInt = 0, tempInt2 = 0;
00044 
00045     unsigned char tempBuff[SD_BUFFER_LEN];
00046 
00047     switch(mode)
00048     {
00049     case sd_Start:              /* Set up the state machine */
00050         // check if card is inserted??
00051         //m_sdfs->unmount();
00052         // close both files if necessary
00053         if (m_data != NULL)
00054             fclose(m_data);
00055         if (m_syslog != NULL)
00056             fclose(m_syslog);
00057 
00058         m_data = NULL;
00059         m_syslog = NULL;
00060 
00061         //mkdir("/sd", 0777);
00062         //m_sdfs->mount();
00063         m_data = fopen(DATA_FILE_NAME, "a");
00064         m_syslog = fopen(SYSLOG_FILE_NAME, "a");
00065 
00066         if ((m_data != NULL) && (m_syslog != NULL))
00067         {
00068             // both opened successfully
00069             fprintf(m_syslog, "Unit booted OK\n");
00070             fclose(m_syslog);
00071             
00072             // write the header in on startup
00073             fprintf(m_data, "Timestamp, Temperature (degC), Humidity (pc), Dewpoint\n");            
00074             fclose(m_data);
00075             mode = sd_CheckSysLogBuffer;
00076         }
00077         break;
00078 
00079     case sd_CheckSysLogBuffer:     /* See if any data should be written to the log file */
00080         if (m_sysLogBuff->dataAvailable())
00081         {
00082             tempInt = m_sysLogBuff->read(tempBuff, SD_BUFFER_LEN);
00083             tempInt2 = fprintf(m_syslog, (const char*)tempBuff);
00084             if (tempInt == tempInt2)
00085             {
00086                 // success
00087                 mode = sd_CheckDataLogBuffer;
00088             }
00089             else
00090             {
00091                 // something went wrong
00092                 m_timer->SetTimer(MyTimers::tmr_SdWaitError, 2000);
00093                 mode = sd_WaitError;
00094             }
00095         }
00096         else {
00097             mode = sd_CheckDataLogBuffer;
00098         }
00099         break;
00100 
00101     case sd_CheckDataLogBuffer:    /* See if any data should be written to the data file */
00102         if (m_dataLogBuff->dataAvailable())
00103         {            
00104             m_data = fopen(DATA_FILE_NAME, "a");
00105 
00106             if (m_data != NULL)
00107             {
00108                 // opened successfully            
00109                 tempInt = m_dataLogBuff->read(tempBuff, SD_BUFFER_LEN);
00110                 tempInt2 = fprintf(m_data, (const char*)tempBuff);            
00111                 fclose(m_data);
00112                 if (tempInt == tempInt2)
00113                 {
00114                     // success
00115                     myled2 = 0;
00116                     mode = sd_CheckSysLogBuffer;
00117                 }
00118                 else
00119                 {
00120                     // something went wrong
00121                     m_timer->SetTimer(MyTimers::tmr_SdWaitError, 2000);
00122                     mode = sd_WaitError;
00123                 }
00124             }            
00125             else
00126             {
00127                 // something went wrong
00128                 m_timer->SetTimer(MyTimers::tmr_SdWaitError, 2000);
00129                 mode = sd_WaitError;
00130             }
00131         }
00132         else {
00133             mode = sd_CheckSysLogBuffer;
00134         }
00135         break;
00136 
00137     case sd_WaitError:     /* Many fails, much wow, wait for a while */
00138         if (!m_timer->GetTimer(MyTimers::tmr_SdWaitError))
00139         {
00140             // timer has elapsed. go back to start.
00141             mode = sd_Start;
00142         }
00143         break;
00144     }
00145 }
00146 
00147 void SdHandler::setRequest(int request, void *data)
00148 {
00149     request_t  req = (request_t )request;
00150     m_lastRequest = req;
00151     switch(req) {
00152     case sdreq_SdNone:
00153     
00154         break;
00155     case sdreq_LogData:
00156             
00157         myled2 = 1;
00158         // have received the data struct. cast it
00159         Dht22Result *result = (Dht22Result*)data;
00160         
00161         // write things to sd card buffer
00162         char s[50]; // buffer
00163         int temp;   // length of buffer
00164         csvStart(result->resultTime);
00165         temp = sprintf(s, "%4.2f", result->lastCelcius);
00166         csvData(s, temp);
00167         temp = sprintf(s, "%4.2f",    result->lastHumidity);
00168         csvData(s, temp);
00169         temp = sprintf(s, "%4.2f",    result->lastDewpoint);
00170         csvData(s, temp);
00171         csvEnd();
00172         break;
00173     case sdreq_LogSystem:
00174         char *str = (char*)data;
00175         logEvent(str);
00176         break;
00177     }
00178 }
00179 
00180 void SdHandler::csvStart(time_t _time)
00181 {
00182     unsigned char sTemp[17];
00183     
00184     
00185     // extract time_t to time info struct
00186     
00187     struct tm * timeinfo = localtime(&_time);
00188     
00189     // print the formatted timestamp at the start of terminalBuffer, with comma
00190     sprintf((char*)&sTemp[0], "%04d%02d%02d %02d%02d%02d,", (timeinfo->tm_year + 1900),
00191                                                     (timeinfo->tm_mon + 1),
00192                                                     timeinfo->tm_mday,
00193                                                     timeinfo->tm_hour,
00194                                                     timeinfo->tm_min,
00195                                                     timeinfo->tm_sec);
00196                       
00197     sTemp[16] = 0;
00198                           
00199     m_dataLogBuff->add(sTemp);
00200 }
00201 
00202 void SdHandler::csvData(const char * s, int len)
00203 {
00204     unsigned char sTemp[50];
00205     int idx = 0;
00206     // add a column to the buffer
00207     sprintf((char*)&sTemp[idx], s);
00208     idx += len;
00209     sTemp[idx++] = ',';
00210     sTemp[idx] = 0;
00211     m_dataLogBuff->add(sTemp);
00212 }
00213 
00214 void SdHandler::csvEnd()
00215 {
00216     unsigned char sTemp[2];
00217     sTemp[0] = '\n';
00218     sTemp[1] = 0;
00219     m_dataLogBuff->add(sTemp);
00220 }
00221 
00222 void SdHandler::logEvent(const char * s)
00223 {
00224 }