3rd Repo, trying to figure this out.
Fork of SOFT253_Template_Weather_OS_54 by
main.cpp
- Committer:
- aburch1
- Date:
- 2017-05-11
- Revision:
- 81:996c0a3319b4
- Parent:
- 80:959151952153
- Child:
- 82:668b51a39148
File content as of revision 81:996c0a3319b4:
#include "mbed.h" #include "rtos.h" #include "hts221.h" #include "LPS25H.h" #include "MessageLogger.h" #include "CircularArray.h" #include "FakeSensor.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 // Thread *produceThread; Thread *measureThread; Thread *consumeThread; Thread *loggingThread; Ticker timer; Ticker realTimeDate; // // GLOBAL VARIABLES // Mail<Measure, 16> mail_box; LocalDate *localDate; //Mail<> bool logging = true; double sampleRate = 15; char temp[256]; // Logging objects MessageLogger logger; CircularArray buffer(BUFFER_SIZE, &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() { double temperature , humidity, pressure; while(true) { temperature = 0; humidity = 0; pressure = 0; //Await signal from ticker Thread::signal_wait(SIGNAL_doMeasure); Measure *measure = mail_box.alloc(); if (measure == NULL) { logger.SendError("Out of memory\n\r"); 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) { snprintf(temp, 256, "queue->put() Error code: %4Xh, Resource not available\r\n", stat); logger.SendError(temp); 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 { snprintf(temp, 256, "ERROR: %x\n\r", evt.status); logger.SendError(temp); } } } 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 bool CompareCommands(char command[],char targetcommand[], int size) { for(i = 0; i < size; i ++) { if(command[i] != targetcommand[i]) { return false; } } return true; } // // 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("\r\nAwaiting Command: \r\n"); 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 ) { command[--crtChar] = '\0'; } //If NOT enter AND NOT Backspace is pressed, SAVE the char else if(charCmd != 13 && charCmd != 127) { command[crtChar++] = charCmd; } //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)) { charPos = strtok(NULL," -,"); //Check if it's a "LIST ALL" command if(CompareCommands(charPos, "all",3)) { logger.SendMessage("Printing all measures performed so far: \r\n"); // Changed to use circular buffer rather than list buffer buffer.readAll(); logger.SendMessage("D O N E ! \r\n"); } //Check if it's a "LIST X" command else if(strtol(charPos,NULL,10) != 0) { int num = atoi(charPos); //char *temp1; //strncpy(temp1, "\r\nPrinting ", 31); //strcat(temp1, charPos); //strcat(temp1, " measures: \r\n"); snprintf(temp, 256, "Printing %i measures: \r\n", num); logger.SendMessage(temp); // Changed to use circular buffer rather than list buffer buffer.readX(num); logger.SendMessage("D O N E ! \r\n"); } else { logger.SendMessage("Expected parameters: \"all\" | \"n\", where n is a number.\r\n"); } } //Check if it's a "DELETE" command else if (CompareCommands(charPos,"delete",6)) { charPos = strtok(NULL," -,"); //Check if it's a "DELETE ALL" command if(CompareCommands(charPos,"all",3)) { logger.SendMessage("Deleting all measures performed so far: \r\n"); // Changed to use circular buffer rather than list buffer buffer.deleteAll(); logger.SendMessage("Elements deleted!\r\n"); } //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("Elements deleted!\r\n"); } else { logger.SendMessage("Expected parameters: \"all\" | \"n\", where n is a number."); } } //Check if it's a "STATUS" command else if (CompareCommands(charPos,"status",6)) { char *ptr = localDate->ToString(); // Changed to use circular buffer rather than list buffer if(logging == true) { snprintf(temp, 256, "STATUS: \r\n # of measures: %i \r\n SAMPLING: ON \r\n Current Date: %s \r\n Sample Rate(s): %2.2f \r\n", buffer.getSize(), ptr,sampleRate); } else { snprintf(temp, 256, "STATUS: \r\n # of measures: %i \r\n SAMPLING: OFF \r\n Current Date: %s \r\n Sample Rate(s): %2.2f \r\n", buffer.getSize(), ptr,sampleRate); } logger.SendMessage(temp); } //Check if it's a "SETTIME" command else if (CompareCommands(charPos,"settime",7)) { 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(); snprintf(temp, 256, "Updated Date to: %s \r\n", ptr); logger.SendMessage(temp); } //If not valid, prompt user else { logger.SendMessage("\r\nWrong format! please use HH-MM-SS. \r\n"); } } //Check if it's a "SETDATE" command else if (CompareCommands(charPos,"setdate",7)) { 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(); snprintf(temp, 256, "Updated Date to: %s \r\n", ptr); logger.SendMessage(temp); } // Prompt user if they are not. else { logger.SendMessage("Wrong format! please use DD-MM-YYYY. \r\n"); } } // Check if it's a "LOGGING" command else if(CompareCommands(charPos,"state",5)) { charPos = strtok(NULL," ,"); //Check if it should be turned ON / OFF if(CompareCommands(charPos,"on",2)) { logging = true; logger.SendMessage("Sampling turned ON!\r\n"); } else if (CompareCommands(charPos,"off",3)) { logging = false; logger.SendMessage("Sampling turned OFF!\r\n"); } else { logger.SendMessage("Expected parameters: \"on\" | \"off\"\r\n"); } } // Check if it's a "SETT" command else if(CompareCommands(charPos,"sett",4)) { charPos = strtok(NULL," ,"); double auxRate = atof(charPos); // Validate rate if(auxRate >= 0.1 && auxRate <= 60) { sampleRate = auxRate; timer.detach(); timer.attach(&SendSignalDoMeasure, sampleRate); snprintf(temp, 256, "Successfully updated sample rate to: %2.2f .\r\n",sampleRate); logger.SendMessage(temp); } // if rate is not valid, prompt: else { logger.SendMessage("Sample rate must be between 0.1 and 60.\r\n"); } } // Check if it's a "HELP" command else if (CompareCommands(charPos,"help",4) || CompareCommands(charPos,"?",1)) { logger.SendMessage("Available Commands:\r\n"); logger.SendMessage(" read <ALL|N> - Read ALL or N first measures.\r\n"); logger.SendMessage(" delete <ALL|N> - Delete ALL or N first measures.\r\n"); logger.SendMessage(" setdate <DD> <MM> <YYYY> Set current date.\r\n"); logger.SendMessage(" settime <HH> <MM> <SS> Set current time.\r\n"); logger.SendMessage(" sett <T> Set sample rate (in seconds).\r\n"); logger.SendMessage(" status - Status report of device.\r\n"); logger.SendMessage(" state - <ON|OFF> - Turn sampling on or OFF.\r\n"); logger.SendMessage(" logging <ON|OFF> - Turn logging on or OFF.\r\n"); } // If command not recognized else { logger.SendMessage("Command not recognized. Type \"help\" for more info.\r\n"); } logger.SendMessage("\r\nAwaiting 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); if(logger.GetError()) { // Kill EVERYTHING //mbed_reset(); //NVIC_SystemReset(); } else if(!logger.GetMessage()) { } } } // Main thread int main() { //Initialize all stuff you need here: measurer.init(); measurer.calib(); localDate = new LocalDate(); //Start message //Hook up timer interrupt timer.attach(&SendSignalDoMeasure, sampleRate); realTimeDate.attach(&RealTimeDate,1.0); //Run Threads loggingThread = new Thread(); loggingThread->start(LoggingThread); logger.SetThread(loggingThread); produceThread = new Thread(); produceThread->start(ProducerThread); measureThread = new Thread(); measureThread->start(MeasureThread); consumeThread = new Thread(); consumeThread->start(ConsumeThread); logger.SendMessage("\r\n--- W E L C O M E --\r\n"); while(true) { // Is there a sleep method that could be used instead or waiting and awaking every 3 seconds? Thread::signal_wait(SIGNAL_terminate); } }