3rd Repo, trying to figure this out.
Fork of SOFT253_Template_Weather_OS_54 by
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(); } }