Latest

Dependencies:   serial_terminal sample_hardware PLL_Config SDCard BMP280 Networkbits TextLCD SDBlockDevice

Revision:
19:88d8359306a4
Parent:
18:3edfb9152b05
Child:
20:cdde0663c481
--- a/main.cpp	Fri Nov 30 14:39:10 2018 +0000
+++ b/main.cpp	Mon Dec 17 16:11:07 2018 +0000
@@ -7,27 +7,88 @@
 #include "events/mbed_events.h"
 #include "LCDdisplay.hpp"
 
+//Defines
+#define BUFFERSIZE 120
+
 //Signals
 #define TAKE_SAMPLE 1
+#define STORE_DATA 2
 
 //Global variables
-float sample_rate = 15;
+
+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
+//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 sample_thread(osPriorityHigh);
-Thread serialthread(osPriorityAboveNormal);
+Thread producer_thread(osPriorityHigh);
+Thread consumer_thread;
+Thread serial_thread(osPriorityAboveNormal);
 Thread SDqueue_thread;
 Thread LCDqueue_thread;
 
@@ -36,10 +97,10 @@
 
 //Function prototypes
 void sampleISR(void);
-void takesample(void);
-void samples(void);
+void sampleProducer(void);
+void sampleConsumer(void);
 void serialISR(void);
-void serialiser(void);
+void serialData(void);
 
 int main() {   
     timeData = new tm;
@@ -54,8 +115,9 @@
     //Start threads
     SDqueue_thread.start(callback(&SDqueue, &EventQueue::dispatch_forever));
     LCDqueue_thread.start(callback(&LCDqueue, &EventQueue::dispatch_forever));
-    serialthread.start(callback(&serialqueue, &EventQueue::dispatch_forever));
-    sample_thread.start(samples);
+    serial_thread.start(callback(&serialqueue, &EventQueue::dispatch_forever));
+    producer_thread.start(sampleProducer);
+    consumer_thread.start(sampleConsumer);
     
     //Attach ISRs
     sample.attach(&sampleISR, sample_rate);    
@@ -68,37 +130,22 @@
     }
 }
 
+/*
+FUNCITONS BELOW NEED MOVING?
+*/
+
 void sampleISR()
 {
-    sample_thread.signal_set(TAKE_SAMPLE);   
-}
-
-void samples()
-{
-    while(true)
-    {
-        //High priority thread 
-        Thread::signal_wait(TAKE_SAMPLE);
-        
-        //needs to be a class at some point
-        //read time also
-        double temp = sensor.getTemperature();
-        double pressure = sensor.getPressure();
-        float light = adcIn.read();
-        
-        //Pass onto queues
-        LCDqueue.call(LCD_display,temp,pressure,light);
-        SDqueue.call(SDaddSample,temp,pressure);
-    }
+    producer_thread.signal_set(TAKE_SAMPLE);   
 }
     
 void serialISR()
 {
     pc->attach(NULL, Serial::RxIrq);
-    serialqueue.call(serialiser);
+    serialqueue.call(serialData);
 }
 
-void serialiser()
+void serialData()
 {    
     static int i = 0;
     if (pc->readable())
@@ -113,3 +160,70 @@
     }
     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");
+    }   
+}