Proj 324 Final

Fork of ELEC351_Group_T by Plymouth ELEC351 Group T

main.cpp

Committer:
chills
Date:
2017-12-20
Revision:
10:46946784326d
Parent:
8:0e4481b64353
Child:
11:e7b5ed6cd3cf

File content as of revision 10:46946784326d:

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

Last Revision: Added DATA class structure
Todo:
make a mailbox of DATA class 120 long
*/

//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;       //Mail Queue, Type DATA, Capacity 120, name mail_box

void Network()
{
    NETWORK_Print();//Runs the network
 //Send DATA to the network   
}//Interrupt service routine for handling the timeout
void SW1TimeOutHandler() 
{
    sw1TimeOut.detach();        //Stop the timeout counter firing
    SW1.fall(&SW1FallingEdge);  //Now wait for a falling edge
}

//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);
        //Detech the not required interrupt then rettach it when finshed
        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 ",temp);
        lcd.printf("%1.1f ",pressure);
        lcd.printf("%1.1f\n",lux);
        }
        else if(mode == 1)//Print the Time to the LCD
        {
                    //Write new data to LCD (not fast!)
        lcd.cls();
        
        lcd.printf("Current Time:%s", buffer);
        
        //Write to SD (potentially slow)
        //fprintf(fp, "%6.1f,%.2f\n\r", temp, pressure);
        }
        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 = mail_box.get();   //Get the latest entry from "mail_box"
        
        if (evt.status == osEventMail){
            DATA *Rec_Data = (DATA*)evt.value.p;  
            pc.printf("Time = %d\t", Rec_Data->get_time());                 //Print Time
            pc.printf("Temperature = %f", Rec_Data->get_temperature());     //Print Temperature
            pc.printf("Pressure = %f", Rec_Data->get_pressure());           //Print Pressure
            pc.printf("Light = %f", Rec_Data->get_light());                 //Print Light
        }
        
        pc.printf("Test\n");//Use this Line to output a string to Putty
        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 = mail_box.alloc();           //Allocate a block from the memory pool, Type Data
        
        if (Send_Data ==  NULL){                     //If Data is empty
            //pc.printf("Out of memory\n\r");     //Print out of memory warning
            return;
        }
        
        Send_Data->set_time(buffer_time);       //Pass in Time
        Send_Data->set_temperature(temp);       //Pass in Temp
        Send_Data->set_pressure(pressure);      //Pass in Pres
        Send_Data->set_light(lux);              //Pass in Light
        
        osStatus stat = mail_box.put(Send_Data);    //Puts "Send_Data" into the mailbox
        
        if (stat == osErrorResource){   //If mailbox overfills
            //pc.printf("queue->put() Error code: %4Xh, Resource not available\r\n", stat);      //Print error message
            mail_box.free(Send_Data);   //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);    
    }
}