Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: serial_terminal sample_hardware PLL_Config SDCard BMP280 Networkbits TextLCD SDBlockDevice
main.cpp
- Committer:
- Swabey89
- Date:
- 2018-12-19
- Revision:
- 24:81981815ef20
- Parent:
- 23:f87fe0c55894
- Child:
- 25:831dc928ccde
File content as of revision 24:81981815ef20:
#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;
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);
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();
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);
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')
{
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());
buffer[newestIndex].updateTime();
//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;
//DO THIS IF THE SD CARD IS INITIALISED
char fileDate[30];
seconds = time(NULL);
timeData = localtime(&seconds);
set_time(mktime(timeData));
strftime(fileDate, 30, "sd/log_%d_%m_%y.csv", timeData);
fp = fopen(fileDate,"a");
if (fp == NULL)
{
pc->printf("WARNING: SD card could not be updated\n\r");
}
else
{
for (int i = 0; i<BUFFERSIZE; i++)
{
fprintf(fp,"%s,%5.2f,%5.2f,%5.2f\n\r", buffer[i].getTime(), buffer[i].gettemp(), buffer[i].getpress(), buffer[i].getlight());
}
printf("SD card updated\r\n");
}
fclose(fp);
redLED = 0;
bufferLock.unlock();
}
}
//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
}
