Latest
Dependencies: serial_terminal sample_hardware PLL_Config SDCard BMP280 Networkbits TextLCD SDBlockDevice
main.cpp
- Committer:
- Swabey89
- Date:
- 2018-12-22
- Revision:
- 28:7fccaef8fa72
- Parent:
- 27:bb8d4c883e1b
- Child:
- 29:806e9281af2f
File content as of revision 28:7fccaef8fa72:
#include "mbed.h" #include "sample_hardware.hpp" #include "Networking.hpp" #include "serial_terminal.hpp" #include "SDCard.hpp" #include "rtos.h" #include "events/mbed_events.h" #include "LCDdisplay.hpp" //Defines TEST FOR SD CARD MOUNT AND UNMOUNT #define EDGE_FALLEN 0 #define EDGE_RISEN 1 //Signals #define TAKE_SAMPLE 1 #define STORE_DATA 2 //Global variables unsigned int newestIndex = BUFFERSIZE-1; //First time it is incremented, it will be 0 unsigned int oldestIndex = BUFFERSIZE-1; FILE* fp; FATFileSystem* fs; //Shared mutable variables VOLATILE bool sd_init; //is it? bool logging = false; float sample_rate = 15; //is it? struct tm* timeData; char cmdBuffer[256]; sensorData buffer[BUFFERSIZE]; RawSerial* pc; //Thread synchronisation primatives Semaphore spaceAvailable(BUFFERSIZE); Semaphore samplesInBuffer(0, BUFFERSIZE); Mutex bufferLock; //Queues EventQueue SDqueue(32*EVENTS_EVENT_SIZE); EventQueue LCDqueue(32*EVENTS_EVENT_SIZE); EventQueue serialqueue(32*EVENTS_EVENT_SIZE); //Threads Thread producer_thread(osPriorityHigh); Thread consumer_thread; Thread serial_thread(osPriorityAboveNormal); Thread SDqueue_thread; //remove Thread LCDqueue_thread; Thread Network_thread; //TEST FOR SD CARD Thread SDmount_thread; //Timers Ticker sample; //Function prototypes void sampleISR(void); void sampleProducer(void); void sampleConsumer(void); void serialISR(void); void serialData(void); //TEST FOR SD CARD MOUNT AND UNMOUNT Timeout userswTimeOut; int userswState = EDGE_FALLEN; InterruptIn usersw(USER_BUTTON); void userswTimeOutHandler(); void userswRisingEdge(); void userswFallingEdge(); void SDmount(); Mutex printlock; Mutex LCDlock; Mutex timeLock; Mutex SDlock; //TEST FOR BUFFER CHANGES unsigned int saveIndex = BUFFERSIZE-1; int32_t Nspaces = BUFFERSIZE; int32_t Nsamples; int main() { timeData = new tm; pc = new RawSerial(USBTX, USBRX); //Initialisations SDcard(); //Power on self test post(); //Start threads SDqueue_thread.start(callback(&SDqueue, &EventQueue::dispatch_forever)); LCDqueue_thread.start(callback(&LCDqueue, &EventQueue::dispatch_forever)); serial_thread.start(callback(&serialqueue, &EventQueue::dispatch_forever)); Network_thread.start(network); producer_thread.start(sampleProducer); consumer_thread.start(sampleConsumer); //TEST FOR SD CARD SDmount_thread.start(SDmount); //Attach ISRs sample.attach(&sampleISR, sample_rate); //Allow sampling to start pc->attach(serialISR, Serial::RxIrq); //TEST FOR SD CARD MOUNT AND UNMOUNT usersw.rise(&userswRisingEdge); //Flash to indicate goodness while(true) { greenLED = !greenLED; Thread::wait(500); } } /* FUNCITONS BELOW NEED MOVING? */ void sampleISR() { producer_thread.signal_set(TAKE_SAMPLE); } void serialISR() { pc->attach(NULL, Serial::RxIrq); serialqueue.call(serialData); } void serialData() { static int i = 0; if (pc->readable()) { cmdBuffer[i] = pc->getc(); if (cmdBuffer[i] == '\r') { cmdBuffer[i+1]==NULL; serialqueue.call(serialterm); i = 0; } else i++; } pc->attach(serialISR, Serial::RxIrq); } void sampleProducer() { while(true) { //High priority thread Thread::signal_wait(TAKE_SAMPLE); Nspaces = spaceAvailable.wait(0); //Non-blocking bufferLock.lock(); //Update buffer newestIndex = (newestIndex+1) % BUFFERSIZE; //CIRCULAR if (newestIndex == oldestIndex) { oldestIndex = (oldestIndex+1) % BUFFERSIZE; } buffer[newestIndex].updatetemp(sensor.getTemperature()); buffer[newestIndex].updatepress(sensor.getPressure()); buffer[newestIndex].updatelight(adcIn.read()); buffer[newestIndex].updateTime(); //bufferLock.unlock(); //normally here, moved due to updating queues. if (Nspaces != 0) { Nspaces--; } samplesInBuffer.release(); //Pass onto queues LCDqueue.call(LCD_display, buffer[newestIndex].gettemp(),buffer[newestIndex].getpress(),buffer[newestIndex].getlight()); if(logging) { printlock.lock(); pc->printf("%s: Sample placed in buffer at position %d\r\n", buffer[newestIndex].getTime(), newestIndex); pc->printf("Number of spaces available in buffer:%d\r\n\n",Nspaces); printlock.unlock(); } bufferLock.unlock(); } } void sampleConsumer() { while(true) { static time_t seconds; //possibly move into if(sd_init) //write to the SD card from oldestindex up to newestIndex. Nsamples = samplesInBuffer.wait(); //Block if no samples to take - acquires if (sd_init) { char fileDate[30]; timeLock.lock(); seconds = time(NULL); timeData = localtime(&seconds); //set_time(mktime(timeData)); strftime(fileDate, 30, "sd/log_%d_%m_%y.csv", timeData); timeLock.unlock(); fp = fopen(fileDate,"a"); if (fp == NULL) { printlock.lock(); pc->printf("WARNING: SD card could not be updated\r\n\n"); sd_init = false; printlock.unlock(); samplesInBuffer.release(); } else { //Nested locks probably a bad idea! bufferLock.lock(); SDlock.lock(); oldestIndex = (oldestIndex+1) % BUFFERSIZE; fprintf(fp,"%s,%5.2f,%5.2f,%5.2f\r", buffer[oldestIndex].getTime(), buffer[oldestIndex].gettemp(), buffer[oldestIndex].getpress(), buffer[oldestIndex].getlight()); SDlock.unlock(); if(logging) { printlock.lock(); pc->printf("Log file %s updated with sample from position %d in buffer\r\n",fileDate,oldestIndex); pc->printf("newestIndex position %d\r\n",newestIndex); pc->printf("oldestIndex position %d\r\n",oldestIndex); printlock.unlock(); } bufferLock.unlock(); fclose(fp); } redLED = 0; } else { samplesInBuffer.release(); } } } //TEST FOR MOUNTING AND UNMOUNTING SD CARD //Interrupt service routine for handling the timeout void userswTimeOutHandler() { userswTimeOut.detach(); //Stop the timeout counter firing //Which event does this follow? switch (userswState) { case EDGE_RISEN: usersw.fall(&userswFallingEdge); //Now wait for a falling edge break; case EDGE_FALLEN: usersw.rise(&userswRisingEdge); //Now wait for a rising edge break; } //end switch } //Interrupt service routine for a rising edge (press) void userswRisingEdge() { usersw.rise(NULL); //Disable detecting more rising edges userswState = EDGE_RISEN; //Flag state userswTimeOut.attach(&userswTimeOutHandler, 0.2); //Start timeout timer } //Interrupt service routive for SW1 falling edge (release) void userswFallingEdge() { usersw.fall(NULL); //Disable this interrupt SDmount_thread.signal_set(SIGNAL_SD); userswState = EDGE_FALLEN; //Flag state userswTimeOut.attach(&userswTimeOutHandler, 0.2); //Start timeout counter - may want to increase this }