Monitor for central heating system (e.g. 2zones+hw) Supports up to 15 temp probes (DS18B20/DS18S20) 3 valve monitors Gas pulse meter recording Use stand-alone or with nodeEnergyServer See http://robdobson.com/2015/09/central-heating-monitor
Dependencies: EthernetInterfacePlusHostname NTPClient Onewire RdWebServer SDFileSystem-RTOS mbed-rtos mbed-src
main.cpp@21:ccf053bab795, 2015-10-16 (annotated)
- Committer:
- Bobty
- Date:
- Fri Oct 16 08:37:30 2015 +0000
- Revision:
- 21:ccf053bab795
- Parent:
- 20:7933076df5af
Added names to thermometers and pumps; Added file upload and delete
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Bobty | 19:0367cb46d003 | 1 | // Gas usage monitor |
Bobty | 19:0367cb46d003 | 2 | // Counts pulses from a gas meter |
Bobty | 19:0367cb46d003 | 3 | // Monitors temperature sensors |
Bobty | 19:0367cb46d003 | 4 | // Monitors valve/pump activity |
Bobty | 19:0367cb46d003 | 5 | // Web interface and UDP broadcast |
Bobty | 19:0367cb46d003 | 6 | // Rob Dobson 2015 |
Bobty | 19:0367cb46d003 | 7 | |
Bobty | 0:f6611c8f453c | 8 | #include "mbed.h" |
Bobty | 0:f6611c8f453c | 9 | #include "EthernetInterface.h" |
Bobty | 5:5bccf48799d4 | 10 | #include "NTPClient.h" |
Bobty | 5:5bccf48799d4 | 11 | #include "RdWebServer.h" |
Bobty | 5:5bccf48799d4 | 12 | #include "GasUseCounter.h" |
Bobty | 9:0e103c2f869a | 13 | #include "Thermometers.h" |
Bobty | 10:72eb217def1f | 14 | #include "VoltAlerter.h" |
Bobty | 12:a52996515063 | 15 | #include "Watchdog.h" |
Bobty | 12:a52996515063 | 16 | #include "Logger.h" |
Bobty | 5:5bccf48799d4 | 17 | |
Bobty | 18:d419ccebc666 | 18 | // System name (used for hostname) |
Bobty | 18:d419ccebc666 | 19 | char systemName[20] = "RdGasUseMonitor"; |
Bobty | 18:d419ccebc666 | 20 | |
Bobty | 5:5bccf48799d4 | 21 | // Web and UDB ports |
Bobty | 5:5bccf48799d4 | 22 | const int WEBPORT = 80; // Port for web server |
Bobty | 5:5bccf48799d4 | 23 | const int BROADCAST_PORT = 42853; // Arbitrarily chosen port number |
Bobty | 5:5bccf48799d4 | 24 | |
Bobty | 11:30182b9aa833 | 25 | // Main loop delay between data collection passes |
Bobty | 9:0e103c2f869a | 26 | const int LOOP_DELAY_IN_MS = 250; |
Bobty | 5:5bccf48799d4 | 27 | |
Bobty | 5:5bccf48799d4 | 28 | // Debugging and status |
Bobty | 5:5bccf48799d4 | 29 | RawSerial pc(USBTX, USBRX); |
Bobty | 5:5bccf48799d4 | 30 | DigitalOut led1(LED1); //ticking (flashes) |
Bobty | 11:30182b9aa833 | 31 | DigitalOut led2(LED2); //state of the 1st voltage alerter |
Bobty | 5:5bccf48799d4 | 32 | DigitalOut led3(LED3); //socket connecting status |
Bobty | 5:5bccf48799d4 | 33 | DigitalOut led4(LED4); //server status |
Bobty | 5:5bccf48799d4 | 34 | |
Bobty | 5:5bccf48799d4 | 35 | // Web server |
Bobty | 5:5bccf48799d4 | 36 | UDPSocket sendUDPSocket; |
Bobty | 5:5bccf48799d4 | 37 | Endpoint broadcastEndpoint; |
Bobty | 5:5bccf48799d4 | 38 | |
Bobty | 10:72eb217def1f | 39 | // Network Time Protocol (NTP) |
Bobty | 10:72eb217def1f | 40 | NTPClient ntp; |
Bobty | 10:72eb217def1f | 41 | const int NTP_REFRESH_INTERVAL_HOURS = 1; |
Bobty | 10:72eb217def1f | 42 | |
Bobty | 20:7933076df5af | 43 | // Mutex for SD card access |
Bobty | 20:7933076df5af | 44 | Mutex sdCardMutex; |
Bobty | 20:7933076df5af | 45 | |
Bobty | 5:5bccf48799d4 | 46 | // File system for SD card |
Bobty | 4:0d3a207680b0 | 47 | SDFileSystem sd(p5, p6, p7, p8, "sd"); |
Bobty | 5:5bccf48799d4 | 48 | |
Bobty | 21:ccf053bab795 | 49 | // Base folder for web file system |
Bobty | 21:ccf053bab795 | 50 | char* baseWebFolder = "/sd/"; |
Bobty | 21:ccf053bab795 | 51 | |
Bobty | 12:a52996515063 | 52 | // Log file names |
Bobty | 19:0367cb46d003 | 53 | const char* gasPulseFileName1 = "/sd/curPulse.txt"; |
Bobty | 19:0367cb46d003 | 54 | const char* gasPulseFileName2 = "/sd/curPulse2.txt"; |
Bobty | 12:a52996515063 | 55 | const char* eventLogFileName = "/sd/log.txt"; |
Bobty | 12:a52996515063 | 56 | const char* dataLogFileBase = "/sd/"; |
Bobty | 12:a52996515063 | 57 | |
Bobty | 12:a52996515063 | 58 | // Logger |
Bobty | 20:7933076df5af | 59 | Logger logger(eventLogFileName, dataLogFileBase, sdCardMutex); |
Bobty | 12:a52996515063 | 60 | |
Bobty | 5:5bccf48799d4 | 61 | // Gas use counter |
Bobty | 5:5bccf48799d4 | 62 | DigitalIn gasPulsePin(p21); |
Bobty | 20:7933076df5af | 63 | GasUseCounter gasUseCounter(gasPulseFileName1, gasPulseFileName2, gasPulsePin, logger, sdCardMutex); |
Bobty | 5:5bccf48799d4 | 64 | |
Bobty | 8:5980547ae71c | 65 | // Thermometers - DS18B20 OneWire Thermometer connections |
Bobty | 8:5980547ae71c | 66 | const PinName tempSensorPins[] = { p22 }; |
Bobty | 20:7933076df5af | 67 | Thermometers thermometers(sizeof(tempSensorPins)/sizeof(PinName), tempSensorPins, LOOP_DELAY_IN_MS, logger); |
Bobty | 8:5980547ae71c | 68 | |
Bobty | 10:72eb217def1f | 69 | // Voltage Sensors / Alerters |
Bobty | 10:72eb217def1f | 70 | const int NUM_VOLT_ALERTERS = 3; |
Bobty | 10:72eb217def1f | 71 | VoltAlerter voltAlerter1(p23); |
Bobty | 10:72eb217def1f | 72 | VoltAlerter voltAlerter2(p24); |
Bobty | 10:72eb217def1f | 73 | VoltAlerter voltAlerter3(p25); |
Bobty | 10:72eb217def1f | 74 | |
Bobty | 12:a52996515063 | 75 | // Watchdog |
Bobty | 12:a52996515063 | 76 | Watchdog watchdog; |
Bobty | 12:a52996515063 | 77 | |
Bobty | 11:30182b9aa833 | 78 | // Broadcast message format |
Bobty | 11:30182b9aa833 | 79 | // Data format of the broadcast message - senml - https://tools.ietf.org/html/draft-jennings-senml-08 |
Bobty | 11:30182b9aa833 | 80 | // { |
Bobty | 11:30182b9aa833 | 81 | // "e": [ |
Bobty | 11:30182b9aa833 | 82 | // {"n":"gasCount","v":%d}, |
Bobty | 11:30182b9aa833 | 83 | // {"n":"gasPulseRateMs","v":%d,"u":"ms"}, |
Bobty | 11:30182b9aa833 | 84 | // {"n":"temp_%s","v":%0.1f,"u":"degC"}, |
Bobty | 11:30182b9aa833 | 85 | // ... |
Bobty | 11:30182b9aa833 | 86 | // {"n":"pump_%d","v":%d}, |
Bobty | 11:30182b9aa833 | 87 | // ... |
Bobty | 11:30182b9aa833 | 88 | // ], |
Bobty | 11:30182b9aa833 | 89 | // "bt": %d |
Bobty | 11:30182b9aa833 | 90 | // } |
Bobty | 10:72eb217def1f | 91 | const char broadcastMsgPrefix[] = "{\"e\":["; |
Bobty | 14:3c3aa4fd7e1a | 92 | const char broadcastMsgGasFormat[] = "{\"n\":\"gasCount\",\"v\":%d,\"u\":\"count\"},{\"n\":\"gasPulseRateMs\",\"v\":%d,\"u\":\"ms\"}"; |
Bobty | 21:ccf053bab795 | 93 | const char broadcastTemperatureFormat[] = "{\"n\":\"temp_%s_%s\",\"v\":%0.1f,\"u\":\"degC\"}"; |
Bobty | 21:ccf053bab795 | 94 | const char broadcastVoltAlerterFormat[] = "{\"n\":\"pump_%d_%s\",\"bv\":%d}"; |
Bobty | 10:72eb217def1f | 95 | const char broadcastMsgSuffix[] = "],\"bt\":%d}"; |
Bobty | 10:72eb217def1f | 96 | |
Bobty | 11:30182b9aa833 | 97 | // Broadcast message length and buffer |
Bobty | 21:ccf053bab795 | 98 | const int MAX_DEVICE_NAME_LEN = 20; |
Bobty | 10:72eb217def1f | 99 | const int broadcastMsgLen = sizeof(broadcastMsgPrefix) + |
Bobty | 10:72eb217def1f | 100 | sizeof(broadcastMsgGasFormat) + |
Bobty | 21:ccf053bab795 | 101 | ((sizeof(broadcastTemperatureFormat)+MAX_DEVICE_NAME_LEN)*Thermometers::MAX_THERMOMETERS) + |
Bobty | 21:ccf053bab795 | 102 | ((sizeof(broadcastVoltAlerterFormat)+MAX_DEVICE_NAME_LEN)*NUM_VOLT_ALERTERS) + |
Bobty | 10:72eb217def1f | 103 | sizeof(broadcastMsgSuffix) + |
Bobty | 10:72eb217def1f | 104 | 60; |
Bobty | 10:72eb217def1f | 105 | char broadcastMsgBuffer[broadcastMsgLen]; |
Bobty | 21:ccf053bab795 | 106 | |
Bobty | 21:ccf053bab795 | 107 | // Handling of SD card file delete and file upload commands |
Bobty | 21:ccf053bab795 | 108 | const int MAX_FNAME_LENGTH = 127; |
Bobty | 21:ccf053bab795 | 109 | char fileNameForWrite[MAX_FNAME_LENGTH+1] = ""; |
Bobty | 21:ccf053bab795 | 110 | int fileRemainingForWrite = 0; |
Bobty | 21:ccf053bab795 | 111 | |
Bobty | 21:ccf053bab795 | 112 | // Thermometer and pump names |
Bobty | 21:ccf053bab795 | 113 | char thermometerAddrs[][MAX_DEVICE_NAME_LEN] = |
Bobty | 21:ccf053bab795 | 114 | { |
Bobty | 21:ccf053bab795 | 115 | "28b1b1e0050000d0", |
Bobty | 21:ccf053bab795 | 116 | "289dd7c705000060", |
Bobty | 21:ccf053bab795 | 117 | "28b3b0c60500000a" |
Bobty | 21:ccf053bab795 | 118 | }; |
Bobty | 21:ccf053bab795 | 119 | char thermometerNames[][MAX_DEVICE_NAME_LEN] = |
Bobty | 21:ccf053bab795 | 120 | { |
Bobty | 21:ccf053bab795 | 121 | "HWCylinder", |
Bobty | 21:ccf053bab795 | 122 | "Inflow2", |
Bobty | 21:ccf053bab795 | 123 | "Outflow2" |
Bobty | 21:ccf053bab795 | 124 | }; |
Bobty | 21:ccf053bab795 | 125 | int numNamedThermometers = 3; |
Bobty | 21:ccf053bab795 | 126 | |
Bobty | 21:ccf053bab795 | 127 | char voltAlerterNames[][MAX_DEVICE_NAME_LEN] = |
Bobty | 21:ccf053bab795 | 128 | { |
Bobty | 21:ccf053bab795 | 129 | "PumpUpper", |
Bobty | 21:ccf053bab795 | 130 | "PumpLower", |
Bobty | 21:ccf053bab795 | 131 | "PumpHW" |
Bobty | 21:ccf053bab795 | 132 | }; |
Bobty | 21:ccf053bab795 | 133 | |
Bobty | 21:ccf053bab795 | 134 | // Get names of thermometers |
Bobty | 21:ccf053bab795 | 135 | char* getThermometerName(char* thermAddr) |
Bobty | 21:ccf053bab795 | 136 | { |
Bobty | 21:ccf053bab795 | 137 | for (int i = 0; i < numNamedThermometers; i++) |
Bobty | 21:ccf053bab795 | 138 | { |
Bobty | 21:ccf053bab795 | 139 | if (strcmp(thermometerAddrs[i], thermAddr) == 0) |
Bobty | 21:ccf053bab795 | 140 | return thermometerNames[i]; |
Bobty | 21:ccf053bab795 | 141 | } |
Bobty | 21:ccf053bab795 | 142 | return "Unknown"; |
Bobty | 21:ccf053bab795 | 143 | } |
Bobty | 21:ccf053bab795 | 144 | |
Bobty | 21:ccf053bab795 | 145 | // Get names of volt alerters |
Bobty | 21:ccf053bab795 | 146 | char* getVoltAlerterName(int idx) |
Bobty | 21:ccf053bab795 | 147 | { |
Bobty | 21:ccf053bab795 | 148 | if (idx >= 0 && idx < NUM_VOLT_ALERTERS) |
Bobty | 21:ccf053bab795 | 149 | { |
Bobty | 21:ccf053bab795 | 150 | return voltAlerterNames[idx]; |
Bobty | 21:ccf053bab795 | 151 | } |
Bobty | 21:ccf053bab795 | 152 | return "Unknown"; |
Bobty | 21:ccf053bab795 | 153 | } |
Bobty | 21:ccf053bab795 | 154 | |
Bobty | 14:3c3aa4fd7e1a | 155 | // Format broadcast message |
Bobty | 14:3c3aa4fd7e1a | 156 | void GenBroadcastMessage() |
Bobty | 5:5bccf48799d4 | 157 | { |
Bobty | 9:0e103c2f869a | 158 | // Get temperature values |
Bobty | 9:0e103c2f869a | 159 | TemperatureValue tempValues[Thermometers::MAX_THERMOMETERS]; |
Bobty | 9:0e103c2f869a | 160 | int numTempValues = thermometers.GetTemperatureValues(Thermometers::MAX_THERMOMETERS, tempValues, 100); |
Bobty | 11:30182b9aa833 | 161 | // for (int tempIdx = 0; tempIdx < numTempValues; tempIdx++) |
Bobty | 11:30182b9aa833 | 162 | // { |
Bobty | 11:30182b9aa833 | 163 | // printf("Temp: %.1f, Addr: %s, Time: %d\r\n", tempValues[tempIdx].tempInCentigrade, tempValues[tempIdx].address, tempValues[tempIdx].timeStamp); |
Bobty | 11:30182b9aa833 | 164 | // } |
Bobty | 14:3c3aa4fd7e1a | 165 | |
Bobty | 12:a52996515063 | 166 | // Format the broadcast message |
Bobty | 10:72eb217def1f | 167 | time_t timeNow = time(NULL); |
Bobty | 10:72eb217def1f | 168 | strcpy(broadcastMsgBuffer, broadcastMsgPrefix); |
Bobty | 10:72eb217def1f | 169 | sprintf(broadcastMsgBuffer+strlen(broadcastMsgBuffer), broadcastMsgGasFormat, gasUseCounter.GetCount(), gasUseCounter.GetPulseRateMs()); |
Bobty | 10:72eb217def1f | 170 | strcpy(broadcastMsgBuffer+strlen(broadcastMsgBuffer), ","); |
Bobty | 10:72eb217def1f | 171 | for (int tempIdx = 0; tempIdx < numTempValues; tempIdx++) |
Bobty | 10:72eb217def1f | 172 | { |
Bobty | 21:ccf053bab795 | 173 | sprintf(broadcastMsgBuffer+strlen(broadcastMsgBuffer), broadcastTemperatureFormat, tempValues[tempIdx].address, |
Bobty | 21:ccf053bab795 | 174 | getThermometerName(tempValues[tempIdx].address), |
Bobty | 21:ccf053bab795 | 175 | tempValues[tempIdx].tempInCentigrade); |
Bobty | 10:72eb217def1f | 176 | strcpy(broadcastMsgBuffer+strlen(broadcastMsgBuffer), ","); |
Bobty | 10:72eb217def1f | 177 | } |
Bobty | 21:ccf053bab795 | 178 | sprintf(broadcastMsgBuffer+strlen(broadcastMsgBuffer), broadcastVoltAlerterFormat, 1, getVoltAlerterName(0), voltAlerter1.GetState()); |
Bobty | 10:72eb217def1f | 179 | strcpy(broadcastMsgBuffer+strlen(broadcastMsgBuffer), ","); |
Bobty | 21:ccf053bab795 | 180 | sprintf(broadcastMsgBuffer+strlen(broadcastMsgBuffer), broadcastVoltAlerterFormat, 2, getVoltAlerterName(1), voltAlerter2.GetState()); |
Bobty | 10:72eb217def1f | 181 | strcpy(broadcastMsgBuffer+strlen(broadcastMsgBuffer), ","); |
Bobty | 21:ccf053bab795 | 182 | sprintf(broadcastMsgBuffer+strlen(broadcastMsgBuffer), broadcastVoltAlerterFormat, 3, getVoltAlerterName(2), voltAlerter3.GetState()); |
Bobty | 10:72eb217def1f | 183 | sprintf(broadcastMsgBuffer+strlen(broadcastMsgBuffer), broadcastMsgSuffix, timeNow); |
Bobty | 14:3c3aa4fd7e1a | 184 | } |
Bobty | 14:3c3aa4fd7e1a | 185 | |
Bobty | 14:3c3aa4fd7e1a | 186 | // Send broadcast message with current data |
Bobty | 14:3c3aa4fd7e1a | 187 | void SendInfoBroadcast() |
Bobty | 14:3c3aa4fd7e1a | 188 | { |
Bobty | 14:3c3aa4fd7e1a | 189 | led3 = true; |
Bobty | 14:3c3aa4fd7e1a | 190 | |
Bobty | 14:3c3aa4fd7e1a | 191 | // Init the sending socket |
Bobty | 14:3c3aa4fd7e1a | 192 | sendUDPSocket.init(); |
Bobty | 14:3c3aa4fd7e1a | 193 | sendUDPSocket.set_broadcasting(); |
Bobty | 14:3c3aa4fd7e1a | 194 | broadcastEndpoint.set_address("255.255.255.255", BROADCAST_PORT); |
Bobty | 10:72eb217def1f | 195 | |
Bobty | 14:3c3aa4fd7e1a | 196 | // Format the message |
Bobty | 14:3c3aa4fd7e1a | 197 | GenBroadcastMessage(); |
Bobty | 14:3c3aa4fd7e1a | 198 | |
Bobty | 5:5bccf48799d4 | 199 | // Send |
Bobty | 10:72eb217def1f | 200 | int bytesToSend = strlen(broadcastMsgBuffer); |
Bobty | 10:72eb217def1f | 201 | int rslt = sendUDPSocket.sendTo(broadcastEndpoint, broadcastMsgBuffer, bytesToSend); |
Bobty | 5:5bccf48799d4 | 202 | if (rslt == bytesToSend) |
Bobty | 5:5bccf48799d4 | 203 | { |
Bobty | 20:7933076df5af | 204 | logger.LogDebug("Broadcast (len %d) Sent ok %s", bytesToSend, broadcastMsgBuffer); |
Bobty | 5:5bccf48799d4 | 205 | } |
Bobty | 5:5bccf48799d4 | 206 | else if (rslt == -1) |
Bobty | 5:5bccf48799d4 | 207 | { |
Bobty | 20:7933076df5af | 208 | logger.LogDebug("Broadcast Failed to send %s", broadcastMsgBuffer); |
Bobty | 5:5bccf48799d4 | 209 | } |
Bobty | 5:5bccf48799d4 | 210 | else |
Bobty | 5:5bccf48799d4 | 211 | { |
Bobty | 20:7933076df5af | 212 | logger.LogDebug("Broadcast Didn't send all of %s", broadcastMsgBuffer); |
Bobty | 5:5bccf48799d4 | 213 | } |
Bobty | 5:5bccf48799d4 | 214 | |
Bobty | 12:a52996515063 | 215 | // Log the data |
Bobty | 12:a52996515063 | 216 | logger.LogData(broadcastMsgBuffer); |
Bobty | 5:5bccf48799d4 | 217 | |
Bobty | 5:5bccf48799d4 | 218 | led3 = false; |
Bobty | 5:5bccf48799d4 | 219 | } |
Bobty | 0:f6611c8f453c | 220 | |
Bobty | 16:89778849e9f7 | 221 | char* getCurDataCallback(int method, char* cmdStr, char* argStr, char* msgBuffer, int msgLen, |
Bobty | 16:89778849e9f7 | 222 | int contentLen, unsigned char* pPayload, int payloadLen, int splitPayloadPos) |
Bobty | 5:5bccf48799d4 | 223 | { |
Bobty | 14:3c3aa4fd7e1a | 224 | // Format message |
Bobty | 14:3c3aa4fd7e1a | 225 | GenBroadcastMessage(); |
Bobty | 14:3c3aa4fd7e1a | 226 | return broadcastMsgBuffer; |
Bobty | 5:5bccf48799d4 | 227 | } |
Bobty | 5:5bccf48799d4 | 228 | |
Bobty | 16:89778849e9f7 | 229 | char* setGasUseCallback(int method, char* cmdStr, char* argStr, char* msgBuffer, int msgLen, |
Bobty | 16:89778849e9f7 | 230 | int contentLen, unsigned char* pPayload, int payloadLen, int splitPayloadPos) |
Bobty | 5:5bccf48799d4 | 231 | { |
Bobty | 20:7933076df5af | 232 | logger.LogDebug("Setting gas use count %s", argStr); |
Bobty | 5:5bccf48799d4 | 233 | int newGasUse = 0; |
Bobty | 5:5bccf48799d4 | 234 | char* eqStr = strchr(argStr, '='); |
Bobty | 5:5bccf48799d4 | 235 | if (eqStr == NULL) |
Bobty | 5:5bccf48799d4 | 236 | return "SetGasValue FAILED"; |
Bobty | 5:5bccf48799d4 | 237 | sscanf(eqStr+1, "%d", &newGasUse); |
Bobty | 5:5bccf48799d4 | 238 | gasUseCounter.SetCount(newGasUse); |
Bobty | 5:5bccf48799d4 | 239 | return "SetGasValue OK"; |
Bobty | 5:5bccf48799d4 | 240 | } |
Bobty | 5:5bccf48799d4 | 241 | |
Bobty | 21:ccf053bab795 | 242 | // Handle SD Card File Delete |
Bobty | 21:ccf053bab795 | 243 | char* sdCardDelete(int method, char* cmdStr, char* argStr, char* msgBuffer, int msgLen, |
Bobty | 21:ccf053bab795 | 244 | int contentLen, unsigned char* pPayload, int payloadLen, int splitPayloadPos) |
Bobty | 21:ccf053bab795 | 245 | { |
Bobty | 21:ccf053bab795 | 246 | printf("Delete file %s\r\n", argStr); |
Bobty | 21:ccf053bab795 | 247 | sdCardMutex.lock(); |
Bobty | 21:ccf053bab795 | 248 | char* baseWebFolder = "/sd/"; |
Bobty | 21:ccf053bab795 | 249 | char filename[MAX_FNAME_LENGTH+1]; |
Bobty | 21:ccf053bab795 | 250 | sprintf(filename, "%s%s", baseWebFolder, argStr); |
Bobty | 21:ccf053bab795 | 251 | printf("Full filename for delete is %s\r\n", filename); |
Bobty | 21:ccf053bab795 | 252 | bool delOk = (remove(filename) == 0); |
Bobty | 21:ccf053bab795 | 253 | sdCardMutex.unlock(); |
Bobty | 21:ccf053bab795 | 254 | if (delOk) |
Bobty | 21:ccf053bab795 | 255 | return "Delete OK"; |
Bobty | 21:ccf053bab795 | 256 | return "Delete Failed"; |
Bobty | 21:ccf053bab795 | 257 | } |
Bobty | 21:ccf053bab795 | 258 | |
Bobty | 21:ccf053bab795 | 259 | // Handle SD Card File Upload |
Bobty | 21:ccf053bab795 | 260 | char* sdCardUpload(int method, char* cmdStr, char* argStr, char* msgBuffer, int msgLen, |
Bobty | 21:ccf053bab795 | 261 | int contentLen, unsigned char* pPayload, int payloadLen, int splitPayloadPos) |
Bobty | 21:ccf053bab795 | 262 | { |
Bobty | 21:ccf053bab795 | 263 | printf("Upload file %s PayloadLen %d ContentLen %d MsgLen %d\r\n", argStr, payloadLen, contentLen, msgLen); |
Bobty | 21:ccf053bab795 | 264 | if (payloadLen == 0) |
Bobty | 21:ccf053bab795 | 265 | { |
Bobty | 21:ccf053bab795 | 266 | printf("Upload file - payload len == 0 - quitting\r\n"); |
Bobty | 21:ccf053bab795 | 267 | return "OK"; |
Bobty | 21:ccf053bab795 | 268 | } |
Bobty | 21:ccf053bab795 | 269 | |
Bobty | 21:ccf053bab795 | 270 | bool writeSuccess = false; |
Bobty | 21:ccf053bab795 | 271 | if (splitPayloadPos == 0) |
Bobty | 21:ccf053bab795 | 272 | { |
Bobty | 21:ccf053bab795 | 273 | // Get the filename |
Bobty | 21:ccf053bab795 | 274 | fileNameForWrite[0] = '\0'; |
Bobty | 21:ccf053bab795 | 275 | fileRemainingForWrite = 0; |
Bobty | 21:ccf053bab795 | 276 | char* filenameText = " filename=\""; |
Bobty | 21:ccf053bab795 | 277 | char* pFilename = strstr((char*)pPayload, filenameText); |
Bobty | 21:ccf053bab795 | 278 | if ((pFilename != NULL) && (pFilename - ((char*)pPayload) < 200)) |
Bobty | 21:ccf053bab795 | 279 | { |
Bobty | 21:ccf053bab795 | 280 | pFilename += strlen(filenameText); |
Bobty | 21:ccf053bab795 | 281 | char* pEndFileName = strstr(pFilename, "\""); |
Bobty | 21:ccf053bab795 | 282 | if (pEndFileName != NULL) |
Bobty | 21:ccf053bab795 | 283 | { |
Bobty | 21:ccf053bab795 | 284 | int fileNameLen = pEndFileName - pFilename; |
Bobty | 21:ccf053bab795 | 285 | if (fileNameLen + strlen(baseWebFolder) < MAX_FNAME_LENGTH) |
Bobty | 21:ccf053bab795 | 286 | { |
Bobty | 21:ccf053bab795 | 287 | strcpy(fileNameForWrite, baseWebFolder); |
Bobty | 21:ccf053bab795 | 288 | strncpy(fileNameForWrite+strlen(baseWebFolder), pFilename, fileNameLen); |
Bobty | 21:ccf053bab795 | 289 | fileNameForWrite[fileNameLen+strlen(baseWebFolder)] = '\0'; |
Bobty | 21:ccf053bab795 | 290 | printf("Upload file - filename %s\r\n", fileNameForWrite); |
Bobty | 21:ccf053bab795 | 291 | } |
Bobty | 21:ccf053bab795 | 292 | else |
Bobty | 21:ccf053bab795 | 293 | { |
Bobty | 21:ccf053bab795 | 294 | printf("Upload file - filename too long - quitting\r\n"); |
Bobty | 21:ccf053bab795 | 295 | } |
Bobty | 21:ccf053bab795 | 296 | } |
Bobty | 21:ccf053bab795 | 297 | else |
Bobty | 21:ccf053bab795 | 298 | { |
Bobty | 21:ccf053bab795 | 299 | printf("Upload file - end of filename not found - quitting\r\n"); |
Bobty | 21:ccf053bab795 | 300 | } |
Bobty | 21:ccf053bab795 | 301 | } |
Bobty | 21:ccf053bab795 | 302 | else |
Bobty | 21:ccf053bab795 | 303 | { |
Bobty | 21:ccf053bab795 | 304 | printf("Upload file - filename not found (or not near start of message) - quitting\r\n"); |
Bobty | 21:ccf053bab795 | 305 | } |
Bobty | 21:ccf053bab795 | 306 | // Write first chunk to file |
Bobty | 21:ccf053bab795 | 307 | if (strlen(fileNameForWrite) > 0) |
Bobty | 21:ccf053bab795 | 308 | { |
Bobty | 21:ccf053bab795 | 309 | // Find the chunk start |
Bobty | 21:ccf053bab795 | 310 | char* chunkStartText = "\r\n\r\n"; |
Bobty | 21:ccf053bab795 | 311 | char* pChunk = strstr((char*)pPayload, chunkStartText); |
Bobty | 21:ccf053bab795 | 312 | if ((pChunk != NULL) && (pChunk - ((char*)pPayload) < 300)) |
Bobty | 21:ccf053bab795 | 313 | { |
Bobty | 21:ccf053bab795 | 314 | pChunk += strlen(chunkStartText); |
Bobty | 21:ccf053bab795 | 315 | // Find chunk len |
Bobty | 21:ccf053bab795 | 316 | int headerLen = pChunk - ((char*)pPayload); |
Bobty | 21:ccf053bab795 | 317 | int chunkLen = payloadLen - headerLen; |
Bobty | 21:ccf053bab795 | 318 | fileRemainingForWrite = contentLen - headerLen; |
Bobty | 21:ccf053bab795 | 319 | int numBytesToWrite = chunkLen; |
Bobty | 21:ccf053bab795 | 320 | if (fileRemainingForWrite > 0) |
Bobty | 21:ccf053bab795 | 321 | { |
Bobty | 21:ccf053bab795 | 322 | // Check for end boundary of data |
Bobty | 21:ccf053bab795 | 323 | if ((fileRemainingForWrite - chunkLen < 100) && (payloadLen > 50)) |
Bobty | 21:ccf053bab795 | 324 | { |
Bobty | 21:ccf053bab795 | 325 | char* pEndForm = strstr(((char*)pPayload) + payloadLen - 50, "\r\n------"); |
Bobty | 21:ccf053bab795 | 326 | if (pEndForm != NULL) |
Bobty | 21:ccf053bab795 | 327 | { |
Bobty | 21:ccf053bab795 | 328 | numBytesToWrite = pEndForm - pChunk; |
Bobty | 21:ccf053bab795 | 329 | printf("Upload file - payload end found writing %d bytes\r\n", numBytesToWrite); |
Bobty | 21:ccf053bab795 | 330 | } |
Bobty | 21:ccf053bab795 | 331 | } |
Bobty | 21:ccf053bab795 | 332 | // Write chunk to file |
Bobty | 21:ccf053bab795 | 333 | sdCardMutex.lock(); |
Bobty | 21:ccf053bab795 | 334 | FILE* fp = fopen(fileNameForWrite, "w+"); |
Bobty | 21:ccf053bab795 | 335 | if (fp == NULL) |
Bobty | 21:ccf053bab795 | 336 | { |
Bobty | 21:ccf053bab795 | 337 | printf("Upload file - Failed to open output file\r\n"); |
Bobty | 21:ccf053bab795 | 338 | } |
Bobty | 21:ccf053bab795 | 339 | else |
Bobty | 21:ccf053bab795 | 340 | { |
Bobty | 21:ccf053bab795 | 341 | fwrite(pChunk, sizeof(char), numBytesToWrite, fp); |
Bobty | 21:ccf053bab795 | 342 | fclose(fp); |
Bobty | 21:ccf053bab795 | 343 | printf("Upload file - written %d bytes\r\n", numBytesToWrite); |
Bobty | 21:ccf053bab795 | 344 | writeSuccess = true; |
Bobty | 21:ccf053bab795 | 345 | } |
Bobty | 21:ccf053bab795 | 346 | sdCardMutex.unlock(); |
Bobty | 21:ccf053bab795 | 347 | // Reduce remaining bytes |
Bobty | 21:ccf053bab795 | 348 | fileRemainingForWrite -= chunkLen; |
Bobty | 21:ccf053bab795 | 349 | } |
Bobty | 21:ccf053bab795 | 350 | else |
Bobty | 21:ccf053bab795 | 351 | { |
Bobty | 21:ccf053bab795 | 352 | printf("Upload file - file remaining for write <= 0 - quitting\r\n"); |
Bobty | 21:ccf053bab795 | 353 | } |
Bobty | 21:ccf053bab795 | 354 | } |
Bobty | 21:ccf053bab795 | 355 | else |
Bobty | 21:ccf053bab795 | 356 | { |
Bobty | 21:ccf053bab795 | 357 | printf("Upload file - can't find chunk start - quitting\r\n"); |
Bobty | 21:ccf053bab795 | 358 | } |
Bobty | 21:ccf053bab795 | 359 | } |
Bobty | 21:ccf053bab795 | 360 | else |
Bobty | 21:ccf053bab795 | 361 | { |
Bobty | 21:ccf053bab795 | 362 | printf("Upload file - filename blank - quitting\r\n"); |
Bobty | 21:ccf053bab795 | 363 | } |
Bobty | 21:ccf053bab795 | 364 | |
Bobty | 21:ccf053bab795 | 365 | } |
Bobty | 21:ccf053bab795 | 366 | else |
Bobty | 21:ccf053bab795 | 367 | { |
Bobty | 21:ccf053bab795 | 368 | if (strlen(fileNameForWrite) != 0) |
Bobty | 21:ccf053bab795 | 369 | { |
Bobty | 21:ccf053bab795 | 370 | if (fileRemainingForWrite > 0) |
Bobty | 21:ccf053bab795 | 371 | { |
Bobty | 21:ccf053bab795 | 372 | int numBytesToWrite = payloadLen; |
Bobty | 21:ccf053bab795 | 373 | // Check for end boundary of data |
Bobty | 21:ccf053bab795 | 374 | if ((fileRemainingForWrite - payloadLen < 100) && (payloadLen > 50)) |
Bobty | 21:ccf053bab795 | 375 | { |
Bobty | 21:ccf053bab795 | 376 | char* pEndForm = strstr(((char*)pPayload) + payloadLen - 50, "\r\n------"); |
Bobty | 21:ccf053bab795 | 377 | if (pEndForm != NULL) |
Bobty | 21:ccf053bab795 | 378 | { |
Bobty | 21:ccf053bab795 | 379 | numBytesToWrite = pEndForm - ((char*)pPayload); |
Bobty | 21:ccf053bab795 | 380 | printf("Upload file - payload end found writing %d bytes\r\n", numBytesToWrite); |
Bobty | 21:ccf053bab795 | 381 | } |
Bobty | 21:ccf053bab795 | 382 | } |
Bobty | 21:ccf053bab795 | 383 | sdCardMutex.lock(); |
Bobty | 21:ccf053bab795 | 384 | FILE* fp = fopen(fileNameForWrite, "a"); |
Bobty | 21:ccf053bab795 | 385 | if (fp == NULL) |
Bobty | 21:ccf053bab795 | 386 | { |
Bobty | 21:ccf053bab795 | 387 | printf("Failed to open output file\r\n"); |
Bobty | 21:ccf053bab795 | 388 | } |
Bobty | 21:ccf053bab795 | 389 | else |
Bobty | 21:ccf053bab795 | 390 | { |
Bobty | 21:ccf053bab795 | 391 | fwrite(pPayload, sizeof(char), numBytesToWrite, fp); |
Bobty | 21:ccf053bab795 | 392 | fclose(fp); |
Bobty | 21:ccf053bab795 | 393 | writeSuccess = true; |
Bobty | 21:ccf053bab795 | 394 | printf("Upload file - written %d bytes\r\n", numBytesToWrite); |
Bobty | 21:ccf053bab795 | 395 | } |
Bobty | 21:ccf053bab795 | 396 | sdCardMutex.unlock(); |
Bobty | 21:ccf053bab795 | 397 | // Reduce remaining bytes |
Bobty | 21:ccf053bab795 | 398 | fileRemainingForWrite -= payloadLen; |
Bobty | 21:ccf053bab795 | 399 | } |
Bobty | 21:ccf053bab795 | 400 | else |
Bobty | 21:ccf053bab795 | 401 | { |
Bobty | 21:ccf053bab795 | 402 | printf("Upload file - file remaining for write <= 0 - quitting\r\n"); |
Bobty | 21:ccf053bab795 | 403 | } |
Bobty | 21:ccf053bab795 | 404 | } |
Bobty | 21:ccf053bab795 | 405 | else |
Bobty | 21:ccf053bab795 | 406 | { |
Bobty | 21:ccf053bab795 | 407 | printf("Upload file - filename blank - quitting\r\n"); |
Bobty | 21:ccf053bab795 | 408 | } |
Bobty | 21:ccf053bab795 | 409 | } |
Bobty | 21:ccf053bab795 | 410 | |
Bobty | 21:ccf053bab795 | 411 | // Return results |
Bobty | 21:ccf053bab795 | 412 | if (writeSuccess) |
Bobty | 21:ccf053bab795 | 413 | return "Write OK"; |
Bobty | 21:ccf053bab795 | 414 | return "Write Failed"; |
Bobty | 21:ccf053bab795 | 415 | } |
Bobty | 21:ccf053bab795 | 416 | |
Bobty | 11:30182b9aa833 | 417 | // Create, configure and run the web server |
Bobty | 5:5bccf48799d4 | 418 | void http_thread(void const* arg) |
Bobty | 5:5bccf48799d4 | 419 | { |
Bobty | 20:7933076df5af | 420 | RdWebServer webServer(&sdCardMutex); |
Bobty | 5:5bccf48799d4 | 421 | webServer.addCommand("", RdWebServerCmdDef::CMD_SDORUSBFILE, NULL, "index.htm", false); |
Bobty | 5:5bccf48799d4 | 422 | webServer.addCommand("gear-gr.png", RdWebServerCmdDef::CMD_SDORUSBFILE, NULL, NULL, true); |
Bobty | 12:a52996515063 | 423 | webServer.addCommand("listfiles", RdWebServerCmdDef::CMD_SDORUSBFILE, NULL, "/", false); |
Bobty | 14:3c3aa4fd7e1a | 424 | webServer.addCommand("getcurdata", RdWebServerCmdDef::CMD_CALLBACK, &getCurDataCallback); |
Bobty | 5:5bccf48799d4 | 425 | webServer.addCommand("setgascount", RdWebServerCmdDef::CMD_CALLBACK, &setGasUseCallback); |
Bobty | 21:ccf053bab795 | 426 | webServer.addCommand("delete", RdWebServerCmdDef::CMD_CALLBACK, &sdCardDelete); |
Bobty | 21:ccf053bab795 | 427 | webServer.addCommand("upload", RdWebServerCmdDef::CMD_CALLBACK, &sdCardUpload); |
Bobty | 5:5bccf48799d4 | 428 | webServer.init(WEBPORT, &led4, baseWebFolder); |
Bobty | 5:5bccf48799d4 | 429 | webServer.run(); |
Bobty | 5:5bccf48799d4 | 430 | } |
Bobty | 5:5bccf48799d4 | 431 | |
Bobty | 11:30182b9aa833 | 432 | // Network time protocol (NTP) thread to get time from internet |
Bobty | 5:5bccf48799d4 | 433 | void ntp_thread(void const* arg) |
Bobty | 5:5bccf48799d4 | 434 | { |
Bobty | 5:5bccf48799d4 | 435 | while (1) |
Bobty | 5:5bccf48799d4 | 436 | { |
Bobty | 20:7933076df5af | 437 | logger.LogDebug("Trying to update time..."); |
Bobty | 14:3c3aa4fd7e1a | 438 | if (ntp.setTime("0.pool.ntp.org") == NTP_OK) |
Bobty | 5:5bccf48799d4 | 439 | { |
Bobty | 19:0367cb46d003 | 440 | osDelay(1000); // This delay is simply to try to improve printf output |
Bobty | 20:7933076df5af | 441 | logger.LogDebug("Set time successfully"); |
Bobty | 19:0367cb46d003 | 442 | time_t ctTime; |
Bobty | 19:0367cb46d003 | 443 | ctTime = time(NULL); |
Bobty | 20:7933076df5af | 444 | logger.LogDebug("Time is set to (UTC): %s", ctime(&ctTime)); |
Bobty | 5:5bccf48799d4 | 445 | } |
Bobty | 5:5bccf48799d4 | 446 | else |
Bobty | 5:5bccf48799d4 | 447 | { |
Bobty | 20:7933076df5af | 448 | logger.LogDebug("Cannot set from NTP"); |
Bobty | 10:72eb217def1f | 449 | } |
Bobty | 10:72eb217def1f | 450 | |
Bobty | 10:72eb217def1f | 451 | // Refresh time every K hours |
Bobty | 10:72eb217def1f | 452 | for (int k = 0; k < NTP_REFRESH_INTERVAL_HOURS; k++) |
Bobty | 5:5bccf48799d4 | 453 | { |
Bobty | 10:72eb217def1f | 454 | // 1 hour |
Bobty | 10:72eb217def1f | 455 | for (int i = 0; i < 60; i++) |
Bobty | 5:5bccf48799d4 | 456 | { |
Bobty | 10:72eb217def1f | 457 | for (int j = 0; j < 60; j++) |
Bobty | 10:72eb217def1f | 458 | { |
Bobty | 10:72eb217def1f | 459 | osDelay(1000); |
Bobty | 10:72eb217def1f | 460 | } |
Bobty | 20:7933076df5af | 461 | logger.LogDebug("%d mins to next NTP time refresh", (NTP_REFRESH_INTERVAL_HOURS-k-1)*60 + (59-i)); |
Bobty | 5:5bccf48799d4 | 462 | } |
Bobty | 5:5bccf48799d4 | 463 | } |
Bobty | 5:5bccf48799d4 | 464 | } |
Bobty | 5:5bccf48799d4 | 465 | } |
Bobty | 9:0e103c2f869a | 466 | |
Bobty | 12:a52996515063 | 467 | // #define TEST_WATCHDOG 1 |
Bobty | 12:a52996515063 | 468 | #ifdef TEST_WATCHDOG |
Bobty | 12:a52996515063 | 469 | int watchdogTestLoopCount = 0; |
Bobty | 12:a52996515063 | 470 | #endif |
Bobty | 12:a52996515063 | 471 | |
Bobty | 11:30182b9aa833 | 472 | // Main |
Bobty | 0:f6611c8f453c | 473 | int main() |
Bobty | 0:f6611c8f453c | 474 | { |
Bobty | 0:f6611c8f453c | 475 | pc.baud(115200); |
Bobty | 20:7933076df5af | 476 | logger.SetDebugDest(true, true); |
Bobty | 20:7933076df5af | 477 | logger.LogDebug("\r\n\r\nGas Monitor V2 - Rob Dobson 2015"); |
Bobty | 0:f6611c8f453c | 478 | |
Bobty | 9:0e103c2f869a | 479 | // Initialise thermometers |
Bobty | 9:0e103c2f869a | 480 | thermometers.Init(); |
Bobty | 9:0e103c2f869a | 481 | |
Bobty | 5:5bccf48799d4 | 482 | // Get the current count from the SD Card |
Bobty | 5:5bccf48799d4 | 483 | gasUseCounter.Init(); |
Bobty | 0:f6611c8f453c | 484 | |
Bobty | 18:d419ccebc666 | 485 | // Setup ethernet interface |
Bobty | 18:d419ccebc666 | 486 | char macAddr[6]; |
Bobty | 18:d419ccebc666 | 487 | mbed_mac_address(macAddr); |
Bobty | 20:7933076df5af | 488 | logger.LogDebug("Ethernet MAC address: %02x:%02x:%02x:%02x:%02x:%02x", macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]); |
Bobty | 20:7933076df5af | 489 | logger.LogDebug("Connecting to ethernet ..."); |
Bobty | 18:d419ccebc666 | 490 | |
Bobty | 18:d419ccebc666 | 491 | // Init ethernet |
Bobty | 18:d419ccebc666 | 492 | EthernetInterface::init(); |
Bobty | 18:d419ccebc666 | 493 | |
Bobty | 18:d419ccebc666 | 494 | // Using code described here https://developer.mbed.org/questions/1602/How-to-set-the-TCPIP-stack-s-hostname-pr/ |
Bobty | 18:d419ccebc666 | 495 | // to setName on the ethernet interface |
Bobty | 18:d419ccebc666 | 496 | EthernetInterface::setName(systemName); |
Bobty | 18:d419ccebc666 | 497 | |
Bobty | 18:d419ccebc666 | 498 | // Connect ethernet |
Bobty | 18:d419ccebc666 | 499 | EthernetInterface::connect(); |
Bobty | 20:7933076df5af | 500 | logger.LogDebug("IP Address: %s HostName %s", EthernetInterface::getIPAddress(), EthernetInterface::getName()); |
Bobty | 8:5980547ae71c | 501 | |
Bobty | 8:5980547ae71c | 502 | // NTP Time setter |
Bobty | 5:5bccf48799d4 | 503 | Thread ntpTimeSetter(&ntp_thread); |
Bobty | 0:f6611c8f453c | 504 | |
Bobty | 8:5980547ae71c | 505 | // Web Server |
Bobty | 6:b7064d33e402 | 506 | Thread httpServer(&http_thread, NULL, osPriorityNormal, (DEFAULT_STACK_SIZE * 3)); |
Bobty | 14:3c3aa4fd7e1a | 507 | |
Bobty | 14:3c3aa4fd7e1a | 508 | // Store reason for restart |
Bobty | 14:3c3aa4fd7e1a | 509 | bool watchdogCausedRestart = watchdog.WatchdogCausedRestart(); |
Bobty | 14:3c3aa4fd7e1a | 510 | bool restartCauseRecorded = false; |
Bobty | 5:5bccf48799d4 | 511 | |
Bobty | 20:7933076df5af | 512 | // Setup the watchdog for reset |
Bobty | 21:ccf053bab795 | 513 | watchdog.SetTimeoutSecs(300); |
Bobty | 12:a52996515063 | 514 | |
Bobty | 9:0e103c2f869a | 515 | // Time of last broadcast |
Bobty | 9:0e103c2f869a | 516 | time_t timeOfLastBroadcast = time(NULL); |
Bobty | 9:0e103c2f869a | 517 | const int TIME_BETWEEN_BROADCASTS_IN_SECS = 60; |
Bobty | 5:5bccf48799d4 | 518 | while(true) |
Bobty | 0:f6611c8f453c | 519 | { |
Bobty | 14:3c3aa4fd7e1a | 520 | // Check if we can record the reason for restart (i.e. if time is now set) |
Bobty | 14:3c3aa4fd7e1a | 521 | if (!restartCauseRecorded) |
Bobty | 14:3c3aa4fd7e1a | 522 | { |
Bobty | 14:3c3aa4fd7e1a | 523 | time_t nowTime = time(NULL); |
Bobty | 14:3c3aa4fd7e1a | 524 | if (nowTime > 1000000000) |
Bobty | 14:3c3aa4fd7e1a | 525 | { |
Bobty | 14:3c3aa4fd7e1a | 526 | // Record the reason for restarting in the log file |
Bobty | 14:3c3aa4fd7e1a | 527 | if (watchdogCausedRestart) |
Bobty | 19:0367cb46d003 | 528 | { |
Bobty | 14:3c3aa4fd7e1a | 529 | logger.LogEvent("Watchdog Restart"); |
Bobty | 20:7933076df5af | 530 | logger.LogDebug("Watchdog Restart"); |
Bobty | 19:0367cb46d003 | 531 | } |
Bobty | 14:3c3aa4fd7e1a | 532 | else |
Bobty | 19:0367cb46d003 | 533 | { |
Bobty | 14:3c3aa4fd7e1a | 534 | logger.LogEvent("Normal Restart"); |
Bobty | 20:7933076df5af | 535 | logger.LogDebug("Normal Restart"); |
Bobty | 19:0367cb46d003 | 536 | } |
Bobty | 14:3c3aa4fd7e1a | 537 | restartCauseRecorded = true; |
Bobty | 14:3c3aa4fd7e1a | 538 | } |
Bobty | 14:3c3aa4fd7e1a | 539 | } |
Bobty | 14:3c3aa4fd7e1a | 540 | |
Bobty | 14:3c3aa4fd7e1a | 541 | // Loop delay |
Bobty | 9:0e103c2f869a | 542 | osDelay(LOOP_DELAY_IN_MS); |
Bobty | 14:3c3aa4fd7e1a | 543 | |
Bobty | 14:3c3aa4fd7e1a | 544 | // Feed the watchdog and show the flashing LED |
Bobty | 5:5bccf48799d4 | 545 | led1 = !led1; |
Bobty | 12:a52996515063 | 546 | watchdog.Feed(); |
Bobty | 5:5bccf48799d4 | 547 | |
Bobty | 5:5bccf48799d4 | 548 | // Service gas count |
Bobty | 5:5bccf48799d4 | 549 | if (gasUseCounter.Service()) |
Bobty | 8:5980547ae71c | 550 | { |
Bobty | 9:0e103c2f869a | 551 | SendInfoBroadcast(); |
Bobty | 9:0e103c2f869a | 552 | timeOfLastBroadcast = time(NULL); |
Bobty | 9:0e103c2f869a | 553 | } |
Bobty | 8:5980547ae71c | 554 | |
Bobty | 9:0e103c2f869a | 555 | // Service thermometers |
Bobty | 9:0e103c2f869a | 556 | thermometers.Service(); |
Bobty | 9:0e103c2f869a | 557 | |
Bobty | 9:0e103c2f869a | 558 | // Check if ready for a broadcast |
Bobty | 9:0e103c2f869a | 559 | if ((time(NULL) - timeOfLastBroadcast) >= TIME_BETWEEN_BROADCASTS_IN_SECS) |
Bobty | 9:0e103c2f869a | 560 | { |
Bobty | 9:0e103c2f869a | 561 | SendInfoBroadcast(); |
Bobty | 9:0e103c2f869a | 562 | timeOfLastBroadcast = time(NULL); |
Bobty | 8:5980547ae71c | 563 | } |
Bobty | 10:72eb217def1f | 564 | |
Bobty | 10:72eb217def1f | 565 | // Service volt alerters |
Bobty | 10:72eb217def1f | 566 | voltAlerter1.Service(); |
Bobty | 10:72eb217def1f | 567 | voltAlerter2.Service(); |
Bobty | 10:72eb217def1f | 568 | voltAlerter3.Service(); |
Bobty | 11:30182b9aa833 | 569 | |
Bobty | 11:30182b9aa833 | 570 | // Set LED2 to the state of the first volt alerter |
Bobty | 10:72eb217def1f | 571 | led2 = voltAlerter1.GetState(); |
Bobty | 12:a52996515063 | 572 | |
Bobty | 12:a52996515063 | 573 | #ifdef TEST_WATCHDOG |
Bobty | 12:a52996515063 | 574 | // After about 20 seconds of operation we'll hang to test the watchdog |
Bobty | 12:a52996515063 | 575 | if (watchdogTestLoopCount++ > 80) |
Bobty | 12:a52996515063 | 576 | { |
Bobty | 12:a52996515063 | 577 | // This should cause watchdog to kick in and reset |
Bobty | 12:a52996515063 | 578 | osDelay(20000); |
Bobty | 12:a52996515063 | 579 | } |
Bobty | 12:a52996515063 | 580 | #endif |
Bobty | 0:f6611c8f453c | 581 | } |
Bobty | 5:5bccf48799d4 | 582 | } |
Bobty | 9:0e103c2f869a | 583 |