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
Revision 19:0367cb46d003, committed 2015-10-05
- Comitter:
- Bobty
- Date:
- Mon Oct 05 14:05:33 2015 +0000
- Parent:
- 18:d419ccebc666
- Child:
- 20:7933076df5af
- Commit message:
- Added retries on getting addresses from thermometers; Doubled up on non-volatile storage of latest gas count
Changed in this revision
--- a/GasUseCounter.cpp Mon Sep 28 11:16:46 2015 +0000
+++ b/GasUseCounter.cpp Mon Oct 05 14:05:33 2015 +0000
@@ -1,3 +1,6 @@
+// Gas usage based on pulses from a gas meter
+// Rob Dobson 2015
+
#include "GasUseCounter.h"
// Callback from web server to handle getting current gas count
@@ -36,36 +39,59 @@
// Get the current usage count from SD card
void GasUseCounter::GetGasCountFromSD()
{
- FILE* fp = fopen(_gasUseFilename, "r");
- if (fp == NULL)
- {
- _pc.printf ("Read Gas ... Filename %s not found\r\n", _gasUseFilename);
- }
- else
+ int count0 = 0;
+ int count1 = 0;
+ for (int i = 0; i < 2; i++)
{
- int curCount = 0;
- int retVal = fscanf(fp, "%d", &curCount);
- fclose(fp);
- if (retVal == 1)
- _pc.printf ("Read from SD last gas count = %d\r\n", curCount);
+ const char* fname = _gasUseFilename1;
+ if (i == 1)
+ fname = _gasUseFilename2;
+ FILE* fp = fopen(fname, "r");
+ if (fp == NULL)
+ {
+ _pc.printf ("Read Gas ... Filename %s not found\r\n", fname);
+ }
else
- _pc.printf ("Failed to read gas count from SD card\r\n");
- _lastWrittenGasCount = curCount;
- _pulseDetector->SetPulseCount(curCount);
+ {
+ int curCount = 0;
+ int retVal = fscanf(fp, "%d", &curCount);
+ fclose(fp);
+ if (retVal == 1)
+ _pc.printf ("Read from file %s last gas count = %d\r\n", fname, curCount);
+ else
+ _pc.printf ("Failed to read gas count from file %s\r\n", fname);
+ if (i == 0)
+ count0 = curCount;
+ else
+ count1 = curCount;
+ }
}
+ // Find the highest count
+ int maxCount = count0;
+ if (count1 > count0)
+ maxCount = count1;
+ _lastWrittenGasCount = maxCount;
+ _pulseDetector->SetPulseCount(maxCount);
+ _pc.printf ("Pulse count set to %d\r\n", maxCount);
}
void GasUseCounter::WriteGasCountToSD()
{
- FILE* fp = fopen(_gasUseFilename, "w");
- if (fp == NULL)
+ for (int i = 0; i < 2; i++)
{
- _pc.printf ("WriteGas ... Filename %s not found\r\n", _gasUseFilename);
- }
- else
- {
- fprintf(fp, "%d", GetCount());
- _pc.printf ("Written to SD last gas count = %d\r\n", GetCount());
- fclose(fp);
+ const char* fname = _gasUseFilename1;
+ if (i == 1)
+ fname = _gasUseFilename2;
+ FILE* fp = fopen(fname, "w");
+ if (fp == NULL)
+ {
+ _pc.printf ("WriteGas ... Filename %s not found\r\n", fname);
+ }
+ else
+ {
+ fprintf(fp, "%d", GetCount());
+ _pc.printf ("Written to %s last gas count = %d\r\n", fname, GetCount());
+ fclose(fp);
+ }
}
}
--- a/GasUseCounter.h Mon Sep 28 11:16:46 2015 +0000
+++ b/GasUseCounter.h Mon Oct 05 14:05:33 2015 +0000
@@ -12,10 +12,11 @@
{
public:
// Constructor
- GasUseCounter(const char* gasUseFilename, DigitalIn& gasPulsePin, RawSerial &pc) :
+ GasUseCounter(const char* gasUseFilename1, const char* gasUseFilename2, DigitalIn& gasPulsePin, RawSerial &pc) :
_gasPulsePin(gasPulsePin), _pc(pc)
{
- _gasUseFilename = gasUseFilename;
+ _gasUseFilename1 = gasUseFilename1;
+ _gasUseFilename2 = gasUseFilename2;
_lastWrittenGasCount = 0;
_pulseDetector = new PulsePin(_gasPulsePin, false, 200);
}
@@ -54,7 +55,8 @@
private:
// Gas use filename for non-volatile
- const char* _gasUseFilename;
+ const char* _gasUseFilename1;
+ const char* _gasUseFilename2;
int _curGasCount;
int _lastWrittenGasCount;
char _gasCountStr [MAX_GAS_COUNT_STR_LEN];
--- a/Onewire.lib Mon Sep 28 11:16:46 2015 +0000 +++ b/Onewire.lib Mon Oct 05 14:05:33 2015 +0000 @@ -1,1 +1,1 @@ -https://developer.mbed.org/users/Bobty/code/Onewire/#45b6a39002f1 +https://developer.mbed.org/users/Bobty/code/Onewire/#d2452e9b169b
--- a/RdDS18B20.cpp Mon Sep 28 11:16:46 2015 +0000
+++ b/RdDS18B20.cpp Mon Oct 05 14:05:33 2015 +0000
@@ -133,58 +133,90 @@
int DS18B20::SearchToGetAddresses()
{
- _numValidAddresses = 0;
- for (int addrIdx = 0; addrIdx < MAX_BUS_DEVICES; addrIdx++)
- {
- uint8_t addr[8];
+
+ const int MAX_ADDR_SEARCH_RETRIES = 5;
- if ( !_oneWire.search(addr))
+ // Address Table
+ uint8_t tmpAddrTable[MAX_BUS_DEVICES][ONEWIRE_ADDR_BYTES];
+ int validAddresses = 0;
+ bool okResultAchieved = false;
+
+ // Try a number of times
+ for (int retryCount = 0; retryCount < MAX_ADDR_SEARCH_RETRIES; retryCount++)
+ {
+ // Check if the last search was ok (if there was one)
+ if (okResultAchieved)
{
-#ifdef SHOW_18B20_DEBUGGING
- printf("No more addresses.\r\n");
-#endif
- _oneWire.reset_search();
+ // Copy found addresses
+ for (int addrIdx = 0; addrIdx < validAddresses; addrIdx++)
+ {
+ for( int i = 0; i < ONEWIRE_ADDR_BYTES; i++)
+ _addrTable[addrIdx][i] = tmpAddrTable[addrIdx][i];
+ }
+ _numValidAddresses = validAddresses;
break;
}
-#ifdef SHOW_18B20_DEBUGGING
- printf("Found device addr (ROM) =");
-#endif
- for( int i = 0; i < ONEWIRE_ADDR_BYTES; i++)
+ // Start another search
+ validAddresses = 0;
+ _oneWire.reset_search();
+ for (int addrIdx = 0; addrIdx < MAX_BUS_DEVICES; addrIdx++)
{
- // Copy to table
- _addrTable[_numValidAddresses][i] = addr[i];
+ uint8_t addr[8];
+ uint8_t rslt = _oneWire.search(addr);
+ if (rslt == ONEWIRE_SEARCH_ALL_DONE)
+ {
+ if (validAddresses >= _numValidAddresses)
+ okResultAchieved = true;
+ break;
+ }
+ if (rslt != ONEWIRE_OK)
+ {
#ifdef SHOW_18B20_DEBUGGING
- printf(" %02x", addr[i]);
+ printf("Search returned %s\r\n", (rslt == ONEWIRE_SEARCH_INIT_FAIL) ? "InitFail" : ((rslt == ONEWIRE_SEARCH_NOT_FOUND) ? "NotFound" : "UnknownError"));
+#endif
+ break;
+ }
+
+#ifdef SHOW_18B20_DEBUGGING
+ printf("Found device addr (ROM) =");
#endif
- }
+ for( int i = 0; i < ONEWIRE_ADDR_BYTES; i++)
+ {
+ // Copy to table
+ tmpAddrTable[validAddresses][i] = addr[i];
+#ifdef SHOW_18B20_DEBUGGING
+ printf(" %02x", addr[i]);
+#endif
+ }
- // Check CRC - only include if CRC is valid
- if (_oneWire.CRC(addr, ONEWIRE_ADDR_BYTES-1) == addr[ONEWIRE_ADDR_BYTES-1])
- _numValidAddresses++;
+ // Check CRC - only include if CRC is valid
+ if (_oneWire.CRC(addr, ONEWIRE_ADDR_BYTES-1) == addr[ONEWIRE_ADDR_BYTES-1])
+ validAddresses++;
#ifdef SHOW_18B20_DEBUGGING
- else
- printf(" (CRC INVALID!)");
+ else
+ printf(" (CRC INVALID!)");
#endif
#ifdef SHOW_18B20_DEBUGGING
- // the first ROM byte indicates which chip
- switch (addr[0])
- {
- case 0x10:
- printf(" Chip = DS18S20\r\n"); // or old DS1820
- break;
- case 0x28:
- printf(" Chip = DS18B20\r\n");
- break;
- case 0x22:
- printf(" Chip = DS1822\r\n");
- break;
- default:
- printf(" NOT DS18x20 FAMILY\r\n");
- break;
- }
+ // the first ROM byte indicates which chip
+ switch (addr[0])
+ {
+ case 0x10:
+ printf(" Chip = DS18S20\r\n"); // or old DS1820
+ break;
+ case 0x28:
+ printf(" Chip = DS18B20\r\n");
+ break;
+ case 0x22:
+ printf(" Chip = DS1822\r\n");
+ break;
+ default:
+ printf(" NOT DS18x20 FAMILY\r\n");
+ break;
+ }
#endif
+ }
}
- return _numValidAddresses;
+ return validAddresses;
}
--- a/Thermometers.cpp Mon Sep 28 11:16:46 2015 +0000
+++ b/Thermometers.cpp Mon Oct 05 14:05:33 2015 +0000
@@ -4,6 +4,7 @@
#include "Thermometers.h"
#define SHOW_THERMOMETER_DEBUGGING 1
+const int DEBUG_EXPECTED_THERMOMETER_COUNT = 3;
Thermometers::Thermometers(int numTempSensorPins, const PinName tempSensorPins[], int serviceIntervalInMs)
{
@@ -47,7 +48,7 @@
{
DS18B20* pThermBus = _thermometerBuses[busIdx];
int numTherms = pThermBus->SearchToGetAddresses();
- if (numTherms != 3)
+ if (numTherms != DEBUG_EXPECTED_THERMOMETER_COUNT)
_failAddrCount++;
}
}
@@ -58,7 +59,7 @@
}
else
{
- // Check if time to request thermometer readings
+ // Check if time to request thermometers to take readings
if (_countForThermReadings == loopCountForRequestingThermReading)
{
#ifdef SHOW_THERMOMETER_DEBUGGING
@@ -75,7 +76,7 @@
}
}
- // Read thermometers
+ // Check if it is time to get the values from the thermometers
if (_countForThermReadings > numLoopsPerThermReading)
{
_countForThermReadings = 0;
--- a/Watchdog.h Mon Sep 28 11:16:46 2015 +0000
+++ b/Watchdog.h Mon Oct 05 14:05:33 2015 +0000
@@ -20,8 +20,10 @@
// by writing this required bit pattern
void Feed()
{
+ __disable_irq();
LPC_WDT->WDFEED = 0xAA;
LPC_WDT->WDFEED = 0x55;
+ __enable_irq();
}
bool WatchdogCausedRestart()
--- a/main.cpp Mon Sep 28 11:16:46 2015 +0000
+++ b/main.cpp Mon Oct 05 14:05:33 2015 +0000
@@ -1,3 +1,10 @@
+// Gas usage monitor
+// Counts pulses from a gas meter
+// Monitors temperature sensors
+// Monitors valve/pump activity
+// Web interface and UDP broadcast
+// Rob Dobson 2015
+
#include "mbed.h"
#include "EthernetInterface.h"
#include "NTPClient.h"
@@ -37,7 +44,8 @@
SDFileSystem sd(p5, p6, p7, p8, "sd");
// Log file names
-const char* gasPulseFileName = "/sd/curPulse.txt";
+const char* gasPulseFileName1 = "/sd/curPulse.txt";
+const char* gasPulseFileName2 = "/sd/curPulse2.txt";
const char* eventLogFileName = "/sd/log.txt";
const char* dataLogFileBase = "/sd/";
@@ -46,7 +54,7 @@
// Gas use counter
DigitalIn gasPulsePin(p21);
-GasUseCounter gasUseCounter(gasPulseFileName, gasPulsePin, pc);
+GasUseCounter gasUseCounter(gasPulseFileName1, gasPulseFileName2, gasPulsePin, pc);
// Thermometers - DS18B20 OneWire Thermometer connections
const PinName tempSensorPins[] = { p22 };
@@ -196,14 +204,15 @@
pc.printf("Trying to update time...\r\n");
if (ntp.setTime("0.pool.ntp.org") == NTP_OK)
{
- printf("Set time successfully\r\n");
- time_t ctTime;
- ctTime = time(NULL);
- printf("Time is set to (UTC): %s\r\n", ctime(&ctTime));
+ osDelay(1000); // This delay is simply to try to improve printf output
+ printf("Set time successfully\r\n");
+ time_t ctTime;
+ ctTime = time(NULL);
+ pc.printf("Time is set to (UTC): %s\r\n", ctime(&ctTime));
}
else
{
- printf("Cannot set from NTP\r\n");
+ pc.printf("Cannot set from NTP\r\n");
}
// Refresh time every K hours
@@ -231,7 +240,7 @@
int main()
{
pc.baud(115200);
- pc.printf("Gas Monitor V2 - Rob Dobson 2014\r\n");
+ pc.printf("\r\n\r\nGas Monitor V2 - Rob Dobson 2014\r\n");
// Initialise thermometers
thermometers.Init();
@@ -239,7 +248,6 @@
// Get the current count from the SD Card
gasUseCounter.Init();
-
// Setup ethernet interface
char macAddr[6];
mbed_mac_address(macAddr);
@@ -283,9 +291,15 @@
{
// Record the reason for restarting in the log file
if (watchdogCausedRestart)
+ {
logger.LogEvent("Watchdog Restart");
+ pc.printf("Watchdog Restart\r\n");
+ }
else
+ {
logger.LogEvent("Normal Restart");
+ pc.printf("Normal Restart\r\n");
+ }
restartCauseRecorded = true;
}
}