Proj 324 Final

Fork of ELEC351_Group_T by Plymouth ELEC351 Group T

main.cpp

Committer:
thomasmorris
Date:
2017-12-30
Revision:
23:3c85d7f657a2
Parent:
22:eb4cc12087b2
Child:
24:7d2da96e05ad

File content as of revision 23:3c85d7f657a2:

/*
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 "SETUP.hpp"
void Network()                                  //Interrupt service routine for handling the timeout
{
    osEvent evt_network = mail_box.get();                        //Get the latest entry from "mail_box"
        
    if (evt_network.status == osEventMail)
    {
        DATA *Rec_Data_Network = (DATA*)evt_network.value.p;                    //Create pointer to mailbox
        DATA msg_network;                                                       //Create temporary instance of DATA class
            
        msg_network.set_time(Rec_Data_Network->get_time());                     //Copy time from mailbox to temporary instance
        msg_network.set_temperature(Rec_Data_Network->get_temperature());       //Copy temperature from mailbox to temporary instance
        msg_network.set_pressure(Rec_Data_Network->get_pressure());             //Copy pressure from mailbox to temporary instance
        msg_network.set_light(Rec_Data_Network->get_light());                   //Copy light from mailbox to temporary instance   
        mail_box.free(Rec_Data_Network);                                        //Free space in the mailbox (delete earliest sample taken)
    
        //networktest();//Run the network
    }                                                
}

void SW1TimeOutHandler() 
{
    sw1TimeOut.detach();        //Stop the timeout counter firing
    SW1.fall(&SW1FallingEdge);  //Now wait for a falling edge
}
void SDWrite()
{
    osEvent evt_sd = mail_box.get();                        //Get the latest entry from "mail_box"
        
    if (evt_sd.status == osEventMail)
    {
        DATA *Rec_Data_SD = (DATA*)evt_sd.value.p;                      //Create pointer to mailbox
        DATA msg_sd;                                                    //Create temporary instance of DATA class
            
        msg_sd.set_time(Rec_Data_SD->get_time());                       //Copy time from mailbox to temporary instance
        msg_sd.set_temperature(Rec_Data_SD->get_temperature());         //Copy temperature from mailbox to temporary instance
        msg_sd.set_pressure(Rec_Data_SD->get_pressure());               //Copy pressure from mailbox to temporary instance
        msg_sd.set_light(Rec_Data_SD->get_light());                     //Copy light from mailbox to temporary instance
        mail_box.free(Rec_Data_SD);                                     //Free space in the mailbox (delete earliest sample taken)
    }    
}
//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(100);//Wait the thread
        
        osEvent evt_lcd = mail_box.get();                        //Get the latest entry from "mail_box"
        
        if (evt_lcd.status == osEventMail)
        {
            DATA *Rec_Data_LCD = (DATA*)evt_lcd.value.p;                    //Create pointer to mailbox
            DATA msg_lcd;                                                   //Create temporary instance of DATA class
            
            msg_lcd.set_time(Rec_Data_LCD->get_time());                     //Copy time from mailbox to temporary instance
            msg_lcd.set_temperature(Rec_Data_LCD->get_temperature());       //Copy temperature from mailbox to temporary instance
            msg_lcd.set_pressure(Rec_Data_LCD->get_pressure());             //Copy pressure from mailbox to temporary instance
            msg_lcd.set_light(Rec_Data_LCD->get_light());                   //Copy light from mailbox to temporary instance
            mail_box.free(Rec_Data_LCD);                                    //Free space in the mailbox (delete earliest sample taken)
            
            if(mode == 0)//Print values to the LCD
            {
                //Write new data to LCD (not fast!)
                                      
                sprintf (LCD_buffer, "%1.1f %1.1f %1.1f",msg_lcd.get_temperature(),msg_lcd.get_pressure(),msg_lcd.get_light());//Used for converting to a sting
                
                //LCD.Display_Clear();
                LCD.DDRAM_Address(0x00);
                LCD.Write_String("Temp Pres  li");
                LCD.DDRAM_Address(0x40);
                
                LCD.Write_String(LCD_buffer);
                //LCD.Write_String("Temp Pres  li\n");
                //LCD.Write_String("%1.1f ",    msg_lcd.get_temperature());//Print Temperature to LCD
                //LCD.Write_String("%1.1f ",    msg_lcd.get_pressure());//Print Pressure to LCD
                //LCD.Write_String("%1.1f\n",   msg_lcd.get_light()); //Print Light to LCD
                
            }
            else if(mode == 1)//Print the Time to the LCD
            {
                time_t msel_time = msg_lcd.get_time();                                  //Declare local variable for time
                strftime(scom_time_buffer, 32, "%I:%M %p", localtime(&msel_time));     //Format time as a string
                LCD.Display_Clear();
                sprintf (LCD_buffer, "%s",scom_time_buffer);
                LCD.DDRAM_Address(0x00);
                LCD.Write_String("Current Time:");
                LCD.DDRAM_Address(0x40);
                LCD.Write_String(LCD_buffer);

            }
            else
            {
                mode = 0;
            }
        }
    }
}

void Check_Serial_Input()
{
    t6.signal_set(1);
    while(1)
    {
        Thread::signal_wait(1);
        Thread::wait(100);//Waits 100ms
        cout << "In Check_Serial_Input" << endl;
        cin >> Serial_Enter_Check;//Only run this if Seriak Commands input is finished
        if (Serial_Enter_Check == "c")
        {
            t5.signal_set(SerialTime);
            t2.signal_set(0);
            //Run Serial Commands window and stop the printing of the last command
            Serial_Enter_Check = "0";   
        }
        else
        {
            t6.signal_set(1);   
        }
    }
       
}
void Serial_Commands()
{
    while(1)
    {   
        t5.signal_set(NotSerialTime);
        Thread::signal_wait(SerialTime);
        cout << "Please type in a Serial command" << endl;
        //Mutex this
        Sample_timer.detach();
        t6.signal_set(0);
        cin >> Serial_Input;
        t6.signal_set(1);
        if (Serial_Input == "Test")
        {
            cout << "Testing Serial Comms" <<endl;
        }
        else if(Serial_Input == "READALL")
        {
            Serial_timer.attach(&Serial_Comms_set,1);
        }
        else if(Serial_Input == "DELETE_ALL")
        {
        
        }
        else if(Serial_Input == "READ_<n>")
        {
        
        }
        else if(Serial_Input == "DELETE_<n>")
        {
        
        }
        else if(Serial_Input == "SETDATE_<dd>_<mm>_<yyyy>")
        {
        
        }
        else if(Serial_Input == "SETT_<T>")
        {
        
        }
        else if(Serial_Input == "STATE_<x>")
        {
        
        }
        else if(Serial_Input == "LOGGING_<x>")
        {
        
        }
        else if(Serial_Input == "HELP")// Use this to display all of the availble commands   
        {
            HELP();   
        }    
        else
        {
            cout << "Please enter a acceptable command" << endl;    
        }
    }
}
void Serial_Comms()//Thread for Serial Communications //Alter this function
{
    //cout << "In Serial Comms" << endl;
    while(1)
    {
        cout << "In Serial Comms" << endl;
        Thread::signal_wait(SERIAL_COMMS);
        //t2.signal_set(SERIAL_COMMS);
        cout << "In Serial Comms 2" << endl;
        osEvent evt_serial = mail_box.get();                                   //Get the latest entry from "mail_box"
        
        if (evt_serial.status == osEventMail)
        {
            DATA *Rec_Data_Serial = (DATA*)evt_serial.value.p;                      //Create pointer to mailbox
            DATA msg_serial;                                                        //Create temporary instance of DATA class
            
            msg_serial.set_time(Rec_Data_Serial->get_time());                       //Copy time from mailbox to temporary instance
            msg_serial.set_temperature(Rec_Data_Serial->get_temperature());         //Copy teperature from mailbox to temporary instance
            msg_serial.set_pressure(Rec_Data_Serial->get_pressure());               //Copy pressure from mailbox to temporary instance
            msg_serial.set_light(Rec_Data_Serial->get_light());                     //Copy light from mailbox to temporary instance
            mail_box.free(Rec_Data_Serial);                                         //Free space in the mailbox (delete earliest sample taken)
            
            time_t scom_time = msg_serial.get_time();                               //Declare local variable for time
            strftime(scom_time_buffer, 32, "%I:%M %p\t", localtime(&scom_time));    //Format time as a string
            pc.printf("Time = %s", scom_time_buffer);                               //Print the string formatted 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
        }
        t2.signal_set(NotSERIAL_COMMS);
        Green_led.Toggle();
        
        //Thread::wait(1000);   
    }
}

void Serial_Comms_set()
{
    t2.signal_set(SERIAL_COMMS);
}

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
        time_t buffer_time = time(NULL);        //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
    pc.printf("Test Start");
    pc.printf("\n\r");
        
    set_time(1512940530);               //Set RTC time to December 10 2017
    pc.baud(9600);                      //Sets the Serial Comms Baud Rate
    
    LCD.Initialise();
    LCD.DDRAM_Address(0x00);
  
    post();     //Power on Self Test
    
    //Initialise the SD card (this needs to move)
    if ( sd.init() != 0) {
        printf("Init failed \n");
        LCD.Display_Clear();
        LCD.Write_String("CANNOT INIT SD");
        errorCode(FATAL);
    } 
    
    
    
    
    LCD.Display_Clear();
                sprintf (LCD_buffer, "%s",scom_time_buffer);
                LCD.DDRAM_Address(0x00);
                LCD.Write_String("Current Time:");
                LCD.DDRAM_Address(0x40);
                LCD.Write_String(LCD_buffer);
    //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.Display_Clear();
        LCD.Write_String("CANNOT OPEN FILE");
        errorCode(FATAL);
    }
    
    //Last message before sampling begins
    LCD.Display_Clear();
    LCD.Write_String("POST");
    LCD.DDRAM_Address(0x40);
    LCD.Write_String("SUCCESSFUL");
    wait(1);
    LCD.Display_Clear();
    LCD.Write_String("READY");
    
    t5.signal_set(NotSerialTime);
    //Run interrupts
    SW1.fall(&SW1FallingEdge);
    Sample_timer.attach(&Sample_signal_set,TimerInterval);
    //Run Threads
    
    //Thread t4(osPriorityAboveNormal);//Sets the Priority bigly
    t1.start(Sample);
    t2.start(Serial_Comms);
    t3.start(ModeSelection);
    t4.start(Network);
    t5.start(Serial_Commands);
    t6.start(Check_Serial_Input);
    //Main thread ID
    
    idMain = osThreadGetId();   //CMSIS RTOS call
    
    //Thread ID
    id1 = t1.gettid();
    id2 = t2.gettid();
    id3 = t3.gettid();
    id4 = t4.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);    
    }
}