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

Committer:
Bobty
Date:
Fri Feb 20 22:53:28 2015 +0000
Revision:
7:113c68639d10
Parent:
6:b7064d33e402
Child:
8:5980547ae71c
Re-enabled pulse sensing and broadcast capabilities

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Bobty 0:f6611c8f453c 1 #include "mbed.h"
Bobty 0:f6611c8f453c 2 #include "EthernetInterface.h"
Bobty 5:5bccf48799d4 3 #include "NTPClient.h"
Bobty 5:5bccf48799d4 4 #include "RdWebServer.h"
Bobty 5:5bccf48799d4 5 #include "GasUseCounter.h"
Bobty 5:5bccf48799d4 6 #include <stdarg.h>
Bobty 5:5bccf48799d4 7
Bobty 7:113c68639d10 8 //#define TEST_REMOVE_UDP_AND_NTP 1
Bobty 6:b7064d33e402 9
Bobty 5:5bccf48799d4 10 // Web and UDB ports
Bobty 5:5bccf48799d4 11 const int WEBPORT = 80; // Port for web server
Bobty 5:5bccf48799d4 12 const int BROADCAST_PORT = 42853; // Arbitrarily chosen port number
Bobty 5:5bccf48799d4 13
Bobty 5:5bccf48799d4 14 // Ticker collects data
Bobty 6:b7064d33e402 15 //Ticker ticker;
Bobty 6:b7064d33e402 16 //const int TICK_MS = 250;
Bobty 5:5bccf48799d4 17
Bobty 5:5bccf48799d4 18 // Debugging and status
Bobty 5:5bccf48799d4 19 RawSerial pc(USBTX, USBRX);
Bobty 5:5bccf48799d4 20 DigitalOut led1(LED1); //ticking (flashes)
Bobty 5:5bccf48799d4 21 DigitalOut led2(LED2); //server listning status (flashes)
Bobty 5:5bccf48799d4 22 DigitalOut led3(LED3); //socket connecting status
Bobty 5:5bccf48799d4 23 DigitalOut led4(LED4); //server status
Bobty 5:5bccf48799d4 24
Bobty 5:5bccf48799d4 25 // Web server
Bobty 5:5bccf48799d4 26 EthernetInterface eth;
Bobty 5:5bccf48799d4 27 NTPClient ntp;
Bobty 5:5bccf48799d4 28 UDPSocket sendUDPSocket;
Bobty 5:5bccf48799d4 29 Endpoint broadcastEndpoint;
Bobty 5:5bccf48799d4 30
Bobty 5:5bccf48799d4 31 // File system for SD card
Bobty 4:0d3a207680b0 32 SDFileSystem sd(p5, p6, p7, p8, "sd");
Bobty 5:5bccf48799d4 33
Bobty 5:5bccf48799d4 34 // Gas use counter
Bobty 5:5bccf48799d4 35 DigitalIn gasPulsePin(p21);
Bobty 5:5bccf48799d4 36 const char* gasPulseFileName = "/sd/curPulse.txt";
Bobty 5:5bccf48799d4 37 const char* logFilename = "/sd/log.txt";
Bobty 5:5bccf48799d4 38 GasUseCounter gasUseCounter(gasPulseFileName, gasPulsePin, pc);
Bobty 5:5bccf48799d4 39
Bobty 5:5bccf48799d4 40 void LogData(const char* format, ...)
Bobty 5:5bccf48799d4 41 {
Bobty 5:5bccf48799d4 42 FILE* fp = fopen(logFilename, "a");
Bobty 5:5bccf48799d4 43 if (fp == NULL)
Bobty 5:5bccf48799d4 44 {
Bobty 5:5bccf48799d4 45 pc.printf ("Log ... Filename %s not found\r\n", logFilename);
Bobty 5:5bccf48799d4 46 }
Bobty 5:5bccf48799d4 47 else
Bobty 5:5bccf48799d4 48 {
Bobty 5:5bccf48799d4 49 va_list argptr;
Bobty 5:5bccf48799d4 50 va_start(argptr, format);
Bobty 5:5bccf48799d4 51 vfprintf(fp, format, argptr);
Bobty 5:5bccf48799d4 52 va_end(argptr);
Bobty 5:5bccf48799d4 53 fclose(fp);
Bobty 5:5bccf48799d4 54 }
Bobty 5:5bccf48799d4 55 }
Bobty 5:5bccf48799d4 56
Bobty 5:5bccf48799d4 57 void SendInfoBroadcast()
Bobty 5:5bccf48799d4 58 {
Bobty 5:5bccf48799d4 59 led3 = true;
Bobty 5:5bccf48799d4 60 // Init the sending socket
Bobty 5:5bccf48799d4 61 sendUDPSocket.init();
Bobty 5:5bccf48799d4 62 sendUDPSocket.set_broadcasting();
Bobty 5:5bccf48799d4 63 broadcastEndpoint.set_address("255.255.255.255", BROADCAST_PORT);
Bobty 5:5bccf48799d4 64
Bobty 5:5bccf48799d4 65 // Format message
Bobty 5:5bccf48799d4 66 char outBuf[200];
Bobty 5:5bccf48799d4 67 sprintf(outBuf, "{\"e\":[{\"n\":\"gasCount\",\"v\":%d},{\"n\":\"gasPulseRateMs\",\"v\":%d,\"u\":\"ms\"}]}",
Bobty 5:5bccf48799d4 68 gasUseCounter.GetCount(), gasUseCounter.GetPulseRateMs());
Bobty 5:5bccf48799d4 69
Bobty 5:5bccf48799d4 70 // Send
Bobty 5:5bccf48799d4 71 int bytesToSend = strlen(outBuf);
Bobty 5:5bccf48799d4 72 int rslt = sendUDPSocket.sendTo(broadcastEndpoint, outBuf, bytesToSend);
Bobty 5:5bccf48799d4 73 if (rslt == bytesToSend)
Bobty 5:5bccf48799d4 74 {
Bobty 5:5bccf48799d4 75 pc.printf("Broadcast Sent ok %s\n", outBuf);
Bobty 5:5bccf48799d4 76 }
Bobty 5:5bccf48799d4 77 else if (rslt == -1)
Bobty 5:5bccf48799d4 78 {
Bobty 5:5bccf48799d4 79 pc.printf("Broadcast Failed to send %s\n", outBuf);
Bobty 5:5bccf48799d4 80 }
Bobty 5:5bccf48799d4 81 else
Bobty 5:5bccf48799d4 82 {
Bobty 5:5bccf48799d4 83 pc.printf("Broadcast Didn't send all of %s\n", outBuf);
Bobty 5:5bccf48799d4 84 }
Bobty 5:5bccf48799d4 85
Bobty 5:5bccf48799d4 86 // Log
Bobty 5:5bccf48799d4 87 char timeBuf[32];
Bobty 5:5bccf48799d4 88 time_t seconds = time(NULL);
Bobty 5:5bccf48799d4 89 strftime(timeBuf, 32, "%Y-%m-%d %H:%M:%S", localtime(&seconds));
Bobty 5:5bccf48799d4 90 LogData("%s\t%d\t%d ms\n", timeBuf, gasUseCounter.GetCount(), gasUseCounter.GetPulseRateMs());
Bobty 5:5bccf48799d4 91
Bobty 5:5bccf48799d4 92 led3 = false;
Bobty 5:5bccf48799d4 93 }
Bobty 0:f6611c8f453c 94
Bobty 5:5bccf48799d4 95 // Ticker's tick function
Bobty 6:b7064d33e402 96 //void TickFunction()
Bobty 6:b7064d33e402 97 //{
Bobty 6:b7064d33e402 98 //}
Bobty 5:5bccf48799d4 99
Bobty 5:5bccf48799d4 100 char* getGasUseCallback(int method, char* cmdStr, char* argStr)
Bobty 5:5bccf48799d4 101 {
Bobty 5:5bccf48799d4 102 char* pResp = gasUseCounter.getGasUseCallback(cmdStr, argStr);
Bobty 5:5bccf48799d4 103 pc.printf("Returning gas use %s\r\n", pResp);
Bobty 5:5bccf48799d4 104 return pResp;
Bobty 5:5bccf48799d4 105 }
Bobty 5:5bccf48799d4 106
Bobty 5:5bccf48799d4 107 char* setGasUseCallback(int method, char* cmdStr, char* argStr)
Bobty 5:5bccf48799d4 108 {
Bobty 5:5bccf48799d4 109 pc.printf("Setting gas use count %s\n\r", argStr);
Bobty 5:5bccf48799d4 110 int newGasUse = 0;
Bobty 5:5bccf48799d4 111 char* eqStr = strchr(argStr, '=');
Bobty 5:5bccf48799d4 112 if (eqStr == NULL)
Bobty 5:5bccf48799d4 113 return "SetGasValue FAILED";
Bobty 5:5bccf48799d4 114 sscanf(eqStr+1, "%d", &newGasUse);
Bobty 5:5bccf48799d4 115 gasUseCounter.SetCount(newGasUse);
Bobty 5:5bccf48799d4 116 return "SetGasValue OK";
Bobty 5:5bccf48799d4 117 }
Bobty 5:5bccf48799d4 118
Bobty 5:5bccf48799d4 119 void http_thread(void const* arg)
Bobty 5:5bccf48799d4 120 {
Bobty 5:5bccf48799d4 121 char* baseWebFolder = "/sd/";
Bobty 5:5bccf48799d4 122
Bobty 5:5bccf48799d4 123 RdWebServer webServer;
Bobty 5:5bccf48799d4 124 webServer.addCommand("", RdWebServerCmdDef::CMD_SDORUSBFILE, NULL, "index.htm", false);
Bobty 5:5bccf48799d4 125 webServer.addCommand("gear-gr.png", RdWebServerCmdDef::CMD_SDORUSBFILE, NULL, NULL, true);
Bobty 5:5bccf48799d4 126 webServer.addCommand("getgascount", RdWebServerCmdDef::CMD_CALLBACK, &getGasUseCallback);
Bobty 5:5bccf48799d4 127 webServer.addCommand("setgascount", RdWebServerCmdDef::CMD_CALLBACK, &setGasUseCallback);
Bobty 0:f6611c8f453c 128
Bobty 5:5bccf48799d4 129 webServer.init(WEBPORT, &led4, baseWebFolder);
Bobty 5:5bccf48799d4 130
Bobty 5:5bccf48799d4 131 webServer.run();
Bobty 5:5bccf48799d4 132 }
Bobty 5:5bccf48799d4 133
Bobty 5:5bccf48799d4 134 void ntp_thread(void const* arg)
Bobty 5:5bccf48799d4 135 {
Bobty 5:5bccf48799d4 136 while (1)
Bobty 5:5bccf48799d4 137 {
Bobty 5:5bccf48799d4 138 pc.printf("Trying to update time...\r\n");
Bobty 5:5bccf48799d4 139 if (ntp.setTime("0.pool.ntp.org") == 0)
Bobty 5:5bccf48799d4 140 {
Bobty 5:5bccf48799d4 141 printf("Set time successfully\r\n");
Bobty 5:5bccf48799d4 142 time_t ctTime;
Bobty 5:5bccf48799d4 143 ctTime = time(NULL);
Bobty 5:5bccf48799d4 144 printf("Time is set to (UTC): %s\r\n", ctime(&ctTime));
Bobty 5:5bccf48799d4 145 }
Bobty 5:5bccf48799d4 146 else
Bobty 5:5bccf48799d4 147 {
Bobty 5:5bccf48799d4 148 printf("Cannot set from NTP\r\n");
Bobty 5:5bccf48799d4 149 }
Bobty 5:5bccf48799d4 150 // 1 hour
Bobty 5:5bccf48799d4 151 for (int i = 0; i < 60; i++)
Bobty 5:5bccf48799d4 152 {
Bobty 5:5bccf48799d4 153 for (int j = 0; j < 60; j++)
Bobty 5:5bccf48799d4 154 {
Bobty 5:5bccf48799d4 155 osDelay(1000);
Bobty 5:5bccf48799d4 156 }
Bobty 5:5bccf48799d4 157 pc.printf("Waited %d mins\r\n", i);
Bobty 5:5bccf48799d4 158 }
Bobty 6:b7064d33e402 159 #ifndef TEST_REMOVE_UDP_AND_NTP
Bobty 6:b7064d33e402 160 break;
Bobty 6:b7064d33e402 161 #endif
Bobty 5:5bccf48799d4 162 }
Bobty 5:5bccf48799d4 163 }
Bobty 5:5bccf48799d4 164
Bobty 0:f6611c8f453c 165 int main()
Bobty 0:f6611c8f453c 166 {
Bobty 0:f6611c8f453c 167 pc.baud(115200);
Bobty 5:5bccf48799d4 168 pc.printf("Gas Monitor V2 - Rob Dobson 2014\r\n");
Bobty 0:f6611c8f453c 169
Bobty 6:b7064d33e402 170 // ticker.attach(&TickFunction,TICK_MS / 1000.0);
Bobty 5:5bccf48799d4 171
Bobty 5:5bccf48799d4 172 // Get the current count from the SD Card
Bobty 5:5bccf48799d4 173 gasUseCounter.Init();
Bobty 0:f6611c8f453c 174
Bobty 5:5bccf48799d4 175 // setup ethernet interface
Bobty 5:5bccf48799d4 176 eth.init(); //Use DHCP
Bobty 5:5bccf48799d4 177 eth.connect();
Bobty 2:6bfef0839102 178
Bobty 5:5bccf48799d4 179 pc.printf("IP Address is %s\n\r", eth.getIPAddress());
Bobty 5:5bccf48799d4 180
Bobty 6:b7064d33e402 181 #ifndef TEST_REMOVE_UDP_AND_NTP
Bobty 5:5bccf48799d4 182 Thread ntpTimeSetter(&ntp_thread);
Bobty 6:b7064d33e402 183 #endif
Bobty 0:f6611c8f453c 184
Bobty 6:b7064d33e402 185 Thread httpServer(&http_thread, NULL, osPriorityNormal, (DEFAULT_STACK_SIZE * 3));
Bobty 5:5bccf48799d4 186
Bobty 5:5bccf48799d4 187 while(true)
Bobty 0:f6611c8f453c 188 {
Bobty 5:5bccf48799d4 189 osDelay(250);
Bobty 5:5bccf48799d4 190 led1 = !led1;
Bobty 5:5bccf48799d4 191
Bobty 5:5bccf48799d4 192 // Service gas count
Bobty 6:b7064d33e402 193 #ifndef TEST_REMOVE_UDP_AND_NTP
Bobty 5:5bccf48799d4 194 if (gasUseCounter.Service())
Bobty 5:5bccf48799d4 195 SendInfoBroadcast();
Bobty 6:b7064d33e402 196 #endif
Bobty 0:f6611c8f453c 197 }
Bobty 5:5bccf48799d4 198 }