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
Handlers/SdHandler.cpp@0:2df78a4443cd, 2016-04-10 (annotated)
- Committer:
- Joseph Radford
- Date:
- Sun Apr 10 15:47:33 2016 +1000
- Revision:
- 0:2df78a4443cd
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Joseph Radford |
0:2df78a4443cd | 1 | #include "SdHandler.h" |
Joseph Radford |
0:2df78a4443cd | 2 | |
Joseph Radford |
0:2df78a4443cd | 3 | #include "GroveDht22.h" // for interpreting the result struct |
Joseph Radford |
0:2df78a4443cd | 4 | #include "circbuff.h" |
Joseph Radford |
0:2df78a4443cd | 5 | |
Joseph Radford |
0:2df78a4443cd | 6 | #define SD_BUFFER_LEN 256u // length of circular buffers |
Joseph Radford |
0:2df78a4443cd | 7 | |
Joseph Radford |
0:2df78a4443cd | 8 | // define pins for communicating with SD card |
Joseph Radford |
0:2df78a4443cd | 9 | #define PIN_MOSI P1_22 |
Joseph Radford |
0:2df78a4443cd | 10 | #define PIN_MISO P1_21 |
Joseph Radford |
0:2df78a4443cd | 11 | #define PIN_SCK P1_20 |
Joseph Radford |
0:2df78a4443cd | 12 | #define PIN_CS P1_23 |
Joseph Radford |
0:2df78a4443cd | 13 | |
Joseph Radford |
0:2df78a4443cd | 14 | #define DATA_FILE_NAME "/sd/data.csv" |
Joseph Radford |
0:2df78a4443cd | 15 | #define SYSLOG_FILE_NAME "/sd/log.txt" |
Joseph Radford |
0:2df78a4443cd | 16 | |
Joseph Radford |
0:2df78a4443cd | 17 | // declare led that will be used to express state of SD card |
Joseph Radford |
0:2df78a4443cd | 18 | extern DigitalOut myled2; |
Joseph Radford |
0:2df78a4443cd | 19 | |
Joseph Radford |
0:2df78a4443cd | 20 | SdHandler::SdHandler(MyTimers * _timer) : AbstractHandler(_timer) |
Joseph Radford |
0:2df78a4443cd | 21 | { |
Joseph Radford |
0:2df78a4443cd | 22 | // init file system and files |
Joseph Radford |
0:2df78a4443cd | 23 | m_sdfs = new SDFileSystem(PIN_MOSI, PIN_MISO, PIN_SCK, PIN_CS, "sd"); |
Joseph Radford |
0:2df78a4443cd | 24 | m_data = NULL; |
Joseph Radford |
0:2df78a4443cd | 25 | m_syslog = NULL; |
Joseph Radford |
0:2df78a4443cd | 26 | |
Joseph Radford |
0:2df78a4443cd | 27 | // initialise circular buffers |
Joseph Radford |
0:2df78a4443cd | 28 | m_dataLogBuff = new CircBuff(SD_BUFFER_LEN); |
Joseph Radford |
0:2df78a4443cd | 29 | m_sysLogBuff = new CircBuff(SD_BUFFER_LEN); |
Joseph Radford |
0:2df78a4443cd | 30 | |
Joseph Radford |
0:2df78a4443cd | 31 | mode = sd_Start; |
Joseph Radford |
0:2df78a4443cd | 32 | m_lastRequest = sdreq_SdNone; |
Joseph Radford |
0:2df78a4443cd | 33 | } |
Joseph Radford |
0:2df78a4443cd | 34 | |
Joseph Radford |
0:2df78a4443cd | 35 | SdHandler::~SdHandler() |
Joseph Radford |
0:2df78a4443cd | 36 | { |
Joseph Radford |
0:2df78a4443cd | 37 | delete m_dataLogBuff; |
Joseph Radford |
0:2df78a4443cd | 38 | delete m_sysLogBuff; |
Joseph Radford |
0:2df78a4443cd | 39 | } |
Joseph Radford |
0:2df78a4443cd | 40 | |
Joseph Radford |
0:2df78a4443cd | 41 | void SdHandler::run() |
Joseph Radford |
0:2df78a4443cd | 42 | { |
Joseph Radford |
0:2df78a4443cd | 43 | uint16_t tempInt = 0, tempInt2 = 0; |
Joseph Radford |
0:2df78a4443cd | 44 | |
Joseph Radford |
0:2df78a4443cd | 45 | unsigned char tempBuff[SD_BUFFER_LEN]; |
Joseph Radford |
0:2df78a4443cd | 46 | |
Joseph Radford |
0:2df78a4443cd | 47 | switch(mode) |
Joseph Radford |
0:2df78a4443cd | 48 | { |
Joseph Radford |
0:2df78a4443cd | 49 | case sd_Start: /* Set up the state machine */ |
Joseph Radford |
0:2df78a4443cd | 50 | // check if card is inserted?? |
Joseph Radford |
0:2df78a4443cd | 51 | //m_sdfs->unmount(); |
Joseph Radford |
0:2df78a4443cd | 52 | // close both files if necessary |
Joseph Radford |
0:2df78a4443cd | 53 | if (m_data != NULL) |
Joseph Radford |
0:2df78a4443cd | 54 | fclose(m_data); |
Joseph Radford |
0:2df78a4443cd | 55 | if (m_syslog != NULL) |
Joseph Radford |
0:2df78a4443cd | 56 | fclose(m_syslog); |
Joseph Radford |
0:2df78a4443cd | 57 | |
Joseph Radford |
0:2df78a4443cd | 58 | m_data = NULL; |
Joseph Radford |
0:2df78a4443cd | 59 | m_syslog = NULL; |
Joseph Radford |
0:2df78a4443cd | 60 | |
Joseph Radford |
0:2df78a4443cd | 61 | //mkdir("/sd", 0777); |
Joseph Radford |
0:2df78a4443cd | 62 | //m_sdfs->mount(); |
Joseph Radford |
0:2df78a4443cd | 63 | m_data = fopen(DATA_FILE_NAME, "a"); |
Joseph Radford |
0:2df78a4443cd | 64 | m_syslog = fopen(SYSLOG_FILE_NAME, "a"); |
Joseph Radford |
0:2df78a4443cd | 65 | |
Joseph Radford |
0:2df78a4443cd | 66 | if ((m_data != NULL) && (m_syslog != NULL)) |
Joseph Radford |
0:2df78a4443cd | 67 | { |
Joseph Radford |
0:2df78a4443cd | 68 | // both opened successfully |
Joseph Radford |
0:2df78a4443cd | 69 | fprintf(m_syslog, "Unit booted OK\n"); |
Joseph Radford |
0:2df78a4443cd | 70 | fclose(m_syslog); |
Joseph Radford |
0:2df78a4443cd | 71 | |
Joseph Radford |
0:2df78a4443cd | 72 | // write the header in on startup |
Joseph Radford |
0:2df78a4443cd | 73 | fprintf(m_data, "Timestamp, Temperature (degC), Humidity (pc), Dewpoint\n"); |
Joseph Radford |
0:2df78a4443cd | 74 | fclose(m_data); |
Joseph Radford |
0:2df78a4443cd | 75 | mode = sd_CheckSysLogBuffer; |
Joseph Radford |
0:2df78a4443cd | 76 | } |
Joseph Radford |
0:2df78a4443cd | 77 | break; |
Joseph Radford |
0:2df78a4443cd | 78 | |
Joseph Radford |
0:2df78a4443cd | 79 | case sd_CheckSysLogBuffer: /* See if any data should be written to the log file */ |
Joseph Radford |
0:2df78a4443cd | 80 | if (m_sysLogBuff->dataAvailable()) |
Joseph Radford |
0:2df78a4443cd | 81 | { |
Joseph Radford |
0:2df78a4443cd | 82 | tempInt = m_sysLogBuff->read(tempBuff, SD_BUFFER_LEN); |
Joseph Radford |
0:2df78a4443cd | 83 | tempInt2 = fprintf(m_syslog, (const char*)tempBuff); |
Joseph Radford |
0:2df78a4443cd | 84 | if (tempInt == tempInt2) |
Joseph Radford |
0:2df78a4443cd | 85 | { |
Joseph Radford |
0:2df78a4443cd | 86 | // success |
Joseph Radford |
0:2df78a4443cd | 87 | mode = sd_CheckDataLogBuffer; |
Joseph Radford |
0:2df78a4443cd | 88 | } |
Joseph Radford |
0:2df78a4443cd | 89 | else |
Joseph Radford |
0:2df78a4443cd | 90 | { |
Joseph Radford |
0:2df78a4443cd | 91 | // something went wrong |
Joseph Radford |
0:2df78a4443cd | 92 | m_timer->SetTimer(MyTimers::tmr_SdWaitError, 2000); |
Joseph Radford |
0:2df78a4443cd | 93 | mode = sd_WaitError; |
Joseph Radford |
0:2df78a4443cd | 94 | } |
Joseph Radford |
0:2df78a4443cd | 95 | } |
Joseph Radford |
0:2df78a4443cd | 96 | else { |
Joseph Radford |
0:2df78a4443cd | 97 | mode = sd_CheckDataLogBuffer; |
Joseph Radford |
0:2df78a4443cd | 98 | } |
Joseph Radford |
0:2df78a4443cd | 99 | break; |
Joseph Radford |
0:2df78a4443cd | 100 | |
Joseph Radford |
0:2df78a4443cd | 101 | case sd_CheckDataLogBuffer: /* See if any data should be written to the data file */ |
Joseph Radford |
0:2df78a4443cd | 102 | if (m_dataLogBuff->dataAvailable()) |
Joseph Radford |
0:2df78a4443cd | 103 | { |
Joseph Radford |
0:2df78a4443cd | 104 | m_data = fopen(DATA_FILE_NAME, "a"); |
Joseph Radford |
0:2df78a4443cd | 105 | |
Joseph Radford |
0:2df78a4443cd | 106 | if (m_data != NULL) |
Joseph Radford |
0:2df78a4443cd | 107 | { |
Joseph Radford |
0:2df78a4443cd | 108 | // opened successfully |
Joseph Radford |
0:2df78a4443cd | 109 | tempInt = m_dataLogBuff->read(tempBuff, SD_BUFFER_LEN); |
Joseph Radford |
0:2df78a4443cd | 110 | tempInt2 = fprintf(m_data, (const char*)tempBuff); |
Joseph Radford |
0:2df78a4443cd | 111 | fclose(m_data); |
Joseph Radford |
0:2df78a4443cd | 112 | if (tempInt == tempInt2) |
Joseph Radford |
0:2df78a4443cd | 113 | { |
Joseph Radford |
0:2df78a4443cd | 114 | // success |
Joseph Radford |
0:2df78a4443cd | 115 | myled2 = 0; |
Joseph Radford |
0:2df78a4443cd | 116 | mode = sd_CheckSysLogBuffer; |
Joseph Radford |
0:2df78a4443cd | 117 | } |
Joseph Radford |
0:2df78a4443cd | 118 | else |
Joseph Radford |
0:2df78a4443cd | 119 | { |
Joseph Radford |
0:2df78a4443cd | 120 | // something went wrong |
Joseph Radford |
0:2df78a4443cd | 121 | m_timer->SetTimer(MyTimers::tmr_SdWaitError, 2000); |
Joseph Radford |
0:2df78a4443cd | 122 | mode = sd_WaitError; |
Joseph Radford |
0:2df78a4443cd | 123 | } |
Joseph Radford |
0:2df78a4443cd | 124 | } |
Joseph Radford |
0:2df78a4443cd | 125 | else |
Joseph Radford |
0:2df78a4443cd | 126 | { |
Joseph Radford |
0:2df78a4443cd | 127 | // something went wrong |
Joseph Radford |
0:2df78a4443cd | 128 | m_timer->SetTimer(MyTimers::tmr_SdWaitError, 2000); |
Joseph Radford |
0:2df78a4443cd | 129 | mode = sd_WaitError; |
Joseph Radford |
0:2df78a4443cd | 130 | } |
Joseph Radford |
0:2df78a4443cd | 131 | } |
Joseph Radford |
0:2df78a4443cd | 132 | else { |
Joseph Radford |
0:2df78a4443cd | 133 | mode = sd_CheckSysLogBuffer; |
Joseph Radford |
0:2df78a4443cd | 134 | } |
Joseph Radford |
0:2df78a4443cd | 135 | break; |
Joseph Radford |
0:2df78a4443cd | 136 | |
Joseph Radford |
0:2df78a4443cd | 137 | case sd_WaitError: /* Many fails, much wow, wait for a while */ |
Joseph Radford |
0:2df78a4443cd | 138 | if (!m_timer->GetTimer(MyTimers::tmr_SdWaitError)) |
Joseph Radford |
0:2df78a4443cd | 139 | { |
Joseph Radford |
0:2df78a4443cd | 140 | // timer has elapsed. go back to start. |
Joseph Radford |
0:2df78a4443cd | 141 | mode = sd_Start; |
Joseph Radford |
0:2df78a4443cd | 142 | } |
Joseph Radford |
0:2df78a4443cd | 143 | break; |
Joseph Radford |
0:2df78a4443cd | 144 | } |
Joseph Radford |
0:2df78a4443cd | 145 | } |
Joseph Radford |
0:2df78a4443cd | 146 | |
Joseph Radford |
0:2df78a4443cd | 147 | void SdHandler::setRequest(int request, void *data) |
Joseph Radford |
0:2df78a4443cd | 148 | { |
Joseph Radford |
0:2df78a4443cd | 149 | request_t req = (request_t)request; |
Joseph Radford |
0:2df78a4443cd | 150 | m_lastRequest = req; |
Joseph Radford |
0:2df78a4443cd | 151 | switch(req) { |
Joseph Radford |
0:2df78a4443cd | 152 | case sdreq_SdNone: |
Joseph Radford |
0:2df78a4443cd | 153 | |
Joseph Radford |
0:2df78a4443cd | 154 | break; |
Joseph Radford |
0:2df78a4443cd | 155 | case sdreq_LogData: |
Joseph Radford |
0:2df78a4443cd | 156 | |
Joseph Radford |
0:2df78a4443cd | 157 | myled2 = 1; |
Joseph Radford |
0:2df78a4443cd | 158 | // have received the data struct. cast it |
Joseph Radford |
0:2df78a4443cd | 159 | Dht22Result *result = (Dht22Result*)data; |
Joseph Radford |
0:2df78a4443cd | 160 | |
Joseph Radford |
0:2df78a4443cd | 161 | // write things to sd card buffer |
Joseph Radford |
0:2df78a4443cd | 162 | char s[50]; // buffer |
Joseph Radford |
0:2df78a4443cd | 163 | int temp; // length of buffer |
Joseph Radford |
0:2df78a4443cd | 164 | csvStart(result->resultTime); |
Joseph Radford |
0:2df78a4443cd | 165 | temp = sprintf(s, "%4.2f", result->lastCelcius); |
Joseph Radford |
0:2df78a4443cd | 166 | csvData(s, temp); |
Joseph Radford |
0:2df78a4443cd | 167 | temp = sprintf(s, "%4.2f", result->lastHumidity); |
Joseph Radford |
0:2df78a4443cd | 168 | csvData(s, temp); |
Joseph Radford |
0:2df78a4443cd | 169 | temp = sprintf(s, "%4.2f", result->lastDewpoint); |
Joseph Radford |
0:2df78a4443cd | 170 | csvData(s, temp); |
Joseph Radford |
0:2df78a4443cd | 171 | csvEnd(); |
Joseph Radford |
0:2df78a4443cd | 172 | break; |
Joseph Radford |
0:2df78a4443cd | 173 | case sdreq_LogSystem: |
Joseph Radford |
0:2df78a4443cd | 174 | char *str = (char*)data; |
Joseph Radford |
0:2df78a4443cd | 175 | logEvent(str); |
Joseph Radford |
0:2df78a4443cd | 176 | break; |
Joseph Radford |
0:2df78a4443cd | 177 | } |
Joseph Radford |
0:2df78a4443cd | 178 | } |
Joseph Radford |
0:2df78a4443cd | 179 | |
Joseph Radford |
0:2df78a4443cd | 180 | void SdHandler::csvStart(time_t _time) |
Joseph Radford |
0:2df78a4443cd | 181 | { |
Joseph Radford |
0:2df78a4443cd | 182 | unsigned char sTemp[17]; |
Joseph Radford |
0:2df78a4443cd | 183 | |
Joseph Radford |
0:2df78a4443cd | 184 | |
Joseph Radford |
0:2df78a4443cd | 185 | // extract time_t to time info struct |
Joseph Radford |
0:2df78a4443cd | 186 | |
Joseph Radford |
0:2df78a4443cd | 187 | struct tm * timeinfo = localtime(&_time); |
Joseph Radford |
0:2df78a4443cd | 188 | |
Joseph Radford |
0:2df78a4443cd | 189 | // print the formatted timestamp at the start of terminalBuffer, with comma |
Joseph Radford |
0:2df78a4443cd | 190 | sprintf((char*)&sTemp[0], "%04d%02d%02d %02d%02d%02d,", (timeinfo->tm_year + 1900), |
Joseph Radford |
0:2df78a4443cd | 191 | (timeinfo->tm_mon + 1), |
Joseph Radford |
0:2df78a4443cd | 192 | timeinfo->tm_mday, |
Joseph Radford |
0:2df78a4443cd | 193 | timeinfo->tm_hour, |
Joseph Radford |
0:2df78a4443cd | 194 | timeinfo->tm_min, |
Joseph Radford |
0:2df78a4443cd | 195 | timeinfo->tm_sec); |
Joseph Radford |
0:2df78a4443cd | 196 | |
Joseph Radford |
0:2df78a4443cd | 197 | sTemp[16] = 0; |
Joseph Radford |
0:2df78a4443cd | 198 | |
Joseph Radford |
0:2df78a4443cd | 199 | m_dataLogBuff->add(sTemp); |
Joseph Radford |
0:2df78a4443cd | 200 | } |
Joseph Radford |
0:2df78a4443cd | 201 | |
Joseph Radford |
0:2df78a4443cd | 202 | void SdHandler::csvData(const char * s, int len) |
Joseph Radford |
0:2df78a4443cd | 203 | { |
Joseph Radford |
0:2df78a4443cd | 204 | unsigned char sTemp[50]; |
Joseph Radford |
0:2df78a4443cd | 205 | int idx = 0; |
Joseph Radford |
0:2df78a4443cd | 206 | // add a column to the buffer |
Joseph Radford |
0:2df78a4443cd | 207 | sprintf((char*)&sTemp[idx], s); |
Joseph Radford |
0:2df78a4443cd | 208 | idx += len; |
Joseph Radford |
0:2df78a4443cd | 209 | sTemp[idx++] = ','; |
Joseph Radford |
0:2df78a4443cd | 210 | sTemp[idx] = 0; |
Joseph Radford |
0:2df78a4443cd | 211 | m_dataLogBuff->add(sTemp); |
Joseph Radford |
0:2df78a4443cd | 212 | } |
Joseph Radford |
0:2df78a4443cd | 213 | |
Joseph Radford |
0:2df78a4443cd | 214 | void SdHandler::csvEnd() |
Joseph Radford |
0:2df78a4443cd | 215 | { |
Joseph Radford |
0:2df78a4443cd | 216 | unsigned char sTemp[2]; |
Joseph Radford |
0:2df78a4443cd | 217 | sTemp[0] = '\n'; |
Joseph Radford |
0:2df78a4443cd | 218 | sTemp[1] = 0; |
Joseph Radford |
0:2df78a4443cd | 219 | m_dataLogBuff->add(sTemp); |
Joseph Radford |
0:2df78a4443cd | 220 | } |
Joseph Radford |
0:2df78a4443cd | 221 | |
Joseph Radford |
0:2df78a4443cd | 222 | void SdHandler::logEvent(const char * s) |
Joseph Radford |
0:2df78a4443cd | 223 | { |
Joseph Radford |
0:2df78a4443cd | 224 | } |