3rd Repo, trying to figure this out.

Dependencies:   LPS25H hts221

Fork of SOFT253_Template_Weather_OS_54 by Stage-1 Students SoCEM

main.cpp

Committer:
aburch1
Date:
2017-04-27
Revision:
78:6c2b8ade8414
Parent:
77:db3384071634

File content as of revision 78:6c2b8ade8414:


#include "mbed.h"
#include "rtos.h"
#include "hts221.h"
#include "LPS25H.h"

#include "CircularArray.h"
#include "FakeSensor.h"
#include "MessageLogger.h"

#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <iostream>
#include <sstream>

#define SIGNAL_doMeasure 1
#define SIGNAL_printMessage 2
#define SIGNAL_terminate 3
#define SWITCH1_RELEASE 90
#define BUFFER_SIZE 120
 
//
//  MBED DECLARATIONS
//
DigitalOut myled(LED1);
DigitalIn  onBoardSwitch(USER_BUTTON);
I2C i2c2(I2C_SDA, I2C_SCL);

//
// SENSOR DECLARATIONS
// MAKE SURE ONE OF THESE IS COMMENTED OUT
// Real sensor
// LPS25H barometer(i2c2, LPS25H_V_CHIP_ADDR);
// HTS221 measurer(I2C_SDA, I2C_SCL);
// Fake sensor
FakeBarometer barometer(1029.0, 1031.0);
FakeMeasurer measurer(20.0, 25.0, 30.0, 50.0);

//
// THREADS DECLARATION
//
osThreadId mainThreadID;
Thread *produceThread;
Thread *measureThread;
Thread *consumeThread;
Thread *loggingThread;
Ticker timer;
Ticker realTimeDate;
//
//  GLOBAL VARIABLES
// 
Mail<Measure, 16> mail_box;
CircularArray buffer(BUFFER_SIZE);
LocalDate *localDate;
//Mail<>
bool logging = true;
float sampleRate = 1;

// Logging objects
std::ostringstream oss;
MessageLogger logger;

// 
//  Called by a TICKER
//  Adds 1 second every second to the clock
void RealTimeDate()
{
    localDate->TickSecond();
}

//
//  Ticker that signals the measureThread to do a measure
//
 void SendSignalDoMeasure()
 {
    if(logging == true)
        measureThread->signal_set(SIGNAL_doMeasure);    
}

//
//  SIGNALED BY Ticker at a frequency of <T> Hz
//  Reads values from sensor board, sends over through mail queue
void MeasureThread() {

    while(true)
    {   
        //Await signal from ticker
        Thread::signal_wait(SIGNAL_doMeasure);
        
        float temperature = 0 , humidity = 0,pressure = 0;
        
        Measure *measure = mail_box.alloc();
        if (measure == NULL) 
        {
           logger.SendError("Out of memory");
           return;   
        }
    
        //Read and fill in data
        measurer.ReadTempHumi(&temperature,&humidity);
        barometer.get();
        pressure = barometer.pressure();
        
        measure->temperature = temperature;
        measure->humidity = humidity;
        measure->pressure = pressure;
        measure->date.setValues(localDate);

        osStatus stat = mail_box.put(measure);
    
        //Check if succesful
        if (stat == osErrorResource) 
        {
            char* c;
            sprintf(c, "%4X - Resource not available\n\r", stat);  
            string s(c);
            logger.SendError(s);
            mail_box.free(measure);
            return;
        }
    }
}
 
//
//  Receives data through mail queue, then adds it to the global declared list
//  A.K.A. Producer Thread
void ProducerThread() 
{      
    while (true) 
    {
        //Block on the queue
        osEvent evt = mail_box.get();
        
        //Check status
        if (evt.status == osEventMail) {
            
            Measure *measure = (Measure*)evt.value.p;          
            Measure msr(measure->date,measure->temperature, measure->humidity,measure->pressure);
            
            // Changed to use circlar buffer rather than list buffer
            buffer.pushValue(msr);
            mail_box.free(measure);
        } 
        else 
        {
            char* c;
            sprintf(c, "%4X - Failed to allocate memory\n\r", evt.status);  
            string s(c);
            logger.SendError(s);  
        }  
        
    }
}
int i;
//
//  Compares two char arrays and returns result
//  Param1: First char Array / pointer
//  Param2: Second char Array / pointer
//  Param3. Size of the smallest char arrays (between param1 and param2)
//  Return: "-1" IF NOT EQUAL
//          "1 " IF EQUAL
int CompareCommands(char command[],char targetcommand[], int size)
{
       for(i = 0; i < size; i ++)
       {
            if(command[i] != targetcommand[i])
                return -1;
        }
        return 1;
}

//
//  Reads commands through PUTTY and 'consumes the data' accordingly
//  A.K.A. Consumer Thread
void ConsumeThread()
{
    //Last character pressed read (last key input)
    char charCmd;
    //Char array that stores the command after user presses ENTER
    char command[40];
    //Current Command Size
    int crtChar = 0;
    logger.SendMessage("\n\rAwaiting command:\n\r");  
     
    while(1)
    {
        charCmd = NULL;
        charCmd = getchar();
        if(charCmd != NULL)
        {
            //If BACKSPACE is pressed, Print "DEL" so it deletes last character typed.
            if (charCmd == 127 && crtChar > 0 )
            {
                char* c;
                sprintf(c, "%c", charCmd);  
                string s(c);
                logger.SendMessage(s); 
                command[--crtChar] = '\0';   
            }
            //If NOT enter AND NOT Backspace is pressed, SAVE the char
            else if(charCmd != 13 && charCmd != 127) 
            {
                command[crtChar++] = charCmd;
                char* c;
                sprintf(c, "%c", charCmd);  
                string s(c);
                logger.SendMessage(s); 
            }
            //If ENTER is pressed, PROCESS it
            else if(charCmd == 13) // If Enter is pressed
            {   
                //Get first word of command:
                char *charPos;
                charPos = strtok(command," -,");
                
                //Check if it's a "LIST" command
                if(CompareCommands(charPos, "read",4) == 1)
                {
                    charPos = strtok(NULL," -,");
                    //Check if it's a "LIST ALL" command
                    if(CompareCommands(charPos, "all",3) == 1)
                    {
                        logger.SendMessage("\n\rPrinting all measures performed so far: \n\r");
                        
                        // Changed to use circular buffer rather than list buffer
                        buffer.readAll();
                        logger.SendMessage("\n\rD O N E ! \n\r");
                    }
                    //Check if it's a "LIST X" command
                    else if(strtol(charPos,NULL,10) != 0)
                    {
                        int num = atoi(charPos);
                        char* c;
                        sprintf(c, "\n\rPrinting %i measures: \n\r", num);  
                        string s(c);
                        logger.SendMessage(s); 
                        
                        // Changed to use circular buffer rather than list buffer
                        buffer.readX(num);
                        logger.SendMessage("\n\rD O N E ! \n\r");
                    }
                    else
                    {
                        logger.SendMessage("\n\rExpected parameters: \"all\" | \"n\", where n is a number.");   
                    }
                }
                //Check if it's a "DELETE" command
                else if (CompareCommands(charPos,"delete",6) == 1)
                {
                    charPos = strtok(NULL," -,");
                    //Check if it's a "DELETE ALL" command
                    if(CompareCommands(charPos,"all",3) == 1)
                    {
                        logger.SendMessage("\n\rDeleting all measures performed so far: \n\r");
                        
                        // Changed to use circular buffer rather than list buffer
                        buffer.deleteAll();
                        logger.SendMessage("\n\rElements deleted!\n\r");
                    }
                    //Check if it's a "DELETE X" command
                    else if (strtol(charPos,NULL,10) != 0)
                    {
                        // Changed to use circular buffer rather than list buffer
                        buffer.deleteX(atoi(charPos));
                        logger.SendMessage("\n\rElements deleted!\n\r");
                    }
                    else
                    {
                        logger.SendMessage("\n\rExpected parameters: \"all\" | \"n\", where n is a number.");     
                    }
                       
                }
                //Check if it's a "STATUS" command
                else if (CompareCommands(charPos,"status",6) == 1)
                {
                    char *ptr = localDate->ToString();
                    
                    // Changed to use circular buffer rather than list buffer
                    if(logging == true)
                    {
                        char* c;
                        sprintf(c, "\n\rSTATUS: \n\r   # of measures: %i \n\r   SAMPLING: ON \n\r   Current Date: %s \n\r   Sample Rate(s): %2.2f \n\r", buffer.getSize(), ptr,sampleRate);  
                        string s(c);
                        logger.SendMessage(s); 
                    }
                    else
                    {
                        char* c;
                        sprintf(c, "\n\rSTATUS: \n\r   # of measures: %i \n\r   SAMPLING: OFF \n\r   Current Date: %s \n\r   Sample Rate(s): %2.2f \n\r", buffer.getSize(), ptr,sampleRate);  
                        string s(c);
                        logger.SendMessage(s); 
                    }
                }
                //Check if it's a "SETTIME" command
                else if (CompareCommands(charPos,"settime",7) == 1)
                {
                    int h,m,s;
                    //Fetch 1st Param
                    charPos = strtok(NULL," ,");
                    if(strtol(charPos,NULL,10) != 0)
                    {
                        h = atoi(charPos);   
                    }
                    //Fech 2nd Param
                    charPos = strtok(NULL," ,");
                    if(strtol(charPos,NULL,10) != 0)
                    {
                        m = atoi(charPos);   
                    }
                    //Fetch 3rd Param
                    charPos = strtok(NULL," ,");
                    if(strtol(charPos,NULL,10) != 0)
                    {
                        s = atoi(charPos);   
                    }
                    //Check if parameters are valid
                    if((h>=0 && h < 24) && (m>=0 && m<60) && (s>=0 && s<60))
                    {
                        localDate->hour = h;
                        localDate->min = m;   
                        localDate->sec = s;
                        char *ptr = localDate->ToString();
                        char* c;
                        sprintf(c, "\n\rUpdated Date to: %s \n\r", ptr);
                        string s(c);
                        logger.SendMessage(s); 
                    } 
                    //If not valid, prompt user
                    else
                    {
                        printf("\n\rWrong format! please use HH-MM-SS separated by spaces. \n\r");   
                    }
                }
                //Check if it's a "SETDATE" command
                else if (CompareCommands(charPos,"setdate",7) == 1)
                {
                    int d,m,y;
                    //Fetch 1st Parameter
                    charPos = strtok(NULL," ,");
                    if(strtol(charPos,NULL,10) != 0)
                    {
                        d = atoi(charPos);   
                    }
                    //Fetch 2nd Parameter
                    charPos = strtok(NULL," ,");
                    if(strtol(charPos,NULL,10) != 0)
                    {
                        m = atoi(charPos);   
                    }
                    //Fetch 3rd Parameter
                    charPos = strtok(NULL," ,");
                    if(strtol(charPos,NULL,10) != 0)
                    {
                        y = atoi(charPos);   
                    }
                    //Check if parameters are valid
                    if((d>=0 && d < 31) && (m>=0 && m<13))
                    {
                        localDate->day = d;
                        localDate->month = m;   
                        localDate->year = y;
                        char *ptr = localDate->ToString();
                        printf("\n\rUpdated Date to: %s \n\r", ptr);
                    } 
                    // Prompt user if they are not.
                    else
                    {
                        printf("\n\rWrong format! please use DD-MM-YYYY separated by spaces. \n\r");   
                    }
                }
                // Check if it's a "LOGGING" command
                else if(CompareCommands(charPos,"state",5) == 1)
                {
                    charPos = strtok(NULL," ,");
                    //Check if it should be turned ON / OFF
                    if(CompareCommands(charPos,"on",2) == 1)
                    {
                        logging = true;   
                        printf("\n\rSampling turned ON!\n\r");
                    }
                    else if (CompareCommands(charPos,"off",3) == 1)
                    {
                        logging = false;   
                        printf("\n\rSampling turned OFF!\n\r");
                    }
                    else
                    {
                        printf("\n\rExpected parameters: \"on\" | \"off\"");   
                    }
                }
                // Check if it's a "SETT" command
                else if(CompareCommands(charPos,"sett",4) == 1)
                {
                    charPos = strtok(NULL," ,");
                    float auxRate = atof(charPos);
                    // Validate rate
                    if(auxRate >= 0.1 && 
                       auxRate <= 60 )
                    {
                        sampleRate = auxRate;
                        timer.detach();
                        timer.attach(&SendSignalDoMeasure, sampleRate);
                        printf("\n\rSuccessfully updated sample rate to: %2.2f .\n\r",sampleRate);
                    }
                    // if rate is not valid, prompt:
                    else
                    {
                        printf("\n\r Sample rate must be between 0.1 and 60. \n\r");    
                    }
                }
                // Check if it's a "HELP" command
                else if (CompareCommands(charPos,"help",4) == 1 || CompareCommands(charPos,"?",1) == 1)
                {
                    printf("\n\rAvailable Commands:\n\r");
                    printf("    read <ALL|N> - Read ALL or N first measures.\n\r");
                    printf("    delete <ALL|N> - Delete ALL or N first measures.\n\r");
                    printf("    setdate <DD> <MM> <YYYY> Set current date.\n\r");
                    printf("    settime <HH> <MM> <SS> Set current time.\n\r");
                    printf("    sett <T> Set sample rate (in seconds).\n\r");
                    printf("    status - Status report of device.\n\r");
                    printf("    state - <ON|OFF> - Turn sampling on or OFF.\n\r");
                    printf("    logging <ON|OFF> - Turn logging on or OFF.\n\r");
                }
                else if(CompareCommands(charPos, "test", 4) == 1)
                {
                    charPos = strtok(NULL," ,");
                    //Check if it should be turned ON / OFF
                    if(CompareCommands(charPos,"1",1) == 1)
                    {
                        char *temp;
                        int i = 1337;
                        sprintf(temp, "DIE YOU %d", i);
                        logger.SendMessage(temp);                        
                    }
                    else
                    {
                        char *temp;
                        int i = 50;
                        sprintf(temp, "DIE YOU %d", i);
                        logger.SendError(temp);  
                        
                    }
                }
                // If command not recognized
                else
                {
                    printf("\n\r Command not recognized. Type \"help\" for more info.\n\r");   
                }
                printf("\n\rAwaiting command: \n\r");
                //Clear command!
                //* NOTE * Setting first char in array to '\0' WILL NOT RESET IT...for some reason.
                int i = 0;
                for(i =0 ; i < crtChar; i++)
                    command[i] = ' ';
                command[0] = 0;
                crtChar = 0;
            }
        }
    }
}

void LoggingThread()
{
     //Thread::wait(300000);
     // ARRON: TODO
     
     // - Printing messages
     // - Out of memory
     // - Current status
     // - Display time every X seconds/minutes
     
     // Some queue system holding lines to print
     // If the queue has something to print, print it.
     
     while(true)
     {
        Thread::signal_wait(SIGNAL_printMessage);
        while(true)
        
        {
            if(logger.GetError())
            {
                osSignalSet(mainThreadID, SIGNAL_terminate);
            }
            else if(!logger.GetMessage())
            {
                break;
            }
        }
     }
}
 
// Main thread
int main() 
{
    mainThreadID = osThreadGetId();
    
    //Initialize all stuff you need here:
    measurer.init();
    measurer.calib();
    
    localDate = new LocalDate();
    //Start message
    printf("\n\r\n\r--- W E L C O M E --\n\r");           
   
    //Hook up timer interrupt   
    timer.attach(&SendSignalDoMeasure, sampleRate);
    realTimeDate.attach(&RealTimeDate,1.0);
               
    //Run Threads
    produceThread = new Thread();
    produceThread->start(ProducerThread); 
    measureThread = new Thread();
    measureThread->start(MeasureThread);
    consumeThread = new Thread();
    consumeThread->start(ConsumeThread);
    loggingThread = new Thread();
    loggingThread->start(LoggingThread);
    
    logger.SetThread(loggingThread);
    
    while(true) 
    {
        osSignalWait(SIGNAL_terminate, osWaitForever);
        
        produceThread->terminate();
        measureThread->terminate();
        consumeThread->terminate();
        loggingThread->terminate();
        
        printf("Press any key to restart... ");
        char c = getchar();
        
        NVIC_SystemReset();
    }
}