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
Diff: main.cpp
- Revision:
- 12:a52996515063
- Parent:
- 11:30182b9aa833
- Child:
- 14:3c3aa4fd7e1a
diff -r 30182b9aa833 -r a52996515063 main.cpp --- a/main.cpp Sun Feb 22 20:28:21 2015 +0000 +++ b/main.cpp Sun Feb 22 22:08:37 2015 +0000 @@ -5,7 +5,8 @@ #include "GasUseCounter.h" #include "Thermometers.h" #include "VoltAlerter.h" -#include <stdarg.h> +#include "Watchdog.h" +#include "Logger.h" // Web and UDB ports const int WEBPORT = 80; // Port for web server @@ -33,10 +34,16 @@ // File system for SD card SDFileSystem sd(p5, p6, p7, p8, "sd"); +// Log file names +const char* gasPulseFileName = "/sd/curPulse.txt"; +const char* eventLogFileName = "/sd/log.txt"; +const char* dataLogFileBase = "/sd/"; + +// Logger +Logger logger(eventLogFileName, dataLogFileBase); + // Gas use counter DigitalIn gasPulsePin(p21); -const char* gasPulseFileName = "/sd/curPulse.txt"; -const char* logFilename = "/sd/log.txt"; GasUseCounter gasUseCounter(gasPulseFileName, gasPulsePin, pc); // Thermometers - DS18B20 OneWire Thermometer connections @@ -49,6 +56,9 @@ VoltAlerter voltAlerter2(p24); VoltAlerter voltAlerter3(p25); +// Watchdog +Watchdog watchdog; + // Broadcast message format // Data format of the broadcast message - senml - https://tools.ietf.org/html/draft-jennings-senml-08 // { @@ -77,28 +87,11 @@ 60; char broadcastMsgBuffer[broadcastMsgLen]; -// Utility function to log data -void LogData(const char* format, ...) -{ - FILE* fp = fopen(logFilename, "a"); - if (fp == NULL) - { - pc.printf ("Log ... Filename %s not found\r\n", logFilename); - } - else - { - va_list argptr; - va_start(argptr, format); - vfprintf(fp, format, argptr); - va_end(argptr); - fclose(fp); - } -} - // Send broadcast message with current data void SendInfoBroadcast() { led3 = true; + // Init the sending socket sendUDPSocket.init(); sendUDPSocket.set_broadcasting(); @@ -112,7 +105,7 @@ // printf("Temp: %.1f, Addr: %s, Time: %d\r\n", tempValues[tempIdx].tempInCentigrade, tempValues[tempIdx].address, tempValues[tempIdx].timeStamp); // } - // Send the broadcast + // Format the broadcast message time_t timeNow = time(NULL); strcpy(broadcastMsgBuffer, broadcastMsgPrefix); sprintf(broadcastMsgBuffer+strlen(broadcastMsgBuffer), broadcastMsgGasFormat, gasUseCounter.GetCount(), gasUseCounter.GetPulseRateMs()); @@ -145,11 +138,8 @@ pc.printf("Broadcast Didn't send all of %s\r\n", broadcastMsgBuffer); } - // Log - char timeBuf[32]; - time_t seconds = time(NULL); - strftime(timeBuf, 32, "%Y-%m-%d %H:%M:%S", localtime(&seconds)); - LogData("%s\t%d\t%d ms\n", timeBuf, gasUseCounter.GetCount(), gasUseCounter.GetPulseRateMs()); + // Log the data + logger.LogData(broadcastMsgBuffer); led3 = false; } @@ -180,6 +170,7 @@ RdWebServer webServer; webServer.addCommand("", RdWebServerCmdDef::CMD_SDORUSBFILE, NULL, "index.htm", false); webServer.addCommand("gear-gr.png", RdWebServerCmdDef::CMD_SDORUSBFILE, NULL, NULL, true); + webServer.addCommand("listfiles", RdWebServerCmdDef::CMD_SDORUSBFILE, NULL, "/", false); webServer.addCommand("getgascount", RdWebServerCmdDef::CMD_CALLBACK, &getGasUseCallback); webServer.addCommand("setgascount", RdWebServerCmdDef::CMD_CALLBACK, &setGasUseCallback); webServer.init(WEBPORT, &led4, baseWebFolder); @@ -220,6 +211,11 @@ } } +// #define TEST_WATCHDOG 1 +#ifdef TEST_WATCHDOG +int watchdogTestLoopCount = 0; +#endif + // Main int main() { @@ -244,6 +240,15 @@ // Web Server Thread httpServer(&http_thread, NULL, osPriorityNormal, (DEFAULT_STACK_SIZE * 3)); + // Record the reason for restarting in the log file + if (watchdog.WatchdogCausedRestart()) + logger.LogEvent("Watchdog Restart"); + else + logger.LogEvent("Normal Restart"); + + // Setup the watchdog for 10s reset + watchdog.SetTimeoutSecs(10); + // Time of last broadcast time_t timeOfLastBroadcast = time(NULL); const int TIME_BETWEEN_BROADCASTS_IN_SECS = 60; @@ -251,6 +256,7 @@ { osDelay(LOOP_DELAY_IN_MS); led1 = !led1; + watchdog.Feed(); // Service gas count if (gasUseCounter.Service()) @@ -276,6 +282,15 @@ // Set LED2 to the state of the first volt alerter led2 = voltAlerter1.GetState(); + +#ifdef TEST_WATCHDOG + // After about 20 seconds of operation we'll hang to test the watchdog + if (watchdogTestLoopCount++ > 80) + { + // This should cause watchdog to kick in and reset + osDelay(20000); + } +#endif } }