Latest

Dependencies:   serial_terminal sample_hardware PLL_Config SDCard BMP280 Networkbits TextLCD SDBlockDevice

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?

UserRevisionLine numberNew 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 }