Proj 324 Final

Fork of ELEC351_Group_T by Plymouth ELEC351 Group T

main.cpp

Committer:
chills
Date:
2017-12-20
Revision:
14:45630ba388e1
Parent:
13:db857b3744c6

File content as of revision 14:45630ba388e1:

/*
ELEC 351 Group T
Team Members : Christopher Hills, Thomas Morris
Current Verision 3
Overiew: Working Tasks 1,5,7

Last Revision: Added Mail Box to serial
Todo:
make a mailbox within SD card, LCD, network so they can be used from within
Fix the network so it uses the mail box data.
Place the LCD write functions in their own function
*/

//Includes and Definitions
#include "sample_hardware.hpp"
#include "Networkbits.hpp"
#include "rtos.h"
#include "LED.hpp"
#include "DATA.hpp"
#include "NETWORK.hpp"
#define SamplingTime 1
#define NotSamplingTime 0
#define Print_Time_to_LCD 1
#define Dont_Print_Time_to_LCD 0
#define TimerInterval 15 //This is in seconds
#define EDGE_RISEN 1
#define EDGE_FALLEN 0


Serial pc(USBTX, USBRX);
//SW1+SW2 are declared as interrupt ins in sample hardwarec.pp


//Thread IDs
osThreadId idMain;
osThreadId id1;
osThreadId id2;
osThreadId id3;
osThreadId id4;

Timeout sw1TimeOut;//Used to prevent switch bounce

LED Red_led(PE_15);
LED Yellow_led(PB_10);
LED Green_led(PB_11);

//Tickers

Ticker Sample_timer;

//Threads
Thread t1;
Thread t2;
Thread t3;
Thread t4;
Thread t5;
Thread t6;

double temp = 0;
double pressure = 0;
double lux = 0;
string buffer_time = 0;

char buffer[32];
        

void SW1FallingEdge();
void SW1TimeOutHandler();

int mode = 0;

Mail<DATA, 120> mail_box_network;           //Mail Queue, Type DATA, Capacity 120, name mail_box_network
Mail<DATA, 120> mail_box_sd;                //Mail Queue, Type DATA, Capacity 120, name mail_box_sd
Mail<DATA, 120> mail_box_lcd;               //Mail Queue, Type DATA, Capacity 120, name mail_box_lcd
Mail<DATA, 120> mail_box_serial;            //Mail Queue, Type DATA, Capacity 120, name mail_box_serial

void Network()                                  //Interrupt service routine for handling the timeout
{
    osEvent evt_network = mail_box_network.get();                        //Get the latest entry from "mail_box"
        
    if (evt_network.status == osEventMail)
    {
        DATA *Rec_Data_Network = (DATA*)evt_network.value.p;
        DATA msg_network;
            
        msg_network.set_time(Rec_Data_Network->get_time());
        msg_network.set_temperature(Rec_Data_Network->get_temperature());
        msg_network.set_pressure(Rec_Data_Network->get_pressure());
        msg_network.set_light(Rec_Data_Network->get_light());
    
        //NETWORK_Print();     //Runs the network
    }                                                
}

void SW1TimeOutHandler() 
{
    sw1TimeOut.detach();        //Stop the timeout counter firing
    SW1.fall(&SW1FallingEdge);  //Now wait for a falling edge
}
void SDWrite()//End of skype chat
{
    osEvent evt_sd = mail_box_sd.get();                        //Get the latest entry from "mail_box"
        
    if (evt_sd.status == osEventMail)
    {
        DATA *Rec_Data_SD = (DATA*)evt_sd.value.p;
        DATA msg_sd;
            
        msg_sd.set_time(Rec_Data_SD->get_time());
        msg_sd.set_temperature(Rec_Data_SD->get_temperature());
        msg_sd.set_pressure(Rec_Data_SD->get_pressure());
        msg_sd.set_light(Rec_Data_SD->get_light());
    }    
}
//Interrupt service routive for SW1 falling edge (release)
void SW1FallingEdge() {
    SW1.fall(NULL);                             //Disable this interrupt
    Yellow_led.Toggle();                         //Toggle LED  
    
    mode = mode +1;//Cycles through modes
    if(mode >1)
    {
     mode = 0;   
    }
      
    sw1TimeOut.attach(&SW1TimeOutHandler, 0.2); //Start timeout counter    
}

void ModeSelection()
{
    while(1){

        Thread::wait(1000);
        
        osEvent evt_lcd = mail_box_lcd.get();                        //Get the latest entry from "mail_box"
        
        if (evt_lcd.status == osEventMail)
        {
            DATA *Rec_Data_LCD = (DATA*)evt_lcd.value.p;
            DATA msg_lcd;
            
            msg_lcd.set_time(Rec_Data_LCD->get_time());
            msg_lcd.set_temperature(Rec_Data_LCD->get_temperature());
            msg_lcd.set_pressure(Rec_Data_LCD->get_pressure());
            msg_lcd.set_light(Rec_Data_LCD->get_light());

            
            if(mode == 0)//Print values to the LCD
            {
                //Write new data to LCD (not fast!)
                lcd.cls();
                lcd.printf("Temp Pres  li\n"); 
                lcd.printf("%1.1f ",    msg_lcd.get_temperature());     //Print Temperature to LCD
                lcd.printf("%1.1f ",    msg_lcd.get_pressure());        //Print Pressure to LCD
                lcd.printf("%1.1f\n",   msg_lcd.get_light());           //Print Light to LCD
            }
            else if(mode == 1)//Print the Time to the LCD
            {
                lcd.cls();                              //Write new data to LCD (not fast!)
                lcd.printf("Current Time:%s", buffer);
            }
            else
            {
                mode = 0;
            }
        }
    }
}

void PrintTime()
{
    Thread::signal_wait(Print_Time_to_LCD);
    while(1)
    {
        //lcd.printf("Current Time: \n %s", buffer);
        Thread::wait(1000);//Waits the thread for 1 second
    }
}
void Time()
{
    while (true) 
    {
        time_t seconds = time(NULL);
        //pc.printf("Time as seconds since January 1, 1970 = %d\n", seconds);       
        //pc.printf("Time as a basic string = %s", ctime(&seconds));
        strftime(buffer, 32, "%I:%M %p\n", localtime(&seconds));
        pc.printf("Current Time:%s", buffer);
        
        Thread::wait(1000);
    }   
}


void Serial_Comms()//Thread for Serial Communications
{
    pc.printf("Hello World \n");
    while(1)
    {
        osEvent evt_serial = mail_box_serial.get();                                   //Get the latest entry from "mail_box"
        
        if (evt_serial.status == osEventMail)
        {
            DATA *Rec_Data_Serial = (DATA*)evt_serial.value.p;
            DATA msg_serial;
            
            msg_serial.set_time(Rec_Data_Serial->get_time());
            msg_serial.set_temperature(Rec_Data_Serial->get_temperature());
            msg_serial.set_pressure(Rec_Data_Serial->get_pressure());
            msg_serial.set_light(Rec_Data_Serial->get_light());  
            
            pc.printf("Time = %d\t", msg_serial.get_time());                   //Print Time
            pc.printf("Temperature = %f\t", msg_serial.get_temperature());     //Print Temperature
            pc.printf("Pressure = %f\t", msg_serial.get_pressure());           //Print Pressure
            pc.printf("Light = %f\n\r", msg_serial.get_light());               //Print Light
        }
        Green_led.Toggle();
        Thread::wait(1000);   
    }
}

void Sample_signal_set()            //Sets the Signal for when to sample the sensors
{
    t1.signal_set(SamplingTime);    //Set the sampling thread signal high
}


void Sample()//Samples the hardware and prints the result to the LCD
{
    while(1)
    {     
        Thread::signal_wait(SamplingTime);      //Set the time between samples
            
        temp = sensor.getTemperature();         //Read Temperature
        pressure = sensor.getPressure();        //Read Pressure
        lux = adcIn.read();                     //Read Light
        buffer_time = buffer;                   //Read Time
        
        DATA *Send_Data_network = mail_box_network.alloc();           //Allocate a block from the memory pool, Type Data
        DATA *Send_Data_sd      = mail_box_sd.alloc();                //Allocate a block from the memory pool, Type Data
        DATA *Send_Data_lcd     = mail_box_lcd.alloc();               //Allocate a block from the memory pool, Type Data
        DATA *Send_Data_serial  = mail_box_serial.alloc();            //Allocate a block from the memory pool, Type Data
        
        if (Send_Data_network ==  NULL){return;}
        if (Send_Data_sd      ==  NULL){return;}
        if (Send_Data_lcd     ==  NULL){return;}
        if (Send_Data_serial  ==  NULL){return;}
        
        Send_Data_network->set_time(buffer_time);   Send_Data_sd->set_time(buffer_time);    Send_Data_lcd->set_time(buffer_time);   Send_Data_serial->set_time(buffer_time);       //Pass in Time
        Send_Data_network->set_temperature(temp);   Send_Data_sd->set_temperature(temp);    Send_Data_lcd->set_temperature(temp);   Send_Data_serial->set_temperature(temp);       //Pass in Temp
        Send_Data_network->set_pressure(pressure);  Send_Data_sd->set_pressure(pressure);   Send_Data_lcd->set_pressure(pressure);  Send_Data_serial->set_pressure(pressure);      //Pass in Pres
        Send_Data_network->set_light(lux);          Send_Data_sd->set_light(lux);           Send_Data_lcd->set_light(lux);          Send_Data_serial->set_light(lux);              //Pass in Light                                                        //Pass in Light
        
        osStatus stat_network = mail_box_network.put(Send_Data_network);        //Puts "Send_Data" into the mailbox
        if (stat_network == osErrorResource){                           //If mailbox overfills
            mail_box_network.free(Send_Data_network);                   //Free the mail box
            return;
        }
        osStatus stat_sd = mail_box_sd.put(Send_Data_sd);             //Puts "Send_Data" into the mailbox
        if (stat_sd == osErrorResource){                           //If mailbox overfills
            mail_box_sd.free(Send_Data_sd);                        //Free the mail box
            return;
        }
        osStatus stat_lcd = mail_box_lcd.put(Send_Data_lcd);            //Puts "Send_Data" into the mailbox
        if (stat_lcd == osErrorResource){                           //If mailbox overfills
            mail_box_lcd.free(Send_Data_lcd);                       //Free the mail box
            return;
        }   
        osStatus stat_serial = mail_box_serial.put(Send_Data_serial);         //Puts "Send_Data" into the mailbox
        if (stat_serial == osErrorResource){                           //If mailbox overfills
            mail_box_serial.free(Send_Data_serial);                    //Free the mail box
            return;
        }
        
        
        Red_led.Toggle();
        t1.signal_set(NotSamplingTime);
    }
} 

int main() 
{  
    //Greeting
    printf("Testing\n\n");    
    set_time(1512940530);               //Set RTC time to December 10 2017
    pc.baud(9600);                      //Sets the Serial Comms Baud Rate
    
    post();     //Power on Self Test
    
    //Initialise the SD card (this needs to move)
    if ( sd.init() != 0) {
        printf("Init failed \n");
        lcd.cls();
        lcd.printf("CANNOT INIT SD");        
        errorCode(FATAL);
    } 
    
    //Create a filing system for SD Card
    FATFileSystem fs("sd", &sd);     

    //Open to WRITE
    FILE* fp = fopen("/sd/test.csv","a");
    if (fp == NULL) {
        error("Could not open file for write\n");
        lcd.cls();
        lcd.printf("CANNOT OPEN FILE\n\n");
        errorCode(FATAL);
    }
    
    //Last message before sampling begins
    lcd.cls();
    lcd.printf("READY\n\n");
    
    //Run interrupt
    Sample_timer.attach(&Sample_signal_set,TimerInterval);
    SW1.fall(&SW1FallingEdge);
    //Run Threads
    
    t1.start(Sample);
    t2.start(Serial_Comms);
    t3.start(Time);
    t4.start(PrintTime);
    t5.start(ModeSelection);
    t6.start(Network);
    //Main thread ID
    
    idMain = osThreadGetId();   //CMSIS RTOS call
    
    //Thread ID
    id1 = t1.gettid();
    id2 = t2.gettid();
    id3 = t3.gettid();
    id4 = t4.gettid();
    //id5 = t5.gettid();
    
    //Toggle Green LED after a button has been pressed
    //Press either switch to unmount
    DigitalIn  onBoardSwitch(USER_BUTTON);
    while (onBoardSwitch == 0){
        
    }
    
    //Close File
    fclose(fp);
    
    //Close down
    sd.deinit();
    printf("Unmounted...\n");
    lcd.cls();
    lcd.printf("Unmounted...\n\n");
    
    while(true) {
        greenLED = 1;
        wait(0.5);
        greenLED = 0;
        wait(0.1);    
    }
}