3rd Repo, trying to figure this out.
Fork of SOFT253_Template_Weather_OS_54 by
main.cpp
- Committer:
- aburch1
- Date:
- 2017-05-11
- Revision:
- 82:668b51a39148
- Parent:
- 81:996c0a3319b4
- Child:
- 83:0d3572a8a851
File content as of revision 82:668b51a39148:
#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 // osThreadId mainThreadId; Thread *produceThread; Thread *measureThread; Thread *consumeThread; Thread *loggingThread; Ticker timer; Ticker realTimeDate; // // GLOBAL VARIABLES // Mail<Measure, 16> mail_box; LocalDate *localDate; //Mail<> bool logging = false; bool measuring = 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() { 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() { float 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\r\n"); 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; } if(logging) { logger.SendMessage("Measurement Taken:\r\n"); char *ptr = localDate->ToString(); snprintf(temp, 256, " %s T: %f | H: %f | P: %f |\n\r",ptr, temperature, humidity, pressure); logger.SendMessage(temp); } } } // // 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\r\n", 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(logging) { logging = false; logger.SendMessage("\r\033[1AKey Pressed. Debug logging disabled.\r\n"); charCmd = NULL; } 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)) { // 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); 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(); } //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 snprintf(temp, 256, "\nStatus: \r\n"); logger.SendMessage(temp); snprintf(temp, 256, " # of measures: %i \r\n", buffer.getSize()); logger.SendMessage(temp); snprintf(temp, 256, " Sampling: %s \r\n", measuring ? "On" : "Off"); logger.SendMessage(temp); snprintf(temp, 256, " Logging: %s \r\n", logging ? "On" : "Off"); logger.SendMessage(temp); snprintf(temp, 256, " Current Date: %s \r\n", ptr); logger.SendMessage(temp); snprintf(temp, 256, " Sample Rate(s): %2.2f \r\n", 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 "STATE" command else if(CompareCommands(charPos,"state",5)) { charPos = strtok(NULL," ,"); //Check if it should be turned ON / OFF if(CompareCommands(charPos,"on",2)) { logger.SendMessage("Sampling turned ON!\r\n"); timer.attach(&SendSignalDoMeasure, sampleRate); SendSignalDoMeasure(); measuring = true; } else if (CompareCommands(charPos,"off",3)) { logger.SendMessage("Sampling turned OFF!\r\n"); timer.detach(); measuring = false; } else { logger.SendMessage("Expected parameters: \"on\" | \"off\"\r\n"); } } // Check if it's a "LOGGING" command else if(CompareCommands(charPos,"logging",7)) { charPos = strtok(NULL," ,"); //Check if it should be turned ON / OFF if(CompareCommands(charPos,"on",2)) { logging = true; logger.SendMessage("Debug logging turned ON!\r\n"); logger.SendMessage("Press any key to deactivate\r\n"); } else if (CompareCommands(charPos,"off",3)) { logger.SendMessage("Logging is already 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("\nAvailable 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"); } // Check if it's a "HELP" command else if (CompareCommands(charPos,"reset",5)) { logger.SendError("Program Terminating...\r\n"); } // If command not recognized else { logger.SendMessage("Command not recognized. Type \"help\" for more info.\r\n"); } if(!logging) { logger.SendMessage("\r\nAwaiting Command:\r\n"); } //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 //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"); SendSignalDoMeasure(); 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(); } }