3rd Repo, trying to figure this out.

Dependencies:   LPS25H hts221

Fork of SOFT253_Template_Weather_OS_54 by Stage-1 Students SoCEM

Committer:
niallfrancis
Date:
Sat May 13 17:35:58 2017 +0000
Revision:
85:422d0a1b95cf
Parent:
83:0d3572a8a851
Finished commenting classes;

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;
niallfrancis 85:422d0a1b95cf 187
aburch1 83:0d3572a8a851 188 /**
aburch1 83:0d3572a8a851 189 Compares two char arrays and returns result
aburch1 83:0d3572a8a851 190
aburch1 83:0d3572a8a851 191 @param command : First char Array / pointer
aburch1 83:0d3572a8a851 192 @param targetCommand : Second char Array / pointer
aburch1 83:0d3572a8a851 193 @param size : Size of the smallest char arrays (between param1 and param2)
aburch1 83:0d3572a8a851 194 @return : TRUE if equal, FALSE if not equal
aburch1 83:0d3572a8a851 195 */
aburch1 83:0d3572a8a851 196 bool CompareCommands(char command[],char targetCommand[], int size)
FairyMental 42:b1f29874ab70 197 {
aburch1 83:0d3572a8a851 198 for(i = 0; i < size; i ++)
aburch1 83:0d3572a8a851 199 {
aburch1 83:0d3572a8a851 200 if(command[i] != targetCommand[i])
aburch1 83:0d3572a8a851 201 {
aburch1 83:0d3572a8a851 202 return false;
FairyMental 42:b1f29874ab70 203 }
aburch1 83:0d3572a8a851 204 }
aburch1 83:0d3572a8a851 205 return true;
aburch1 83:0d3572a8a851 206 }
aburch1 74:749727490f44 207
aburch1 83:0d3572a8a851 208 /**
aburch1 83:0d3572a8a851 209 Reads commands from the terminal and 'consumes' the data accordingly.
aburch1 83:0d3572a8a851 210 */
aburch1 83:0d3572a8a851 211 void ConsumerThread()
FairyMental 39:618ad21e2b34 212 {
FairyMental 41:d222c043c96d 213 char charCmd;
aburch1 83:0d3572a8a851 214 //Char array that stores the chars entered when user presses enter.
FairyMental 41:d222c043c96d 215 char command[40];
FairyMental 57:dfcdda1e42b6 216 //Current Command Size
aburch1 83:0d3572a8a851 217 int crtSize = 0;
aburch1 81:996c0a3319b4 218 logger.SendMessage("\r\nAwaiting Command: \r\n");
FairyMental 39:618ad21e2b34 219 while(1)
FairyMental 39:618ad21e2b34 220 {
FairyMental 41:d222c043c96d 221 charCmd = NULL;
FairyMental 41:d222c043c96d 222 charCmd = getchar();
aburch1 82:668b51a39148 223 if(logging)
aburch1 82:668b51a39148 224 {
aburch1 82:668b51a39148 225 logging = false;
aburch1 83:0d3572a8a851 226 logger.SendMessage("\rKey Pressed. Debug logging disabled.\r\n");
aburch1 82:668b51a39148 227 charCmd = NULL;
aburch1 82:668b51a39148 228 }
aburch1 80:959151952153 229
FairyMental 41:d222c043c96d 230 if(charCmd != NULL)
FairyMental 41:d222c043c96d 231 {
FairyMental 57:dfcdda1e42b6 232 //If BACKSPACE is pressed, Print "DEL" so it deletes last character typed.
aburch1 83:0d3572a8a851 233 if (charCmd == 127 && crtSize > 0 )
FairyMental 43:3983059e0d91 234 {
aburch1 83:0d3572a8a851 235 command[--crtSize] = '\0';
FairyMental 43:3983059e0d91 236 }
FairyMental 57:dfcdda1e42b6 237 //If NOT enter AND NOT Backspace is pressed, SAVE the char
FairyMental 57:dfcdda1e42b6 238 else if(charCmd != 13 && charCmd != 127)
FairyMental 41:d222c043c96d 239 {
aburch1 83:0d3572a8a851 240 command[crtSize++] = charCmd;
FairyMental 41:d222c043c96d 241 }
aburch1 83:0d3572a8a851 242 // If enter is pressed, process the command.
aburch1 83:0d3572a8a851 243 else if(charCmd == 13)
FairyMental 49:83bea7fb2728 244 {
aburch1 83:0d3572a8a851 245 logger.SendMessage("\n");
aburch1 83:0d3572a8a851 246 // Get first word of command.
FairyMental 43:3983059e0d91 247 char *charPos;
FairyMental 43:3983059e0d91 248 charPos = strtok(command," -,");
FairyMental 57:dfcdda1e42b6 249
aburch1 83:0d3572a8a851 250 // Check if it's a "read" command
aburch1 81:996c0a3319b4 251 if(CompareCommands(charPos, "read",4))
FairyMental 42:b1f29874ab70 252 {
FairyMental 43:3983059e0d91 253 charPos = strtok(NULL," -,");
aburch1 83:0d3572a8a851 254 // Check if it's a "read all" command
aburch1 81:996c0a3319b4 255 if(CompareCommands(charPos, "all",3))
aburch1 82:668b51a39148 256 {
Netaphous 65:3723d2729b68 257 // Changed to use circular buffer rather than list buffer
Netaphous 65:3723d2729b68 258 buffer.readAll();
aburch1 81:996c0a3319b4 259 logger.SendMessage("D O N E ! \r\n");
FairyMental 43:3983059e0d91 260 }
aburch1 83:0d3572a8a851 261 // Check if it's a "read n" command
FairyMental 43:3983059e0d91 262 else if(strtol(charPos,NULL,10) != 0)
FairyMental 43:3983059e0d91 263 {
aburch1 81:996c0a3319b4 264 int num = atoi(charPos);
aburch1 80:959151952153 265
aburch1 83:0d3572a8a851 266 buffer.readN(num);
aburch1 81:996c0a3319b4 267 logger.SendMessage("D O N E ! \r\n");
FairyMental 60:db8c5b7fc548 268 }
FairyMental 60:db8c5b7fc548 269 else
FairyMental 60:db8c5b7fc548 270 {
aburch1 81:996c0a3319b4 271 logger.SendMessage("Expected parameters: \"all\" | \"n\", where n is a number.\r\n");
FairyMental 43:3983059e0d91 272 }
FairyMental 42:b1f29874ab70 273 }
aburch1 83:0d3572a8a851 274 // Check if it's a "delete" command
aburch1 81:996c0a3319b4 275 else if (CompareCommands(charPos,"delete",6))
FairyMental 44:b523c9a9dd97 276 {
FairyMental 44:b523c9a9dd97 277 charPos = strtok(NULL," -,");
aburch1 83:0d3572a8a851 278 // Check if it's a "delete all" command
aburch1 81:996c0a3319b4 279 if(CompareCommands(charPos,"all",3))
FairyMental 44:b523c9a9dd97 280 {
aburch1 81:996c0a3319b4 281 logger.SendMessage("Deleting all measures performed so far: \r\n");
Netaphous 65:3723d2729b68 282
Netaphous 65:3723d2729b68 283 buffer.deleteAll();
FairyMental 44:b523c9a9dd97 284 }
aburch1 83:0d3572a8a851 285 // Check if it's a "delete n" command
FairyMental 44:b523c9a9dd97 286 else if (strtol(charPos,NULL,10) != 0)
FairyMental 44:b523c9a9dd97 287 {
Netaphous 65:3723d2729b68 288 // Changed to use circular buffer rather than list buffer
aburch1 83:0d3572a8a851 289 buffer.deleteN(atoi(charPos));
aburch1 81:996c0a3319b4 290 logger.SendMessage("Elements deleted!\r\n");
FairyMental 60:db8c5b7fc548 291 }
FairyMental 60:db8c5b7fc548 292 else
FairyMental 60:db8c5b7fc548 293 {
aburch1 81:996c0a3319b4 294 logger.SendMessage("Expected parameters: \"all\" | \"n\", where n is a number.");
aburch1 81:996c0a3319b4 295 }
FairyMental 44:b523c9a9dd97 296 }
aburch1 83:0d3572a8a851 297 // Check if it's a "status" command
aburch1 81:996c0a3319b4 298 else if (CompareCommands(charPos,"status",6))
FairyMental 45:9a33f2bc2b4e 299 {
FairyMental 46:0de1f3c7d118 300 char *ptr = localDate->ToString();
Netaphous 65:3723d2729b68 301
aburch1 82:668b51a39148 302 snprintf(temp, 256, "\nStatus: \r\n");
aburch1 82:668b51a39148 303 logger.SendMessage(temp);
aburch1 82:668b51a39148 304 snprintf(temp, 256, " # of measures: %i \r\n", buffer.getSize());
aburch1 82:668b51a39148 305 logger.SendMessage(temp);
aburch1 82:668b51a39148 306 snprintf(temp, 256, " Sampling: %s \r\n", measuring ? "On" : "Off");
aburch1 82:668b51a39148 307 logger.SendMessage(temp);
aburch1 82:668b51a39148 308 snprintf(temp, 256, " Logging: %s \r\n", logging ? "On" : "Off");
aburch1 82:668b51a39148 309 logger.SendMessage(temp);
aburch1 82:668b51a39148 310 snprintf(temp, 256, " Current Date: %s \r\n", ptr);
aburch1 82:668b51a39148 311 logger.SendMessage(temp);
aburch1 82:668b51a39148 312 snprintf(temp, 256, " Sample Rate(s): %2.2f \r\n", sampleRate);
aburch1 81:996c0a3319b4 313 logger.SendMessage(temp);
FairyMental 45:9a33f2bc2b4e 314 }
aburch1 83:0d3572a8a851 315 //Check if it's a "settime" command
aburch1 81:996c0a3319b4 316 else if (CompareCommands(charPos,"settime",7))
FairyMental 48:a8219954b3f2 317 {
FairyMental 48:a8219954b3f2 318 int h,m,s;
aburch1 83:0d3572a8a851 319
aburch1 81:996c0a3319b4 320 charPos = strtok(NULL," -,");
FairyMental 48:a8219954b3f2 321 if(strtol(charPos,NULL,10) != 0)
FairyMental 48:a8219954b3f2 322 {
FairyMental 48:a8219954b3f2 323 h = atoi(charPos);
FairyMental 48:a8219954b3f2 324 }
aburch1 81:996c0a3319b4 325 charPos = strtok(NULL," -,");
FairyMental 48:a8219954b3f2 326 if(strtol(charPos,NULL,10) != 0)
FairyMental 48:a8219954b3f2 327 {
FairyMental 48:a8219954b3f2 328 m = atoi(charPos);
FairyMental 48:a8219954b3f2 329 }
aburch1 81:996c0a3319b4 330 charPos = strtok(NULL," -,");
FairyMental 48:a8219954b3f2 331 if(strtol(charPos,NULL,10) != 0)
FairyMental 48:a8219954b3f2 332 {
FairyMental 48:a8219954b3f2 333 s = atoi(charPos);
FairyMental 48:a8219954b3f2 334 }
FairyMental 48:a8219954b3f2 335 if((h>=0 && h < 24) && (m>=0 && m<60) && (s>=0 && s<60))
FairyMental 48:a8219954b3f2 336 {
FairyMental 48:a8219954b3f2 337 localDate->hour = h;
FairyMental 48:a8219954b3f2 338 localDate->min = m;
FairyMental 48:a8219954b3f2 339 localDate->sec = s;
FairyMental 60:db8c5b7fc548 340 char *ptr = localDate->ToString();
aburch1 81:996c0a3319b4 341 snprintf(temp, 256, "Updated Date to: %s \r\n", ptr);
aburch1 81:996c0a3319b4 342 logger.SendMessage(temp);
FairyMental 48:a8219954b3f2 343 }
FairyMental 48:a8219954b3f2 344 else
FairyMental 48:a8219954b3f2 345 {
aburch1 81:996c0a3319b4 346 logger.SendMessage("\r\nWrong format! please use HH-MM-SS. \r\n");
FairyMental 48:a8219954b3f2 347 }
FairyMental 48:a8219954b3f2 348 }
aburch1 83:0d3572a8a851 349 //Check if it's a "setdate" command
aburch1 81:996c0a3319b4 350 else if (CompareCommands(charPos,"setdate",7))
FairyMental 48:a8219954b3f2 351 {
FairyMental 48:a8219954b3f2 352 int d,m,y;
aburch1 83:0d3572a8a851 353
aburch1 81:996c0a3319b4 354 charPos = strtok(NULL," ,-");
FairyMental 48:a8219954b3f2 355 if(strtol(charPos,NULL,10) != 0)
FairyMental 48:a8219954b3f2 356 {
FairyMental 48:a8219954b3f2 357 d = atoi(charPos);
FairyMental 48:a8219954b3f2 358 }
aburch1 83:0d3572a8a851 359
aburch1 81:996c0a3319b4 360 charPos = strtok(NULL," ,-");
FairyMental 48:a8219954b3f2 361 if(strtol(charPos,NULL,10) != 0)
FairyMental 48:a8219954b3f2 362 {
FairyMental 48:a8219954b3f2 363 m = atoi(charPos);
FairyMental 48:a8219954b3f2 364 }
aburch1 83:0d3572a8a851 365
aburch1 81:996c0a3319b4 366 charPos = strtok(NULL," ,-");
FairyMental 48:a8219954b3f2 367 if(strtol(charPos,NULL,10) != 0)
FairyMental 48:a8219954b3f2 368 {
FairyMental 48:a8219954b3f2 369 y = atoi(charPos);
FairyMental 48:a8219954b3f2 370 }
aburch1 83:0d3572a8a851 371
FairyMental 48:a8219954b3f2 372 if((d>=0 && d < 31) && (m>=0 && m<13))
FairyMental 48:a8219954b3f2 373 {
FairyMental 48:a8219954b3f2 374 localDate->day = d;
FairyMental 48:a8219954b3f2 375 localDate->month = m;
FairyMental 48:a8219954b3f2 376 localDate->year = y;
FairyMental 60:db8c5b7fc548 377 char *ptr = localDate->ToString();
aburch1 81:996c0a3319b4 378 snprintf(temp, 256, "Updated Date to: %s \r\n", ptr);
aburch1 81:996c0a3319b4 379 logger.SendMessage(temp);
FairyMental 48:a8219954b3f2 380 }
FairyMental 48:a8219954b3f2 381 else
FairyMental 48:a8219954b3f2 382 {
aburch1 81:996c0a3319b4 383 logger.SendMessage("Wrong format! please use DD-MM-YYYY. \r\n");
FairyMental 48:a8219954b3f2 384 }
FairyMental 48:a8219954b3f2 385 }
aburch1 83:0d3572a8a851 386 // Check if it's a "state" command
aburch1 81:996c0a3319b4 387 else if(CompareCommands(charPos,"state",5))
FairyMental 49:83bea7fb2728 388 {
FairyMental 49:83bea7fb2728 389 charPos = strtok(NULL," ,");
aburch1 83:0d3572a8a851 390
aburch1 83:0d3572a8a851 391 // Check if it should be turned on / off
aburch1 81:996c0a3319b4 392 if(CompareCommands(charPos,"on",2))
FairyMental 49:83bea7fb2728 393 {
aburch1 83:0d3572a8a851 394 logger.SendMessage("Sampling turned on!\r\n");
aburch1 82:668b51a39148 395 timer.attach(&SendSignalDoMeasure, sampleRate);
aburch1 82:668b51a39148 396 SendSignalDoMeasure();
aburch1 82:668b51a39148 397 measuring = true;
FairyMental 49:83bea7fb2728 398 }
aburch1 81:996c0a3319b4 399 else if (CompareCommands(charPos,"off",3))
FairyMental 49:83bea7fb2728 400 {
aburch1 83:0d3572a8a851 401 logger.SendMessage("Sampling turned off!\r\n");
aburch1 82:668b51a39148 402 timer.detach();
aburch1 82:668b51a39148 403 measuring = false;
aburch1 82:668b51a39148 404 }
aburch1 82:668b51a39148 405 else
aburch1 82:668b51a39148 406 {
aburch1 82:668b51a39148 407 logger.SendMessage("Expected parameters: \"on\" | \"off\"\r\n");
aburch1 82:668b51a39148 408 }
aburch1 82:668b51a39148 409 }
aburch1 83:0d3572a8a851 410 // Check if it's a "logging" command
aburch1 82:668b51a39148 411 else if(CompareCommands(charPos,"logging",7))
aburch1 82:668b51a39148 412 {
aburch1 82:668b51a39148 413 charPos = strtok(NULL," ,");
aburch1 82:668b51a39148 414 //Check if it should be turned ON / OFF
aburch1 82:668b51a39148 415 if(CompareCommands(charPos,"on",2))
aburch1 82:668b51a39148 416 {
aburch1 82:668b51a39148 417 logging = true;
aburch1 83:0d3572a8a851 418 logger.SendMessage("Debug logging turned on!\r\n");
aburch1 82:668b51a39148 419 logger.SendMessage("Press any key to deactivate\r\n");
aburch1 82:668b51a39148 420 }
aburch1 82:668b51a39148 421 else if (CompareCommands(charPos,"off",3))
aburch1 82:668b51a39148 422 {
aburch1 82:668b51a39148 423 logger.SendMessage("Logging is already turned off.\r\n");
FairyMental 60:db8c5b7fc548 424 }
FairyMental 60:db8c5b7fc548 425 else
FairyMental 60:db8c5b7fc548 426 {
aburch1 81:996c0a3319b4 427 logger.SendMessage("Expected parameters: \"on\" | \"off\"\r\n");
FairyMental 49:83bea7fb2728 428 }
FairyMental 58:7fc6e3e4d746 429 }
aburch1 83:0d3572a8a851 430 // Check if it's a "sett" command
aburch1 81:996c0a3319b4 431 else if(CompareCommands(charPos,"sett",4))
FairyMental 58:7fc6e3e4d746 432 {
FairyMental 58:7fc6e3e4d746 433 charPos = strtok(NULL," ,");
aburch1 81:996c0a3319b4 434 double auxRate = atof(charPos);
FairyMental 68:d3765f93c16a 435 // Validate rate
aburch1 81:996c0a3319b4 436 if(auxRate >= 0.1 &&
aburch1 81:996c0a3319b4 437 auxRate <= 60)
FairyMental 58:7fc6e3e4d746 438 {
FairyMental 58:7fc6e3e4d746 439 sampleRate = auxRate;
FairyMental 58:7fc6e3e4d746 440 timer.detach();
FairyMental 58:7fc6e3e4d746 441 timer.attach(&SendSignalDoMeasure, sampleRate);
aburch1 81:996c0a3319b4 442 snprintf(temp, 256, "Successfully updated sample rate to: %2.2f .\r\n",sampleRate);
aburch1 81:996c0a3319b4 443 logger.SendMessage(temp);
FairyMental 58:7fc6e3e4d746 444 }
FairyMental 58:7fc6e3e4d746 445 else
FairyMental 58:7fc6e3e4d746 446 {
aburch1 81:996c0a3319b4 447 logger.SendMessage("Sample rate must be between 0.1 and 60.\r\n");
FairyMental 58:7fc6e3e4d746 448 }
FairyMental 58:7fc6e3e4d746 449 }
aburch1 83:0d3572a8a851 450 // Check if it's a "help" command
aburch1 81:996c0a3319b4 451 else if (CompareCommands(charPos,"help",4) || CompareCommands(charPos,"?",1))
aburch1 75:b44645bbf2d2 452 {
aburch1 82:668b51a39148 453 logger.SendMessage("\nAvailable Commands:\r\n");
aburch1 82:668b51a39148 454 logger.SendMessage(" read <all|n> - Read all or n first measures.\r\n");
aburch1 82:668b51a39148 455 logger.SendMessage(" delete <all|n> - Delete all or n first measures.\r\n");
aburch1 81:996c0a3319b4 456 logger.SendMessage(" setdate <DD> <MM> <YYYY> Set current date.\r\n");
aburch1 81:996c0a3319b4 457 logger.SendMessage(" settime <HH> <MM> <SS> Set current time.\r\n");
aburch1 81:996c0a3319b4 458 logger.SendMessage(" sett <T> Set sample rate (in seconds).\r\n");
aburch1 81:996c0a3319b4 459 logger.SendMessage(" status - Status report of device.\r\n");
aburch1 82:668b51a39148 460 logger.SendMessage(" state - <on|off> - Turn sampling on or off.\r\n");
aburch1 82:668b51a39148 461 logger.SendMessage(" logging <on|off> - Turn logging on or off.\r\n");
aburch1 83:0d3572a8a851 462 logger.SendMessage(" reset - Resets the current session of the application.\r\n");
aburch1 82:668b51a39148 463 }
aburch1 83:0d3572a8a851 464 // Check if it's a "reset" command
aburch1 82:668b51a39148 465 else if (CompareCommands(charPos,"reset",5))
aburch1 82:668b51a39148 466 {
aburch1 82:668b51a39148 467 logger.SendError("Program Terminating...\r\n");
aburch1 75:b44645bbf2d2 468 }
aburch1 83:0d3572a8a851 469 // If command is not recognized
FairyMental 60:db8c5b7fc548 470 else
FairyMental 60:db8c5b7fc548 471 {
aburch1 81:996c0a3319b4 472 logger.SendMessage("Command not recognized. Type \"help\" for more info.\r\n");
FairyMental 60:db8c5b7fc548 473 }
aburch1 83:0d3572a8a851 474
aburch1 83:0d3572a8a851 475 if(!logging)
aburch1 82:668b51a39148 476 {
aburch1 82:668b51a39148 477 logger.SendMessage("\r\nAwaiting Command:\r\n");
aburch1 82:668b51a39148 478 }
aburch1 83:0d3572a8a851 479
aburch1 83:0d3572a8a851 480 // Clear currently stored command
FairyMental 41:d222c043c96d 481 int i = 0;
aburch1 83:0d3572a8a851 482 for(i =0 ; i < crtSize; i++)
FairyMental 41:d222c043c96d 483 command[i] = ' ';
FairyMental 41:d222c043c96d 484 command[0] = 0;
aburch1 83:0d3572a8a851 485 crtSize = 0;
FairyMental 41:d222c043c96d 486 }
FairyMental 41:d222c043c96d 487 }
FairyMental 39:618ad21e2b34 488 }
FairyMental 39:618ad21e2b34 489 }
aburch1 73:cfad270d2f2c 490
aburch1 83:0d3572a8a851 491 /**
aburch1 83:0d3572a8a851 492 Waits for a signal from the MessageLogger before confirming a message is to be printed,
aburch1 83:0d3572a8a851 493 ensuring messages are displayed in the correct order.
aburch1 83:0d3572a8a851 494
aburch1 83:0d3572a8a851 495 If an error is recieved, error is prioritised and signal is sent to the main thread for the
aburch1 83:0d3572a8a851 496 program to be terminated, waiting for user input to reset.
aburch1 83:0d3572a8a851 497 */
aburch1 73:cfad270d2f2c 498 void LoggingThread()
aburch1 83:0d3572a8a851 499 {
aburch1 82:668b51a39148 500 while(true)
aburch1 82:668b51a39148 501 {
aburch1 82:668b51a39148 502 Thread::signal_wait(SIGNAL_printMessage);
aburch1 82:668b51a39148 503
aburch1 82:668b51a39148 504 while(true)
aburch1 82:668b51a39148 505 {
aburch1 75:b44645bbf2d2 506 if(logger.GetError())
aburch1 75:b44645bbf2d2 507 {
aburch1 82:668b51a39148 508 osSignalSet(mainThreadId, SIGNAL_terminate);
aburch1 75:b44645bbf2d2 509 }
aburch1 75:b44645bbf2d2 510 else if(!logger.GetMessage())
aburch1 75:b44645bbf2d2 511 {
aburch1 82:668b51a39148 512 break;
aburch1 82:668b51a39148 513 }
aburch1 82:668b51a39148 514 }
aburch1 82:668b51a39148 515 }
aburch1 73:cfad270d2f2c 516 }
FairyMental 34:09ed07f2acba 517
aburch1 83:0d3572a8a851 518 /**
aburch1 83:0d3572a8a851 519 Main Thread: Entry point to program.
aburch1 83:0d3572a8a851 520 */
FairyMental 34:09ed07f2acba 521 int main() {
aburch1 83:0d3572a8a851 522
aburch1 83:0d3572a8a851 523 mainThreadId = osThreadGetId();
aburch1 83:0d3572a8a851 524
FairyMental 34:09ed07f2acba 525 measurer.init();
FairyMental 34:09ed07f2acba 526 measurer.calib();
Netaphous 54:53ee2d07d684 527
aburch1 83:0d3572a8a851 528 localDate = new LocalDate();
FairyMental 34:09ed07f2acba 529
aburch1 83:0d3572a8a851 530 // Timer initialised for measurements to be collected every sampleRate seconds.
FairyMental 58:7fc6e3e4d746 531 timer.attach(&SendSignalDoMeasure, sampleRate);
FairyMental 46:0de1f3c7d118 532 realTimeDate.attach(&RealTimeDate,1.0);
FairyMental 34:09ed07f2acba 533
aburch1 83:0d3572a8a851 534 // Start Threads
aburch1 83:0d3572a8a851 535
aburch1 80:959151952153 536 loggingThread = new Thread();
aburch1 80:959151952153 537 loggingThread->start(LoggingThread);
aburch1 80:959151952153 538
aburch1 80:959151952153 539 logger.SetThread(loggingThread);
aburch1 80:959151952153 540
aburch1 83:0d3572a8a851 541 producerThread = new Thread();
aburch1 83:0d3572a8a851 542 producerThread->start(ProducerThread);
aburch1 83:0d3572a8a851 543
aburch1 83:0d3572a8a851 544 measurementThread = new Thread();
aburch1 83:0d3572a8a851 545 measurementThread->start(MeasurementThread);
aburch1 83:0d3572a8a851 546
aburch1 83:0d3572a8a851 547 consumerThread = new Thread();
aburch1 83:0d3572a8a851 548 consumerThread->start(ConsumerThread);
aburch1 74:749727490f44 549
aburch1 82:668b51a39148 550 logger.SendMessage("\r\n--- W E L C O M E ---\r\n");
aburch1 82:668b51a39148 551
aburch1 82:668b51a39148 552 SendSignalDoMeasure();
FairyMental 34:09ed07f2acba 553
aburch1 75:b44645bbf2d2 554 while(true)
martinsimpson 32:260a288be58f 555 {
aburch1 83:0d3572a8a851 556 // Waits for temination signal from logging thread when an error is received.
aburch1 82:668b51a39148 557 osSignalWait(SIGNAL_terminate, osWaitForever);
aburch1 82:668b51a39148 558
aburch1 83:0d3572a8a851 559 producerThread->terminate();
aburch1 83:0d3572a8a851 560 measurementThread->terminate();
aburch1 83:0d3572a8a851 561 consumerThread->terminate();
aburch1 82:668b51a39148 562 loggingThread->terminate();
aburch1 82:668b51a39148 563
aburch1 83:0d3572a8a851 564 // Waits for user input before resetting the system.
aburch1 82:668b51a39148 565 printf("Press any key to restart...");
aburch1 82:668b51a39148 566 char c = getchar();
aburch1 83:0d3572a8a851 567 printf("===============================\n\n\n");
aburch1 82:668b51a39148 568 NVIC_SystemReset();
FairyMental 68:d3765f93c16a 569 }
Netaphous 70:ee19a73ed215 570 }