Latest
Dependencies: serial_terminal sample_hardware PLL_Config SDCard BMP280 Networkbits TextLCD SDBlockDevice
main.cpp@27:bb8d4c883e1b, 2018-12-21 (annotated)
- Committer:
- Swabey89
- Date:
- Fri Dec 21 09:59:24 2018 +0000
- Revision:
- 27:bb8d4c883e1b
- Parent:
- 26:94238a308ff9
- Child:
- 28:7fccaef8fa72
Pre-producer/consumer pattern changes
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Swabey89 | 7:e2bf2d703867 | 1 | #include "mbed.h" |
Swabey89 | 1:31c7b4ab552b | 2 | #include "sample_hardware.hpp" |
Swabey89 | 21:2c438eeaab14 | 3 | #include "Networking.hpp" |
Swabey89 | 5:956984cbe447 | 4 | #include "serial_terminal.hpp" |
Swabey89 | 6:a5394c9e5927 | 5 | #include "SDCard.hpp" |
Swabey89 | 5:956984cbe447 | 6 | #include "rtos.h" |
Swabey89 | 11:3ad0327e8c9f | 7 | #include "events/mbed_events.h" |
Swabey89 | 8:c81b0ff8b822 | 8 | #include "LCDdisplay.hpp" |
Swabey89 | 5:956984cbe447 | 9 | |
Swabey89 | 24:81981815ef20 | 10 | //Defines TEST FOR SD CARD MOUNT AND UNMOUNT |
Swabey89 | 24:81981815ef20 | 11 | #define EDGE_FALLEN 0 |
Swabey89 | 24:81981815ef20 | 12 | #define EDGE_RISEN 1 |
Swabey89 | 19:88d8359306a4 | 13 | |
Swabey89 | 10:0fffc988d325 | 14 | //Signals |
Swabey89 | 8:c81b0ff8b822 | 15 | #define TAKE_SAMPLE 1 |
Swabey89 | 19:88d8359306a4 | 16 | #define STORE_DATA 2 |
Swabey89 | 10:0fffc988d325 | 17 | |
Swabey89 | 24:81981815ef20 | 18 | |
Swabey89 | 17:ead43c1b729d | 19 | //Global variables |
Swabey89 | 19:88d8359306a4 | 20 | |
Swabey89 | 27:bb8d4c883e1b | 21 | |
Swabey89 | 27:bb8d4c883e1b | 22 | unsigned int newestIndex = 0; //First time it is incremented, it will be 0 |
Swabey89 | 27:bb8d4c883e1b | 23 | unsigned int oldestIndex = 0; |
Swabey89 | 17:ead43c1b729d | 24 | FILE* fp; |
Swabey89 | 17:ead43c1b729d | 25 | FATFileSystem* fs; |
Swabey89 | 10:0fffc988d325 | 26 | |
Swabey89 | 19:88d8359306a4 | 27 | //Shared mutable variables VOLATILE |
Swabey89 | 25:831dc928ccde | 28 | bool sd_init; //is it? |
Swabey89 | 22:d9cbbbf3cf69 | 29 | float sample_rate = 15; //is it? |
Swabey89 | 17:ead43c1b729d | 30 | struct tm* timeData; |
Swabey89 | 18:3edfb9152b05 | 31 | char cmdBuffer[256]; |
Swabey89 | 19:88d8359306a4 | 32 | sensorData buffer[BUFFERSIZE]; |
Swabey89 | 17:ead43c1b729d | 33 | RawSerial* pc; |
Swabey89 | 8:c81b0ff8b822 | 34 | |
Swabey89 | 19:88d8359306a4 | 35 | //Thread synchronisation primatives |
Swabey89 | 19:88d8359306a4 | 36 | Semaphore spaceAvailable(BUFFERSIZE); |
Swabey89 | 19:88d8359306a4 | 37 | Semaphore samplesInBuffer(0); |
Swabey89 | 19:88d8359306a4 | 38 | Mutex bufferLock; |
Swabey89 | 19:88d8359306a4 | 39 | |
Swabey89 | 8:c81b0ff8b822 | 40 | //Queues |
Swabey89 | 11:3ad0327e8c9f | 41 | EventQueue SDqueue(32*EVENTS_EVENT_SIZE); |
Swabey89 | 11:3ad0327e8c9f | 42 | EventQueue LCDqueue(32*EVENTS_EVENT_SIZE); |
Swabey89 | 17:ead43c1b729d | 43 | EventQueue serialqueue(32*EVENTS_EVENT_SIZE); |
Swabey89 | 1:31c7b4ab552b | 44 | |
Swabey89 | 1:31c7b4ab552b | 45 | //Threads |
Swabey89 | 19:88d8359306a4 | 46 | Thread producer_thread(osPriorityHigh); |
Swabey89 | 19:88d8359306a4 | 47 | Thread consumer_thread; |
Swabey89 | 19:88d8359306a4 | 48 | Thread serial_thread(osPriorityAboveNormal); |
Swabey89 | 24:81981815ef20 | 49 | Thread SDqueue_thread; //remove |
Swabey89 | 11:3ad0327e8c9f | 50 | Thread LCDqueue_thread; |
Swabey89 | 20:cdde0663c481 | 51 | Thread Network_thread; |
Swabey89 | 0:4afd4940a189 | 52 | |
Swabey89 | 24:81981815ef20 | 53 | //TEST FOR SD CARD |
Swabey89 | 24:81981815ef20 | 54 | Thread SDmount_thread; |
Swabey89 | 24:81981815ef20 | 55 | |
Swabey89 | 17:ead43c1b729d | 56 | //Timers |
Swabey89 | 8:c81b0ff8b822 | 57 | Ticker sample; |
Swabey89 | 10:0fffc988d325 | 58 | |
Swabey89 | 17:ead43c1b729d | 59 | //Function prototypes |
Swabey89 | 8:c81b0ff8b822 | 60 | void sampleISR(void); |
Swabey89 | 19:88d8359306a4 | 61 | void sampleProducer(void); |
Swabey89 | 19:88d8359306a4 | 62 | void sampleConsumer(void); |
Swabey89 | 11:3ad0327e8c9f | 63 | void serialISR(void); |
Swabey89 | 19:88d8359306a4 | 64 | void serialData(void); |
Swabey89 | 11:3ad0327e8c9f | 65 | |
Swabey89 | 24:81981815ef20 | 66 | |
Swabey89 | 24:81981815ef20 | 67 | |
Swabey89 | 24:81981815ef20 | 68 | //TEST FOR SD CARD MOUNT AND UNMOUNT |
Swabey89 | 24:81981815ef20 | 69 | Timeout userswTimeOut; |
Swabey89 | 24:81981815ef20 | 70 | int userswState = EDGE_FALLEN; |
Swabey89 | 24:81981815ef20 | 71 | InterruptIn usersw(USER_BUTTON); |
Swabey89 | 24:81981815ef20 | 72 | void userswTimeOutHandler(); |
Swabey89 | 24:81981815ef20 | 73 | void userswRisingEdge(); |
Swabey89 | 24:81981815ef20 | 74 | void userswFallingEdge(); |
Swabey89 | 24:81981815ef20 | 75 | void SDmount(); |
Swabey89 | 24:81981815ef20 | 76 | |
Swabey89 | 25:831dc928ccde | 77 | Mutex printlock; |
Swabey89 | 25:831dc928ccde | 78 | Mutex LCDlock; |
Swabey89 | 25:831dc928ccde | 79 | Mutex timeLock; |
Swabey89 | 25:831dc928ccde | 80 | Mutex SDlock; |
Swabey89 | 24:81981815ef20 | 81 | |
Swabey89 | 24:81981815ef20 | 82 | |
Swabey89 | 27:bb8d4c883e1b | 83 | //TEST FOR BUFFER CHANGES |
Swabey89 | 27:bb8d4c883e1b | 84 | unsigned int saveIndex = 0; |
Swabey89 | 27:bb8d4c883e1b | 85 | |
Swabey89 | 27:bb8d4c883e1b | 86 | |
Swabey89 | 15:8af9672a6778 | 87 | int main() { |
Swabey89 | 17:ead43c1b729d | 88 | timeData = new tm; |
Swabey89 | 11:3ad0327e8c9f | 89 | pc = new RawSerial(USBTX, USBRX); |
Swabey89 | 8:c81b0ff8b822 | 90 | |
Swabey89 | 18:3edfb9152b05 | 91 | //Initialisations |
Swabey89 | 17:ead43c1b729d | 92 | SDcard(); |
Swabey89 | 9:fa8a35d9d6c0 | 93 | |
Swabey89 | 1:31c7b4ab552b | 94 | //Power on self test |
Swabey89 | 1:31c7b4ab552b | 95 | post(); |
Swabey89 | 18:3edfb9152b05 | 96 | |
Swabey89 | 18:3edfb9152b05 | 97 | //Start threads |
Swabey89 | 18:3edfb9152b05 | 98 | SDqueue_thread.start(callback(&SDqueue, &EventQueue::dispatch_forever)); |
Swabey89 | 18:3edfb9152b05 | 99 | LCDqueue_thread.start(callback(&LCDqueue, &EventQueue::dispatch_forever)); |
Swabey89 | 19:88d8359306a4 | 100 | serial_thread.start(callback(&serialqueue, &EventQueue::dispatch_forever)); |
Swabey89 | 21:2c438eeaab14 | 101 | Network_thread.start(network); |
Swabey89 | 19:88d8359306a4 | 102 | producer_thread.start(sampleProducer); |
Swabey89 | 19:88d8359306a4 | 103 | consumer_thread.start(sampleConsumer); |
Swabey89 | 3:b1583f309b43 | 104 | |
Swabey89 | 24:81981815ef20 | 105 | //TEST FOR SD CARD |
Swabey89 | 24:81981815ef20 | 106 | SDmount_thread.start(SDmount); |
Swabey89 | 24:81981815ef20 | 107 | |
Swabey89 | 20:cdde0663c481 | 108 | |
Swabey89 | 18:3edfb9152b05 | 109 | //Attach ISRs |
Swabey89 | 18:3edfb9152b05 | 110 | sample.attach(&sampleISR, sample_rate); |
Swabey89 | 11:3ad0327e8c9f | 111 | pc->attach(serialISR, Serial::RxIrq); |
Swabey89 | 15:8af9672a6778 | 112 | |
Swabey89 | 24:81981815ef20 | 113 | //TEST FOR SD CARD MOUNT AND UNMOUNT |
Swabey89 | 24:81981815ef20 | 114 | usersw.rise(&userswRisingEdge); |
Swabey89 | 24:81981815ef20 | 115 | |
Swabey89 | 1:31c7b4ab552b | 116 | //Flash to indicate goodness |
Swabey89 | 1:31c7b4ab552b | 117 | while(true) { |
Swabey89 | 5:956984cbe447 | 118 | greenLED = !greenLED; |
Swabey89 | 5:956984cbe447 | 119 | Thread::wait(500); |
Swabey89 | 0:4afd4940a189 | 120 | } |
Swabey89 | 0:4afd4940a189 | 121 | } |
Swabey89 | 1:31c7b4ab552b | 122 | |
Swabey89 | 19:88d8359306a4 | 123 | /* |
Swabey89 | 19:88d8359306a4 | 124 | FUNCITONS BELOW NEED MOVING? |
Swabey89 | 19:88d8359306a4 | 125 | */ |
Swabey89 | 19:88d8359306a4 | 126 | |
Swabey89 | 8:c81b0ff8b822 | 127 | void sampleISR() |
Swabey89 | 8:c81b0ff8b822 | 128 | { |
Swabey89 | 19:88d8359306a4 | 129 | producer_thread.signal_set(TAKE_SAMPLE); |
Swabey89 | 8:c81b0ff8b822 | 130 | } |
Swabey89 | 1:31c7b4ab552b | 131 | |
Swabey89 | 11:3ad0327e8c9f | 132 | void serialISR() |
Swabey89 | 11:3ad0327e8c9f | 133 | { |
Swabey89 | 11:3ad0327e8c9f | 134 | pc->attach(NULL, Serial::RxIrq); |
Swabey89 | 19:88d8359306a4 | 135 | serialqueue.call(serialData); |
Swabey89 | 11:3ad0327e8c9f | 136 | } |
Swabey89 | 1:31c7b4ab552b | 137 | |
Swabey89 | 19:88d8359306a4 | 138 | void serialData() |
Swabey89 | 12:3a54cbaa714c | 139 | { |
Swabey89 | 17:ead43c1b729d | 140 | static int i = 0; |
Swabey89 | 11:3ad0327e8c9f | 141 | if (pc->readable()) |
Swabey89 | 11:3ad0327e8c9f | 142 | { |
Swabey89 | 18:3edfb9152b05 | 143 | cmdBuffer[i] = pc->getc(); |
Swabey89 | 18:3edfb9152b05 | 144 | if (cmdBuffer[i] == '\r') |
Swabey89 | 11:3ad0327e8c9f | 145 | { |
Swabey89 | 11:3ad0327e8c9f | 146 | i = 0; |
Swabey89 | 18:3edfb9152b05 | 147 | serialqueue.call(serialterm); |
Swabey89 | 11:3ad0327e8c9f | 148 | } |
Swabey89 | 11:3ad0327e8c9f | 149 | else i++; |
Swabey89 | 11:3ad0327e8c9f | 150 | } |
Swabey89 | 11:3ad0327e8c9f | 151 | pc->attach(serialISR, Serial::RxIrq); |
Swabey89 | 11:3ad0327e8c9f | 152 | } |
Swabey89 | 19:88d8359306a4 | 153 | |
Swabey89 | 19:88d8359306a4 | 154 | |
Swabey89 | 19:88d8359306a4 | 155 | void sampleProducer() |
Swabey89 | 19:88d8359306a4 | 156 | { |
Swabey89 | 19:88d8359306a4 | 157 | while(true) |
Swabey89 | 19:88d8359306a4 | 158 | { |
Swabey89 | 19:88d8359306a4 | 159 | //High priority thread |
Swabey89 | 27:bb8d4c883e1b | 160 | Thread::signal_wait(TAKE_SAMPLE); |
Swabey89 | 19:88d8359306a4 | 161 | //int32_t Nspaces = spaceAvailable.wait(); //Blocking if space is not available //Dont check if there is space available becuase we are overwriting |
Swabey89 | 27:bb8d4c883e1b | 162 | |
Swabey89 | 19:88d8359306a4 | 163 | bufferLock.lock(); |
Swabey89 | 27:bb8d4c883e1b | 164 | //Update buffer |
Swabey89 | 19:88d8359306a4 | 165 | buffer[newestIndex].updatetemp(sensor.getTemperature()); |
Swabey89 | 19:88d8359306a4 | 166 | buffer[newestIndex].updatepress(sensor.getPressure()); |
Swabey89 | 19:88d8359306a4 | 167 | buffer[newestIndex].updatelight(adcIn.read()); |
Swabey89 | 27:bb8d4c883e1b | 168 | buffer[newestIndex].updateTime(); |
Swabey89 | 27:bb8d4c883e1b | 169 | newestIndex = (newestIndex+1) % BUFFERSIZE; //CIRCULAR |
Swabey89 | 19:88d8359306a4 | 170 | //bufferLock.unlock(); //normally here, moved due to updating queues. |
Swabey89 | 27:bb8d4c883e1b | 171 | samplesInBuffer.release(); |
Swabey89 | 27:bb8d4c883e1b | 172 | |
Swabey89 | 27:bb8d4c883e1b | 173 | if (newestIndex == oldestIndex) |
Swabey89 | 27:bb8d4c883e1b | 174 | { |
Swabey89 | 27:bb8d4c883e1b | 175 | oldestIndex = (oldestIndex+1) % BUFFERSIZE; |
Swabey89 | 27:bb8d4c883e1b | 176 | } |
Swabey89 | 27:bb8d4c883e1b | 177 | |
Swabey89 | 19:88d8359306a4 | 178 | //Pass onto queues |
Swabey89 | 27:bb8d4c883e1b | 179 | LCDqueue.call(LCD_display, buffer[newestIndex-1].gettemp(),buffer[newestIndex-1].getpress(),buffer[newestIndex-1].getlight()); |
Swabey89 | 19:88d8359306a4 | 180 | bufferLock.unlock(); |
Swabey89 | 19:88d8359306a4 | 181 | |
Swabey89 | 27:bb8d4c883e1b | 182 | if (newestIndex == ((saveIndex + 60) % BUFFERSIZE)) //correct? |
Swabey89 | 19:88d8359306a4 | 183 | { |
Swabey89 | 19:88d8359306a4 | 184 | //save to SD card |
Swabey89 | 19:88d8359306a4 | 185 | consumer_thread.signal_set(STORE_DATA); |
Swabey89 | 19:88d8359306a4 | 186 | |
Swabey89 | 19:88d8359306a4 | 187 | } |
Swabey89 | 19:88d8359306a4 | 188 | } |
Swabey89 | 19:88d8359306a4 | 189 | } |
Swabey89 | 19:88d8359306a4 | 190 | |
Swabey89 | 19:88d8359306a4 | 191 | void sampleConsumer() |
Swabey89 | 19:88d8359306a4 | 192 | { |
Swabey89 | 19:88d8359306a4 | 193 | while(true) |
Swabey89 | 19:88d8359306a4 | 194 | { |
Swabey89 | 19:88d8359306a4 | 195 | |
Swabey89 | 19:88d8359306a4 | 196 | static time_t seconds; |
Swabey89 | 19:88d8359306a4 | 197 | |
Swabey89 | 26:94238a308ff9 | 198 | //write to the SD card from oldestindex up to newestIndex. |
Swabey89 | 19:88d8359306a4 | 199 | Thread::signal_wait(STORE_DATA); |
Swabey89 | 19:88d8359306a4 | 200 | redLED = 1; |
Swabey89 | 19:88d8359306a4 | 201 | |
Swabey89 | 19:88d8359306a4 | 202 | char fileDate[30]; |
Swabey89 | 25:831dc928ccde | 203 | timeLock.lock(); |
Swabey89 | 19:88d8359306a4 | 204 | seconds = time(NULL); |
Swabey89 | 19:88d8359306a4 | 205 | timeData = localtime(&seconds); |
Swabey89 | 19:88d8359306a4 | 206 | set_time(mktime(timeData)); |
Swabey89 | 23:f87fe0c55894 | 207 | strftime(fileDate, 30, "sd/log_%d_%m_%y.csv", timeData); |
Swabey89 | 25:831dc928ccde | 208 | timeLock.unlock(); |
Swabey89 | 19:88d8359306a4 | 209 | fp = fopen(fileDate,"a"); |
Swabey89 | 23:f87fe0c55894 | 210 | if (fp == NULL) |
Swabey89 | 23:f87fe0c55894 | 211 | { |
Swabey89 | 25:831dc928ccde | 212 | printlock.lock(); |
Swabey89 | 25:831dc928ccde | 213 | pc->printf("WARNING: SD card could not be updated\n\r"); |
Swabey89 | 25:831dc928ccde | 214 | printlock.unlock(); |
Swabey89 | 19:88d8359306a4 | 215 | } |
Swabey89 | 23:f87fe0c55894 | 216 | else |
Swabey89 | 23:f87fe0c55894 | 217 | { |
Swabey89 | 25:831dc928ccde | 218 | //Nested locks probably a bad idea! |
Swabey89 | 25:831dc928ccde | 219 | bufferLock.lock(); |
Swabey89 | 25:831dc928ccde | 220 | SDlock.lock(); |
Swabey89 | 27:bb8d4c883e1b | 221 | //read first then update oldestIndex? |
Swabey89 | 27:bb8d4c883e1b | 222 | int i = 0; |
Swabey89 | 27:bb8d4c883e1b | 223 | |
Swabey89 | 27:bb8d4c883e1b | 224 | while (saveIndex != newestIndex) |
Swabey89 | 27:bb8d4c883e1b | 225 | { |
Swabey89 | 27:bb8d4c883e1b | 226 | fprintf(fp,"%s,%5.2f,%5.2f,%5.2f\n\r", buffer[saveIndex].getTime(), buffer[saveIndex].gettemp(), buffer[saveIndex].getpress(), buffer[saveIndex].getlight()); |
Swabey89 | 27:bb8d4c883e1b | 227 | saveIndex = (saveIndex+1) % BUFFERSIZE; |
Swabey89 | 27:bb8d4c883e1b | 228 | i++; |
Swabey89 | 23:f87fe0c55894 | 229 | } |
Swabey89 | 25:831dc928ccde | 230 | SDlock.unlock(); |
Swabey89 | 25:831dc928ccde | 231 | bufferLock.unlock(); |
Swabey89 | 25:831dc928ccde | 232 | |
Swabey89 | 25:831dc928ccde | 233 | printlock.lock(); |
Swabey89 | 27:bb8d4c883e1b | 234 | pc->printf("SD card updated with %d samples\r\n", i); |
Swabey89 | 27:bb8d4c883e1b | 235 | pc->printf("oldestIndex : %d\n\r", oldestIndex); |
Swabey89 | 27:bb8d4c883e1b | 236 | pc->printf("newestIndex : %d\n\r", newestIndex); |
Swabey89 | 27:bb8d4c883e1b | 237 | pc->printf("saveIndex : %d\n\r", saveIndex); |
Swabey89 | 25:831dc928ccde | 238 | printlock.unlock(); |
Swabey89 | 23:f87fe0c55894 | 239 | } |
Swabey89 | 19:88d8359306a4 | 240 | fclose(fp); |
Swabey89 | 25:831dc928ccde | 241 | redLED = 0; |
Swabey89 | 19:88d8359306a4 | 242 | } |
Swabey89 | 19:88d8359306a4 | 243 | } |
Swabey89 | 24:81981815ef20 | 244 | |
Swabey89 | 24:81981815ef20 | 245 | //TEST FOR MOUNTING AND UNMOUNTING SD CARD |
Swabey89 | 24:81981815ef20 | 246 | //Interrupt service routine for handling the timeout |
Swabey89 | 24:81981815ef20 | 247 | |
Swabey89 | 24:81981815ef20 | 248 | |
Swabey89 | 24:81981815ef20 | 249 | void userswTimeOutHandler() { |
Swabey89 | 24:81981815ef20 | 250 | userswTimeOut.detach(); //Stop the timeout counter firing |
Swabey89 | 24:81981815ef20 | 251 | |
Swabey89 | 24:81981815ef20 | 252 | //Which event does this follow? |
Swabey89 | 24:81981815ef20 | 253 | switch (userswState) { |
Swabey89 | 24:81981815ef20 | 254 | case EDGE_RISEN: |
Swabey89 | 24:81981815ef20 | 255 | usersw.fall(&userswFallingEdge); //Now wait for a falling edge |
Swabey89 | 24:81981815ef20 | 256 | break; |
Swabey89 | 24:81981815ef20 | 257 | case EDGE_FALLEN: |
Swabey89 | 24:81981815ef20 | 258 | usersw.rise(&userswRisingEdge); //Now wait for a rising edge |
Swabey89 | 24:81981815ef20 | 259 | break; |
Swabey89 | 24:81981815ef20 | 260 | } //end switch |
Swabey89 | 24:81981815ef20 | 261 | } |
Swabey89 | 24:81981815ef20 | 262 | |
Swabey89 | 24:81981815ef20 | 263 | //Interrupt service routine for a rising edge (press) |
Swabey89 | 24:81981815ef20 | 264 | void userswRisingEdge() { |
Swabey89 | 24:81981815ef20 | 265 | usersw.rise(NULL); //Disable detecting more rising edges |
Swabey89 | 24:81981815ef20 | 266 | userswState = EDGE_RISEN; //Flag state |
Swabey89 | 24:81981815ef20 | 267 | userswTimeOut.attach(&userswTimeOutHandler, 0.2); //Start timeout timer |
Swabey89 | 24:81981815ef20 | 268 | } |
Swabey89 | 24:81981815ef20 | 269 | |
Swabey89 | 24:81981815ef20 | 270 | //Interrupt service routive for SW1 falling edge (release) |
Swabey89 | 24:81981815ef20 | 271 | void userswFallingEdge() { |
Swabey89 | 24:81981815ef20 | 272 | usersw.fall(NULL); //Disable this interrupt |
Swabey89 | 24:81981815ef20 | 273 | SDmount_thread.signal_set(SIGNAL_SD); |
Swabey89 | 24:81981815ef20 | 274 | userswState = EDGE_FALLEN; //Flag state |
Swabey89 | 24:81981815ef20 | 275 | userswTimeOut.attach(&userswTimeOutHandler, 0.2); //Start timeout counter - may want to increase this |
Swabey89 | 24:81981815ef20 | 276 | } |