3rd Repo, trying to figure this out.

Dependencies:   LPS25H hts221

Fork of SOFT253_Template_Weather_OS_54 by Stage-1 Students SoCEM

Committer:
aburch1
Date:
Thu May 11 19:23:55 2017 +0000
Revision:
83:0d3572a8a851
Parent:
82:668b51a39148
Child:
85:422d0a1b95cf
Comments cleaned and improved throughout classes. Main header class comment complete, other class comments still need to be written.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jonathan Austin 0:2757d7abb7d9 1 #include "mbed.h"
martinsimpson 32:260a288be58f 2 #include "rtos.h"
aburch1 74:749727490f44 3 #include "hts221.h"
aburch1 74:749727490f44 4 #include "LPS25H.h"
aburch1 74:749727490f44 5
aburch1 81:996c0a3319b4 6 #include "MessageLogger.h"
aburch1 74:749727490f44 7 #include "CircularArray.h"
aburch1 74:749727490f44 8 #include "FakeSensor.h"
aburch1 74:749727490f44 9
FairyMental 43:3983059e0d91 10 #include <string.h>
FairyMental 34:09ed07f2acba 11 #include <stdio.h>
FairyMental 34:09ed07f2acba 12 #include <ctype.h>
FairyMental 41:d222c043c96d 13 #include <iostream>
aburch1 74:749727490f44 14 #include <sstream>
martinsimpson 32:260a288be58f 15
FairyMental 36:19d3f752f9c3 16 #define SIGNAL_doMeasure 1
aburch1 75:b44645bbf2d2 17 #define SIGNAL_printMessage 2
aburch1 81:996c0a3319b4 18 #define SIGNAL_terminate 3
FairyMental 36:19d3f752f9c3 19 #define SWITCH1_RELEASE 90
Netaphous 65:3723d2729b68 20 #define BUFFER_SIZE 120
FairyMental 34:09ed07f2acba 21
aburch1 83:0d3572a8a851 22 /**
aburch1 83:0d3572a8a851 23 @file : main.cpp
aburch1 83:0d3572a8a851 24 @authors : Radu Marcu, Jacob Williams, Niall Francis, Arron Burch
aburch1 83:0d3572a8a851 25
aburch1 83:0d3572a8a851 26 @section DESCRIPTION
aburch1 83:0d3572a8a851 27
aburch1 83:0d3572a8a851 28 This is the main class where the program runs on startup, this is
aburch1 83:0d3572a8a851 29 a multi-threaded application that will that make the ST F401 Nucleo Target board
aburch1 83:0d3572a8a851 30 take periodic measurements of senor data, including temperature,
aburch1 83:0d3572a8a851 31 pressure and humidity, at a fixed set sample rate. A max of 120 measurements are stored
aburch1 83:0d3572a8a851 32 within RAM at any one time, available to be printed to a termial output via a serial port
aburch1 83:0d3572a8a851 33 connection.
aburch1 83:0d3572a8a851 34 Once 120 measurements are stored, the oldest measurements are overwritten using a circular
aburch1 83:0d3572a8a851 35 buffer, so that the most recent 120 measurements can always be stored on the device.
aburch1 83:0d3572a8a851 36 The application can provide logging data when measurements are taken if logging is turned
aburch1 83:0d3572a8a851 37 on using the logging command (See readme.md).
aburch1 83:0d3572a8a851 38 The application has been written to reduce power consumption where possible by utilising
aburch1 83:0d3572a8a851 39 Thread signals and sleeping when not in use.
aburch1 83:0d3572a8a851 40 Serial Communications are handled within a sepearate thread to ensure that no action will
aburch1 83:0d3572a8a851 41 block or interrupt the CPU when measuring samples.
aburch1 83:0d3572a8a851 42 The serial communications use a priority system, allowing errors to be printed with a higher
aburch1 83:0d3572a8a851 43 priority than logging messages and the application to be terminated and reset by user input
aburch1 83:0d3572a8a851 44 if required.
aburch1 83:0d3572a8a851 45 */
aburch1 83:0d3572a8a851 46
FairyMental 57:dfcdda1e42b6 47 //
FairyMental 57:dfcdda1e42b6 48 // MBED DECLARATIONS
FairyMental 57:dfcdda1e42b6 49 //
martinsimpson 32:260a288be58f 50 DigitalOut myled(LED1);
Netaphous 50:c07e968b9582 51 DigitalIn onBoardSwitch(USER_BUTTON);
martinsimpson 32:260a288be58f 52 I2C i2c2(I2C_SDA, I2C_SCL);
Netaphous 50:c07e968b9582 53
FairyMental 57:dfcdda1e42b6 54 //
FairyMental 57:dfcdda1e42b6 55 // SENSOR DECLARATIONS
Netaphous 50:c07e968b9582 56 // MAKE SURE ONE OF THESE IS COMMENTED OUT
Netaphous 50:c07e968b9582 57 // Real sensor
aburch1 83:0d3572a8a851 58 LPS25H barometer(i2c2, LPS25H_V_CHIP_ADDR);
aburch1 83:0d3572a8a851 59 HTS221 measurer(I2C_SDA, I2C_SCL);
Netaphous 50:c07e968b9582 60 // Fake sensor
aburch1 83:0d3572a8a851 61 // FakeBarometer barometer(1029.0, 1031.0);
aburch1 83:0d3572a8a851 62 // FakeMeasurer measurer(20.0, 25.0, 30.0, 50.0);
Netaphous 50:c07e968b9582 63
FairyMental 57:dfcdda1e42b6 64 //
FairyMental 57:dfcdda1e42b6 65 // THREADS DECLARATION
FairyMental 57:dfcdda1e42b6 66 //
aburch1 82:668b51a39148 67 osThreadId mainThreadId;
aburch1 83:0d3572a8a851 68 Thread *producerThread;
aburch1 83:0d3572a8a851 69 Thread *measurementThread;
aburch1 83:0d3572a8a851 70 Thread *consumerThread;
aburch1 74:749727490f44 71 Thread *loggingThread;
FairyMental 58:7fc6e3e4d746 72 Ticker timer;
FairyMental 58:7fc6e3e4d746 73 Ticker realTimeDate;
FairyMental 57:dfcdda1e42b6 74 //
FairyMental 57:dfcdda1e42b6 75 // GLOBAL VARIABLES
FairyMental 57:dfcdda1e42b6 76 //
FairyMental 34:09ed07f2acba 77 Mail<Measure, 16> mail_box;
FairyMental 46:0de1f3c7d118 78 LocalDate *localDate;
aburch1 82:668b51a39148 79 bool logging = false;
aburch1 82:668b51a39148 80 bool measuring = true;
aburch1 81:996c0a3319b4 81 double sampleRate = 15;
aburch1 81:996c0a3319b4 82 char temp[256];
FairyMental 49:83bea7fb2728 83
aburch1 74:749727490f44 84 // Logging objects
aburch1 75:b44645bbf2d2 85 MessageLogger logger;
aburch1 74:749727490f44 86
aburch1 81:996c0a3319b4 87 CircularArray buffer(BUFFER_SIZE, &logger);
FairyMental 57:dfcdda1e42b6 88 //
aburch1 83:0d3572a8a851 89 // Called by a ticker
FairyMental 57:dfcdda1e42b6 90 // Adds 1 second every second to the clock
aburch1 83:0d3572a8a851 91 //
FairyMental 46:0de1f3c7d118 92 void RealTimeDate()
FairyMental 46:0de1f3c7d118 93 {
FairyMental 46:0de1f3c7d118 94 localDate->TickSecond();
FairyMental 46:0de1f3c7d118 95 }
FairyMental 58:7fc6e3e4d746 96
FairyMental 58:7fc6e3e4d746 97 //
FairyMental 58:7fc6e3e4d746 98 // Ticker that signals the measureThread to do a measure
FairyMental 58:7fc6e3e4d746 99 //
FairyMental 58:7fc6e3e4d746 100 void SendSignalDoMeasure()
aburch1 82:668b51a39148 101 {
aburch1 83:0d3572a8a851 102 measurementThread->signal_set(SIGNAL_doMeasure);
FairyMental 58:7fc6e3e4d746 103 }
FairyMental 58:7fc6e3e4d746 104
FairyMental 57:dfcdda1e42b6 105 //
aburch1 83:0d3572a8a851 106 // Called by ticker every T seconds
aburch1 83:0d3572a8a851 107 // Reads values from sensor board, sends between threads using a mail queue
aburch1 83:0d3572a8a851 108 //
aburch1 83:0d3572a8a851 109 void MeasurementThread()
aburch1 79:4e6b53eb678b 110 {
aburch1 82:668b51a39148 111 float temperature , humidity, pressure;
FairyMental 35:484e384f9bf1 112
FairyMental 36:19d3f752f9c3 113 while(true)
FairyMental 36:19d3f752f9c3 114 {
aburch1 79:4e6b53eb678b 115 temperature = 0;
aburch1 79:4e6b53eb678b 116 humidity = 0;
aburch1 79:4e6b53eb678b 117 pressure = 0;
aburch1 83:0d3572a8a851 118
FairyMental 36:19d3f752f9c3 119 Thread::signal_wait(SIGNAL_doMeasure);
FairyMental 57:dfcdda1e42b6 120
FairyMental 36:19d3f752f9c3 121 Measure *measure = mail_box.alloc();
FairyMental 36:19d3f752f9c3 122 if (measure == NULL)
FairyMental 36:19d3f752f9c3 123 {
aburch1 82:668b51a39148 124 logger.SendError("Out of memory\r\n");
FairyMental 36:19d3f752f9c3 125 return;
FairyMental 36:19d3f752f9c3 126 }
FairyMental 34:09ed07f2acba 127
aburch1 83:0d3572a8a851 128 //Read data from measurer, puts data into a measure object.
FairyMental 36:19d3f752f9c3 129 measurer.ReadTempHumi(&temperature,&humidity);
FairyMental 36:19d3f752f9c3 130 barometer.get();
FairyMental 36:19d3f752f9c3 131 pressure = barometer.pressure();
FairyMental 47:468a89d62c23 132
FairyMental 36:19d3f752f9c3 133 measure->temperature = temperature;
FairyMental 36:19d3f752f9c3 134 measure->humidity = humidity;
FairyMental 36:19d3f752f9c3 135 measure->pressure = pressure;
Netaphous 67:8d0e88172e2a 136 measure->date.setValues(localDate);
FairyMental 36:19d3f752f9c3 137
FairyMental 57:dfcdda1e42b6 138 osStatus stat = mail_box.put(measure);
martinsimpson 32:260a288be58f 139
aburch1 83:0d3572a8a851 140 // Check if mailbox allocation was unsuccessful
aburch1 83:0d3572a8a851 141 if (stat == osErrorResource)
aburch1 83:0d3572a8a851 142 {
aburch1 81:996c0a3319b4 143 snprintf(temp, 256, "queue->put() Error code: %4Xh, Resource not available\r\n", stat);
aburch1 81:996c0a3319b4 144 logger.SendError(temp);
FairyMental 36:19d3f752f9c3 145 mail_box.free(measure);
FairyMental 36:19d3f752f9c3 146 return;
FairyMental 36:19d3f752f9c3 147 }
aburch1 82:668b51a39148 148
aburch1 83:0d3572a8a851 149 // Print measurement taken if logging is enabled
aburch1 82:668b51a39148 150 if(logging)
aburch1 82:668b51a39148 151 {
aburch1 82:668b51a39148 152 logger.SendMessage("Measurement Taken:\r\n");
aburch1 82:668b51a39148 153 char *ptr = localDate->ToString();
aburch1 83:0d3572a8a851 154 snprintf(temp, 256, " %s T: %f, H: %f, P: %f\n\r",ptr, temperature, humidity, pressure);
aburch1 82:668b51a39148 155 logger.SendMessage(temp);
aburch1 82:668b51a39148 156 }
FairyMental 34:09ed07f2acba 157 }
FairyMental 34:09ed07f2acba 158 }
FairyMental 34:09ed07f2acba 159
FairyMental 57:dfcdda1e42b6 160 //
aburch1 83:0d3572a8a851 161 // Receives data through mail queue, then adds it to the circular array buffer.
aburch1 83:0d3572a8a851 162 //
FairyMental 37:00775e368a71 163 void ProducerThread()
FairyMental 34:09ed07f2acba 164 {
FairyMental 57:dfcdda1e42b6 165 while (true)
FairyMental 57:dfcdda1e42b6 166 {
FairyMental 34:09ed07f2acba 167 osEvent evt = mail_box.get();
FairyMental 34:09ed07f2acba 168
aburch1 83:0d3572a8a851 169 // Check if mailbox retrieval was successful
aburch1 83:0d3572a8a851 170 if (evt.status == osEventMail)
aburch1 83:0d3572a8a851 171 {
FairyMental 57:dfcdda1e42b6 172 Measure *measure = (Measure*)evt.value.p;
FairyMental 47:468a89d62c23 173 Measure msr(measure->date,measure->temperature, measure->humidity,measure->pressure);
Netaphous 65:3723d2729b68 174
Netaphous 65:3723d2729b68 175 buffer.pushValue(msr);
FairyMental 34:09ed07f2acba 176 mail_box.free(measure);
aburch1 83:0d3572a8a851 177 }
aburch1 83:0d3572a8a851 178 else
aburch1 83:0d3572a8a851 179 {
aburch1 82:668b51a39148 180 snprintf(temp, 256, "ERROR: %x\r\n", evt.status);
aburch1 81:996c0a3319b4 181 logger.SendError(temp);
aburch1 83:0d3572a8a851 182 }
FairyMental 57:dfcdda1e42b6 183 }
FairyMental 34:09ed07f2acba 184 }
aburch1 83:0d3572a8a851 185
Netaphous 69:72f237750d85 186 int i;
aburch1 83:0d3572a8a851 187 /**
aburch1 83:0d3572a8a851 188 Compares two char arrays and returns result
aburch1 83:0d3572a8a851 189
aburch1 83:0d3572a8a851 190 @param command : First char Array / pointer
aburch1 83:0d3572a8a851 191 @param targetCommand : Second char Array / pointer
aburch1 83:0d3572a8a851 192 @param size : Size of the smallest char arrays (between param1 and param2)
aburch1 83:0d3572a8a851 193 @return : TRUE if equal, FALSE if not equal
aburch1 83:0d3572a8a851 194 */
aburch1 83:0d3572a8a851 195 bool CompareCommands(char command[],char targetCommand[], int size)
FairyMental 42:b1f29874ab70 196 {
aburch1 83:0d3572a8a851 197 for(i = 0; i < size; i ++)
aburch1 83:0d3572a8a851 198 {
aburch1 83:0d3572a8a851 199 if(command[i] != targetCommand[i])
aburch1 83:0d3572a8a851 200 {
aburch1 83:0d3572a8a851 201 return false;
FairyMental 42:b1f29874ab70 202 }
aburch1 83:0d3572a8a851 203 }
aburch1 83:0d3572a8a851 204 return true;
aburch1 83:0d3572a8a851 205 }
aburch1 74:749727490f44 206
aburch1 83:0d3572a8a851 207 /**
aburch1 83:0d3572a8a851 208 Reads commands from the terminal and 'consumes' the data accordingly.
aburch1 83:0d3572a8a851 209 */
aburch1 83:0d3572a8a851 210 void ConsumerThread()
FairyMental 39:618ad21e2b34 211 {
FairyMental 41:d222c043c96d 212 char charCmd;
aburch1 83:0d3572a8a851 213 //Char array that stores the chars entered when user presses enter.
FairyMental 41:d222c043c96d 214 char command[40];
FairyMental 57:dfcdda1e42b6 215 //Current Command Size
aburch1 83:0d3572a8a851 216 int crtSize = 0;
aburch1 81:996c0a3319b4 217 logger.SendMessage("\r\nAwaiting Command: \r\n");
FairyMental 39:618ad21e2b34 218 while(1)
FairyMental 39:618ad21e2b34 219 {
FairyMental 41:d222c043c96d 220 charCmd = NULL;
FairyMental 41:d222c043c96d 221 charCmd = getchar();
aburch1 82:668b51a39148 222 if(logging)
aburch1 82:668b51a39148 223 {
aburch1 82:668b51a39148 224 logging = false;
aburch1 83:0d3572a8a851 225 logger.SendMessage("\rKey Pressed. Debug logging disabled.\r\n");
aburch1 82:668b51a39148 226 charCmd = NULL;
aburch1 82:668b51a39148 227 }
aburch1 80:959151952153 228
FairyMental 41:d222c043c96d 229 if(charCmd != NULL)
FairyMental 41:d222c043c96d 230 {
FairyMental 57:dfcdda1e42b6 231 //If BACKSPACE is pressed, Print "DEL" so it deletes last character typed.
aburch1 83:0d3572a8a851 232 if (charCmd == 127 && crtSize > 0 )
FairyMental 43:3983059e0d91 233 {
aburch1 83:0d3572a8a851 234 command[--crtSize] = '\0';
FairyMental 43:3983059e0d91 235 }
FairyMental 57:dfcdda1e42b6 236 //If NOT enter AND NOT Backspace is pressed, SAVE the char
FairyMental 57:dfcdda1e42b6 237 else if(charCmd != 13 && charCmd != 127)
FairyMental 41:d222c043c96d 238 {
aburch1 83:0d3572a8a851 239 command[crtSize++] = charCmd;
FairyMental 41:d222c043c96d 240 }
aburch1 83:0d3572a8a851 241 // If enter is pressed, process the command.
aburch1 83:0d3572a8a851 242 else if(charCmd == 13)
FairyMental 49:83bea7fb2728 243 {
aburch1 83:0d3572a8a851 244 logger.SendMessage("\n");
aburch1 83:0d3572a8a851 245 // Get first word of command.
FairyMental 43:3983059e0d91 246 char *charPos;
FairyMental 43:3983059e0d91 247 charPos = strtok(command," -,");
FairyMental 57:dfcdda1e42b6 248
aburch1 83:0d3572a8a851 249 // Check if it's a "read" command
aburch1 81:996c0a3319b4 250 if(CompareCommands(charPos, "read",4))
FairyMental 42:b1f29874ab70 251 {
FairyMental 43:3983059e0d91 252 charPos = strtok(NULL," -,");
aburch1 83:0d3572a8a851 253 // Check if it's a "read all" command
aburch1 81:996c0a3319b4 254 if(CompareCommands(charPos, "all",3))
aburch1 82:668b51a39148 255 {
Netaphous 65:3723d2729b68 256 // Changed to use circular buffer rather than list buffer
Netaphous 65:3723d2729b68 257 buffer.readAll();
aburch1 81:996c0a3319b4 258 logger.SendMessage("D O N E ! \r\n");
FairyMental 43:3983059e0d91 259 }
aburch1 83:0d3572a8a851 260 // Check if it's a "read n" command
FairyMental 43:3983059e0d91 261 else if(strtol(charPos,NULL,10) != 0)
FairyMental 43:3983059e0d91 262 {
aburch1 81:996c0a3319b4 263 int num = atoi(charPos);
aburch1 80:959151952153 264
aburch1 83:0d3572a8a851 265 buffer.readN(num);
aburch1 81:996c0a3319b4 266 logger.SendMessage("D O N E ! \r\n");
FairyMental 60:db8c5b7fc548 267 }
FairyMental 60:db8c5b7fc548 268 else
FairyMental 60:db8c5b7fc548 269 {
aburch1 81:996c0a3319b4 270 logger.SendMessage("Expected parameters: \"all\" | \"n\", where n is a number.\r\n");
FairyMental 43:3983059e0d91 271 }
FairyMental 42:b1f29874ab70 272 }
aburch1 83:0d3572a8a851 273 // Check if it's a "delete" command
aburch1 81:996c0a3319b4 274 else if (CompareCommands(charPos,"delete",6))
FairyMental 44:b523c9a9dd97 275 {
FairyMental 44:b523c9a9dd97 276 charPos = strtok(NULL," -,");
aburch1 83:0d3572a8a851 277 // Check if it's a "delete all" command
aburch1 81:996c0a3319b4 278 if(CompareCommands(charPos,"all",3))
FairyMental 44:b523c9a9dd97 279 {
aburch1 81:996c0a3319b4 280 logger.SendMessage("Deleting all measures performed so far: \r\n");
Netaphous 65:3723d2729b68 281
Netaphous 65:3723d2729b68 282 buffer.deleteAll();
FairyMental 44:b523c9a9dd97 283 }
aburch1 83:0d3572a8a851 284 // Check if it's a "delete n" command
FairyMental 44:b523c9a9dd97 285 else if (strtol(charPos,NULL,10) != 0)
FairyMental 44:b523c9a9dd97 286 {
Netaphous 65:3723d2729b68 287 // Changed to use circular buffer rather than list buffer
aburch1 83:0d3572a8a851 288 buffer.deleteN(atoi(charPos));
aburch1 81:996c0a3319b4 289 logger.SendMessage("Elements deleted!\r\n");
FairyMental 60:db8c5b7fc548 290 }
FairyMental 60:db8c5b7fc548 291 else
FairyMental 60:db8c5b7fc548 292 {
aburch1 81:996c0a3319b4 293 logger.SendMessage("Expected parameters: \"all\" | \"n\", where n is a number.");
aburch1 81:996c0a3319b4 294 }
FairyMental 44:b523c9a9dd97 295 }
aburch1 83:0d3572a8a851 296 // Check if it's a "status" command
aburch1 81:996c0a3319b4 297 else if (CompareCommands(charPos,"status",6))
FairyMental 45:9a33f2bc2b4e 298 {
FairyMental 46:0de1f3c7d118 299 char *ptr = localDate->ToString();
Netaphous 65:3723d2729b68 300
aburch1 82:668b51a39148 301 snprintf(temp, 256, "\nStatus: \r\n");
aburch1 82:668b51a39148 302 logger.SendMessage(temp);
aburch1 82:668b51a39148 303 snprintf(temp, 256, " # of measures: %i \r\n", buffer.getSize());
aburch1 82:668b51a39148 304 logger.SendMessage(temp);
aburch1 82:668b51a39148 305 snprintf(temp, 256, " Sampling: %s \r\n", measuring ? "On" : "Off");
aburch1 82:668b51a39148 306 logger.SendMessage(temp);
aburch1 82:668b51a39148 307 snprintf(temp, 256, " Logging: %s \r\n", logging ? "On" : "Off");
aburch1 82:668b51a39148 308 logger.SendMessage(temp);
aburch1 82:668b51a39148 309 snprintf(temp, 256, " Current Date: %s \r\n", ptr);
aburch1 82:668b51a39148 310 logger.SendMessage(temp);
aburch1 82:668b51a39148 311 snprintf(temp, 256, " Sample Rate(s): %2.2f \r\n", sampleRate);
aburch1 81:996c0a3319b4 312 logger.SendMessage(temp);
FairyMental 45:9a33f2bc2b4e 313 }
aburch1 83:0d3572a8a851 314 //Check if it's a "settime" command
aburch1 81:996c0a3319b4 315 else if (CompareCommands(charPos,"settime",7))
FairyMental 48:a8219954b3f2 316 {
FairyMental 48:a8219954b3f2 317 int h,m,s;
aburch1 83:0d3572a8a851 318
aburch1 81:996c0a3319b4 319 charPos = strtok(NULL," -,");
FairyMental 48:a8219954b3f2 320 if(strtol(charPos,NULL,10) != 0)
FairyMental 48:a8219954b3f2 321 {
FairyMental 48:a8219954b3f2 322 h = atoi(charPos);
FairyMental 48:a8219954b3f2 323 }
aburch1 81:996c0a3319b4 324 charPos = strtok(NULL," -,");
FairyMental 48:a8219954b3f2 325 if(strtol(charPos,NULL,10) != 0)
FairyMental 48:a8219954b3f2 326 {
FairyMental 48:a8219954b3f2 327 m = atoi(charPos);
FairyMental 48:a8219954b3f2 328 }
aburch1 81:996c0a3319b4 329 charPos = strtok(NULL," -,");
FairyMental 48:a8219954b3f2 330 if(strtol(charPos,NULL,10) != 0)
FairyMental 48:a8219954b3f2 331 {
FairyMental 48:a8219954b3f2 332 s = atoi(charPos);
FairyMental 48:a8219954b3f2 333 }
FairyMental 48:a8219954b3f2 334 if((h>=0 && h < 24) && (m>=0 && m<60) && (s>=0 && s<60))
FairyMental 48:a8219954b3f2 335 {
FairyMental 48:a8219954b3f2 336 localDate->hour = h;
FairyMental 48:a8219954b3f2 337 localDate->min = m;
FairyMental 48:a8219954b3f2 338 localDate->sec = s;
FairyMental 60:db8c5b7fc548 339 char *ptr = localDate->ToString();
aburch1 81:996c0a3319b4 340 snprintf(temp, 256, "Updated Date to: %s \r\n", ptr);
aburch1 81:996c0a3319b4 341 logger.SendMessage(temp);
FairyMental 48:a8219954b3f2 342 }
FairyMental 48:a8219954b3f2 343 else
FairyMental 48:a8219954b3f2 344 {
aburch1 81:996c0a3319b4 345 logger.SendMessage("\r\nWrong format! please use HH-MM-SS. \r\n");
FairyMental 48:a8219954b3f2 346 }
FairyMental 48:a8219954b3f2 347 }
aburch1 83:0d3572a8a851 348 //Check if it's a "setdate" command
aburch1 81:996c0a3319b4 349 else if (CompareCommands(charPos,"setdate",7))
FairyMental 48:a8219954b3f2 350 {
FairyMental 48:a8219954b3f2 351 int d,m,y;
aburch1 83:0d3572a8a851 352
aburch1 81:996c0a3319b4 353 charPos = strtok(NULL," ,-");
FairyMental 48:a8219954b3f2 354 if(strtol(charPos,NULL,10) != 0)
FairyMental 48:a8219954b3f2 355 {
FairyMental 48:a8219954b3f2 356 d = atoi(charPos);
FairyMental 48:a8219954b3f2 357 }
aburch1 83:0d3572a8a851 358
aburch1 81:996c0a3319b4 359 charPos = strtok(NULL," ,-");
FairyMental 48:a8219954b3f2 360 if(strtol(charPos,NULL,10) != 0)
FairyMental 48:a8219954b3f2 361 {
FairyMental 48:a8219954b3f2 362 m = atoi(charPos);
FairyMental 48:a8219954b3f2 363 }
aburch1 83:0d3572a8a851 364
aburch1 81:996c0a3319b4 365 charPos = strtok(NULL," ,-");
FairyMental 48:a8219954b3f2 366 if(strtol(charPos,NULL,10) != 0)
FairyMental 48:a8219954b3f2 367 {
FairyMental 48:a8219954b3f2 368 y = atoi(charPos);
FairyMental 48:a8219954b3f2 369 }
aburch1 83:0d3572a8a851 370
FairyMental 48:a8219954b3f2 371 if((d>=0 && d < 31) && (m>=0 && m<13))
FairyMental 48:a8219954b3f2 372 {
FairyMental 48:a8219954b3f2 373 localDate->day = d;
FairyMental 48:a8219954b3f2 374 localDate->month = m;
FairyMental 48:a8219954b3f2 375 localDate->year = y;
FairyMental 60:db8c5b7fc548 376 char *ptr = localDate->ToString();
aburch1 81:996c0a3319b4 377 snprintf(temp, 256, "Updated Date to: %s \r\n", ptr);
aburch1 81:996c0a3319b4 378 logger.SendMessage(temp);
FairyMental 48:a8219954b3f2 379 }
FairyMental 48:a8219954b3f2 380 else
FairyMental 48:a8219954b3f2 381 {
aburch1 81:996c0a3319b4 382 logger.SendMessage("Wrong format! please use DD-MM-YYYY. \r\n");
FairyMental 48:a8219954b3f2 383 }
FairyMental 48:a8219954b3f2 384 }
aburch1 83:0d3572a8a851 385 // Check if it's a "state" command
aburch1 81:996c0a3319b4 386 else if(CompareCommands(charPos,"state",5))
FairyMental 49:83bea7fb2728 387 {
FairyMental 49:83bea7fb2728 388 charPos = strtok(NULL," ,");
aburch1 83:0d3572a8a851 389
aburch1 83:0d3572a8a851 390 // Check if it should be turned on / off
aburch1 81:996c0a3319b4 391 if(CompareCommands(charPos,"on",2))
FairyMental 49:83bea7fb2728 392 {
aburch1 83:0d3572a8a851 393 logger.SendMessage("Sampling turned on!\r\n");
aburch1 82:668b51a39148 394 timer.attach(&SendSignalDoMeasure, sampleRate);
aburch1 82:668b51a39148 395 SendSignalDoMeasure();
aburch1 82:668b51a39148 396 measuring = true;
FairyMental 49:83bea7fb2728 397 }
aburch1 81:996c0a3319b4 398 else if (CompareCommands(charPos,"off",3))
FairyMental 49:83bea7fb2728 399 {
aburch1 83:0d3572a8a851 400 logger.SendMessage("Sampling turned off!\r\n");
aburch1 82:668b51a39148 401 timer.detach();
aburch1 82:668b51a39148 402 measuring = false;
aburch1 82:668b51a39148 403 }
aburch1 82:668b51a39148 404 else
aburch1 82:668b51a39148 405 {
aburch1 82:668b51a39148 406 logger.SendMessage("Expected parameters: \"on\" | \"off\"\r\n");
aburch1 82:668b51a39148 407 }
aburch1 82:668b51a39148 408 }
aburch1 83:0d3572a8a851 409 // Check if it's a "logging" command
aburch1 82:668b51a39148 410 else if(CompareCommands(charPos,"logging",7))
aburch1 82:668b51a39148 411 {
aburch1 82:668b51a39148 412 charPos = strtok(NULL," ,");
aburch1 82:668b51a39148 413 //Check if it should be turned ON / OFF
aburch1 82:668b51a39148 414 if(CompareCommands(charPos,"on",2))
aburch1 82:668b51a39148 415 {
aburch1 82:668b51a39148 416 logging = true;
aburch1 83:0d3572a8a851 417 logger.SendMessage("Debug logging turned on!\r\n");
aburch1 82:668b51a39148 418 logger.SendMessage("Press any key to deactivate\r\n");
aburch1 82:668b51a39148 419 }
aburch1 82:668b51a39148 420 else if (CompareCommands(charPos,"off",3))
aburch1 82:668b51a39148 421 {
aburch1 82:668b51a39148 422 logger.SendMessage("Logging is already turned off.\r\n");
FairyMental 60:db8c5b7fc548 423 }
FairyMental 60:db8c5b7fc548 424 else
FairyMental 60:db8c5b7fc548 425 {
aburch1 81:996c0a3319b4 426 logger.SendMessage("Expected parameters: \"on\" | \"off\"\r\n");
FairyMental 49:83bea7fb2728 427 }
FairyMental 58:7fc6e3e4d746 428 }
aburch1 83:0d3572a8a851 429 // Check if it's a "sett" command
aburch1 81:996c0a3319b4 430 else if(CompareCommands(charPos,"sett",4))
FairyMental 58:7fc6e3e4d746 431 {
FairyMental 58:7fc6e3e4d746 432 charPos = strtok(NULL," ,");
aburch1 81:996c0a3319b4 433 double auxRate = atof(charPos);
FairyMental 68:d3765f93c16a 434 // Validate rate
aburch1 81:996c0a3319b4 435 if(auxRate >= 0.1 &&
aburch1 81:996c0a3319b4 436 auxRate <= 60)
FairyMental 58:7fc6e3e4d746 437 {
FairyMental 58:7fc6e3e4d746 438 sampleRate = auxRate;
FairyMental 58:7fc6e3e4d746 439 timer.detach();
FairyMental 58:7fc6e3e4d746 440 timer.attach(&SendSignalDoMeasure, sampleRate);
aburch1 81:996c0a3319b4 441 snprintf(temp, 256, "Successfully updated sample rate to: %2.2f .\r\n",sampleRate);
aburch1 81:996c0a3319b4 442 logger.SendMessage(temp);
FairyMental 58:7fc6e3e4d746 443 }
FairyMental 58:7fc6e3e4d746 444 else
FairyMental 58:7fc6e3e4d746 445 {
aburch1 81:996c0a3319b4 446 logger.SendMessage("Sample rate must be between 0.1 and 60.\r\n");
FairyMental 58:7fc6e3e4d746 447 }
FairyMental 58:7fc6e3e4d746 448 }
aburch1 83:0d3572a8a851 449 // Check if it's a "help" command
aburch1 81:996c0a3319b4 450 else if (CompareCommands(charPos,"help",4) || CompareCommands(charPos,"?",1))
aburch1 75:b44645bbf2d2 451 {
aburch1 82:668b51a39148 452 logger.SendMessage("\nAvailable Commands:\r\n");
aburch1 82:668b51a39148 453 logger.SendMessage(" read <all|n> - Read all or n first measures.\r\n");
aburch1 82:668b51a39148 454 logger.SendMessage(" delete <all|n> - Delete all or n first measures.\r\n");
aburch1 81:996c0a3319b4 455 logger.SendMessage(" setdate <DD> <MM> <YYYY> Set current date.\r\n");
aburch1 81:996c0a3319b4 456 logger.SendMessage(" settime <HH> <MM> <SS> Set current time.\r\n");
aburch1 81:996c0a3319b4 457 logger.SendMessage(" sett <T> Set sample rate (in seconds).\r\n");
aburch1 81:996c0a3319b4 458 logger.SendMessage(" status - Status report of device.\r\n");
aburch1 82:668b51a39148 459 logger.SendMessage(" state - <on|off> - Turn sampling on or off.\r\n");
aburch1 82:668b51a39148 460 logger.SendMessage(" logging <on|off> - Turn logging on or off.\r\n");
aburch1 83:0d3572a8a851 461 logger.SendMessage(" reset - Resets the current session of the application.\r\n");
aburch1 82:668b51a39148 462 }
aburch1 83:0d3572a8a851 463 // Check if it's a "reset" command
aburch1 82:668b51a39148 464 else if (CompareCommands(charPos,"reset",5))
aburch1 82:668b51a39148 465 {
aburch1 82:668b51a39148 466 logger.SendError("Program Terminating...\r\n");
aburch1 75:b44645bbf2d2 467 }
aburch1 83:0d3572a8a851 468 // If command is not recognized
FairyMental 60:db8c5b7fc548 469 else
FairyMental 60:db8c5b7fc548 470 {
aburch1 81:996c0a3319b4 471 logger.SendMessage("Command not recognized. Type \"help\" for more info.\r\n");
FairyMental 60:db8c5b7fc548 472 }
aburch1 83:0d3572a8a851 473
aburch1 83:0d3572a8a851 474 if(!logging)
aburch1 82:668b51a39148 475 {
aburch1 82:668b51a39148 476 logger.SendMessage("\r\nAwaiting Command:\r\n");
aburch1 82:668b51a39148 477 }
aburch1 83:0d3572a8a851 478
aburch1 83:0d3572a8a851 479 // Clear currently stored command
FairyMental 41:d222c043c96d 480 int i = 0;
aburch1 83:0d3572a8a851 481 for(i =0 ; i < crtSize; i++)
FairyMental 41:d222c043c96d 482 command[i] = ' ';
FairyMental 41:d222c043c96d 483 command[0] = 0;
aburch1 83:0d3572a8a851 484 crtSize = 0;
FairyMental 41:d222c043c96d 485 }
FairyMental 41:d222c043c96d 486 }
FairyMental 39:618ad21e2b34 487 }
FairyMental 39:618ad21e2b34 488 }
aburch1 73:cfad270d2f2c 489
aburch1 83:0d3572a8a851 490 /**
aburch1 83:0d3572a8a851 491 Waits for a signal from the MessageLogger before confirming a message is to be printed,
aburch1 83:0d3572a8a851 492 ensuring messages are displayed in the correct order.
aburch1 83:0d3572a8a851 493
aburch1 83:0d3572a8a851 494 If an error is recieved, error is prioritised and signal is sent to the main thread for the
aburch1 83:0d3572a8a851 495 program to be terminated, waiting for user input to reset.
aburch1 83:0d3572a8a851 496 */
aburch1 73:cfad270d2f2c 497 void LoggingThread()
aburch1 83:0d3572a8a851 498 {
aburch1 82:668b51a39148 499 while(true)
aburch1 82:668b51a39148 500 {
aburch1 82:668b51a39148 501 Thread::signal_wait(SIGNAL_printMessage);
aburch1 82:668b51a39148 502
aburch1 82:668b51a39148 503 while(true)
aburch1 82:668b51a39148 504 {
aburch1 75:b44645bbf2d2 505 if(logger.GetError())
aburch1 75:b44645bbf2d2 506 {
aburch1 82:668b51a39148 507 osSignalSet(mainThreadId, SIGNAL_terminate);
aburch1 75:b44645bbf2d2 508 }
aburch1 75:b44645bbf2d2 509 else if(!logger.GetMessage())
aburch1 75:b44645bbf2d2 510 {
aburch1 82:668b51a39148 511 break;
aburch1 82:668b51a39148 512 }
aburch1 82:668b51a39148 513 }
aburch1 82:668b51a39148 514 }
aburch1 73:cfad270d2f2c 515 }
FairyMental 34:09ed07f2acba 516
aburch1 83:0d3572a8a851 517 /**
aburch1 83:0d3572a8a851 518 Main Thread: Entry point to program.
aburch1 83:0d3572a8a851 519 */
FairyMental 34:09ed07f2acba 520 int main() {
aburch1 83:0d3572a8a851 521
aburch1 83:0d3572a8a851 522 mainThreadId = osThreadGetId();
aburch1 83:0d3572a8a851 523
FairyMental 34:09ed07f2acba 524 measurer.init();
FairyMental 34:09ed07f2acba 525 measurer.calib();
Netaphous 54:53ee2d07d684 526
aburch1 83:0d3572a8a851 527 localDate = new LocalDate();
FairyMental 34:09ed07f2acba 528
aburch1 83:0d3572a8a851 529 // Timer initialised for measurements to be collected every sampleRate seconds.
FairyMental 58:7fc6e3e4d746 530 timer.attach(&SendSignalDoMeasure, sampleRate);
FairyMental 46:0de1f3c7d118 531 realTimeDate.attach(&RealTimeDate,1.0);
FairyMental 34:09ed07f2acba 532
aburch1 83:0d3572a8a851 533 // Start Threads
aburch1 83:0d3572a8a851 534
aburch1 80:959151952153 535 loggingThread = new Thread();
aburch1 80:959151952153 536 loggingThread->start(LoggingThread);
aburch1 80:959151952153 537
aburch1 80:959151952153 538 logger.SetThread(loggingThread);
aburch1 80:959151952153 539
aburch1 83:0d3572a8a851 540 producerThread = new Thread();
aburch1 83:0d3572a8a851 541 producerThread->start(ProducerThread);
aburch1 83:0d3572a8a851 542
aburch1 83:0d3572a8a851 543 measurementThread = new Thread();
aburch1 83:0d3572a8a851 544 measurementThread->start(MeasurementThread);
aburch1 83:0d3572a8a851 545
aburch1 83:0d3572a8a851 546 consumerThread = new Thread();
aburch1 83:0d3572a8a851 547 consumerThread->start(ConsumerThread);
aburch1 74:749727490f44 548
aburch1 82:668b51a39148 549 logger.SendMessage("\r\n--- W E L C O M E ---\r\n");
aburch1 82:668b51a39148 550
aburch1 82:668b51a39148 551 SendSignalDoMeasure();
FairyMental 34:09ed07f2acba 552
aburch1 75:b44645bbf2d2 553 while(true)
martinsimpson 32:260a288be58f 554 {
aburch1 83:0d3572a8a851 555 // Waits for temination signal from logging thread when an error is received.
aburch1 82:668b51a39148 556 osSignalWait(SIGNAL_terminate, osWaitForever);
aburch1 82:668b51a39148 557
aburch1 83:0d3572a8a851 558 producerThread->terminate();
aburch1 83:0d3572a8a851 559 measurementThread->terminate();
aburch1 83:0d3572a8a851 560 consumerThread->terminate();
aburch1 82:668b51a39148 561 loggingThread->terminate();
aburch1 82:668b51a39148 562
aburch1 83:0d3572a8a851 563 // Waits for user input before resetting the system.
aburch1 82:668b51a39148 564 printf("Press any key to restart...");
aburch1 82:668b51a39148 565 char c = getchar();
aburch1 83:0d3572a8a851 566 printf("===============================\n\n\n");
aburch1 82:668b51a39148 567 NVIC_SystemReset();
FairyMental 68:d3765f93c16a 568 }
Netaphous 70:ee19a73ed215 569 }