Latest

Dependencies:   serial_terminal sample_hardware PLL_Config SDCard BMP280 Networkbits TextLCD SDBlockDevice

main.cpp

Committer:
Swabey89
Date:
2018-12-17
Revision:
19:88d8359306a4
Parent:
18:3edfb9152b05
Child:
20:cdde0663c481

File content as of revision 19:88d8359306a4:

#include "mbed.h"
#include "sample_hardware.hpp"
#include "Networkbits.hpp"
#include "serial_terminal.hpp"
#include "SDCard.hpp"
#include "rtos.h"
#include "events/mbed_events.h"
#include "LCDdisplay.hpp"

//Defines
#define BUFFERSIZE 120

//Signals
#define TAKE_SAMPLE 1
#define STORE_DATA 2

//Global variables

class sensorData
{
    private:
        double temperature;
        double pressure;
        float lightlevel;
        //time
    public:
        sensorData(void)
        {
            this->temperature = 0;
            this->pressure = 0;
            this->lightlevel = 0;
        }
        
        void updatetemp(double t)
        {
            this->temperature = t;  
        };
        
        void updatepress(double p)
        {
            this->pressure = p;
        };
        
        void updatelight(float l)
        {
            this->lightlevel = l;
        };
        
        double gettemp(void)
        {
           return this->temperature; 
        };
        
        double getpress(void)
        {
          return this->pressure;  
        };
        
        float getlight(void)
        {
          return this->lightlevel;  
        };
};


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
float sample_rate = 15;
struct tm* timeData;
char cmdBuffer[256];
sensorData buffer[BUFFERSIZE];
RawSerial* pc;

//Thread synchronisation primatives
Semaphore spaceAvailable(BUFFERSIZE);
Semaphore samplesInBuffer(0);
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;
Thread LCDqueue_thread;

//Timers
Ticker sample;

//Function prototypes
void sampleISR(void);
void sampleProducer(void);
void sampleConsumer(void);
void serialISR(void);
void serialData(void);

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));
    producer_thread.start(sampleProducer);
    consumer_thread.start(sampleConsumer);
    
    //Attach ISRs
    sample.attach(&sampleISR, sample_rate);    
    pc->attach(serialISR, Serial::RxIrq);
    
    //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')
        {
            i = 0;
            serialqueue.call(serialterm);                     
        }
        else i++;
    }
    pc->attach(serialISR, Serial::RxIrq);
}


void sampleProducer()
{
    while(true)
    {
        //High priority thread 
        Thread::signal_wait(TAKE_SAMPLE);
        
        //int32_t Nspaces = spaceAvailable.wait(); //Blocking if space is not available //Dont check if there is space available becuase we are overwriting
        bufferLock.lock();
        //Update buffer
        newestIndex = (newestIndex+1) % BUFFERSIZE;  //CIRCULAR
        buffer[newestIndex].updatetemp(sensor.getTemperature());
        buffer[newestIndex].updatepress(sensor.getPressure());
        buffer[newestIndex].updatelight(adcIn.read());
        //bufferLock.unlock(); //normally here, moved due to updating queues.
        samplesInBuffer.release();  
              
        //Pass onto queues
        LCDqueue.call(LCD_display, buffer[newestIndex].gettemp(),buffer[newestIndex].getpress(),buffer[newestIndex].getlight());
        bufferLock.unlock();
        
        //Write to the SD card when i have 120 samples in the buffer
        if (newestIndex == 119)
        {
            //save to SD card
            consumer_thread.signal_set(STORE_DATA);
            
        } 
            
        //pc->printf("%d\r\n", newestIndex);
        
    }
}

void sampleConsumer()
{
    while(true)
    {
        
        static time_t seconds;
        
        //write to the SD card from 0 up to newestIndex.
        Thread::signal_wait(STORE_DATA);
        bufferLock.lock();
        redLED = 1;
        
        char fileDate[30];
        seconds = time(NULL);
        timeData = localtime(&seconds);
        set_time(mktime(timeData));
        strftime(fileDate, 30, "sd/sampledata/%d_%m_%y.csv", timeData);
        
        fp = fopen(fileDate,"a");
        
        for (int i = 0; i<BUFFERSIZE; i++)
        {            
            fprintf(fp, "%6.1f,%.2f\n\r", buffer[i].gettemp(), buffer[i].getpress());  //just these for now          
        }
        
        fclose(fp);
        redLED = 0;
        bufferLock.unlock();
        printf("SD card updated\r\n");
    }   
}