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:
9:0e103c2f869a
Parent:
8:5980547ae71c
Child:
16:89778849e9f7
--- a/Thermometers.cpp	Sat Feb 21 19:00:08 2015 +0000
+++ b/Thermometers.cpp	Sun Feb 22 11:57:12 2015 +0000
@@ -0,0 +1,127 @@
+// Handles temperature collection from a number of DS18B20 devices
+// Rob Dobson, 2015
+
+#include "Thermometers.h"
+
+// #define SHOW_THERMOMETER_DEBUGGING 1
+
+Thermometers::Thermometers(int numTempSensorPins, const PinName tempSensorPins[], int serviceIntervalInMs)
+{
+    _numTempSensorPins = numTempSensorPins;
+    _tempSensorPins = tempSensorPins;
+    _serviceIntervalInMs = serviceIntervalInMs;
+    _numThermometerBuses = 0;
+}
+
+void Thermometers::Init()
+{
+    // Setup the thermometers
+    for (int busIdx = 0; busIdx < _numTempSensorPins; busIdx++)
+    {
+        if (busIdx >= MAX_ONEWIRE_BUSES)
+            break;
+        _thermometerBuses[busIdx] = new DS18B20(_tempSensorPins[busIdx]);
+        DS18B20* pThermBus = _thermometerBuses[busIdx];
+        pThermBus->SearchToGetAddresses();
+        pThermBus->ReqConvert();
+        _numThermometerBuses++;
+    }
+}
+
+void Thermometers::Service()
+{
+    int numLoopsPerThermReading = numSecondsBetweenThermReadings*1000/_serviceIntervalInMs;
+    int loopCountForRequestingThermReading = numLoopsPerThermReading - (timeForThermReadingInSecs*1000/_serviceIntervalInMs);
+
+    // Check if thermometer addresses need to be got
+    if (_countForThermReadings++ == 0)
+    {
+        if (_countForGetThermometerAddresses++ == 0)
+        {
+#ifdef SHOW_THERMOMETER_DEBUGGING
+            printf("Requested Addresses\r\n");
+#endif
+            for (int busIdx = 0; busIdx < _numThermometerBuses; busIdx++)
+            {
+                DS18B20* pThermBus = _thermometerBuses[busIdx];
+                pThermBus->SearchToGetAddresses();
+            }
+        }
+        else if (_countForGetThermometerAddresses > reGetThermometerAddressesAfterNumReadings)
+        {
+            _countForGetThermometerAddresses = 0;
+        }
+    }
+    else
+    {
+        // Check if time to request thermometer readings
+        if (_countForThermReadings == loopCountForRequestingThermReading)
+        {
+#ifdef SHOW_THERMOMETER_DEBUGGING
+            printf("Requested Conversion\r\n");
+#endif
+            for (int busIdx = 0; busIdx < _numThermometerBuses; busIdx++)
+            {
+                DS18B20* pThermBus = _thermometerBuses[busIdx];
+#ifdef SHOW_THERMOMETER_DEBUGGING
+                printf("Bus %d Num therms %d\r\n", busIdx, pThermBus->GetNumAddresses());
+#endif
+                pThermBus->ReqConvert();
+            }                
+        }
+    
+        // Read thermometers
+        if (_countForThermReadings > numLoopsPerThermReading)
+        {
+            _countForThermReadings = 0;
+#ifdef SHOW_THERMOMETER_DEBUGGING
+            printf("Reading Temp\r\n");
+#endif
+            for (int busIdx = 0; busIdx < _numThermometerBuses; busIdx++)
+            {
+                DS18B20* pThermBus = _thermometerBuses[busIdx];
+                for (int addrIdx = 0; addrIdx < pThermBus->GetNumAddresses(); addrIdx++)
+                {
+                    double tempValue = pThermBus->ReadTemperature(addrIdx);
+#ifdef SHOW_THERMOMETER_DEBUGGING                    
+                    printf("Bus %d Therm %d === %.2fC ... Addr = ", busIdx, addrIdx, tempValue);
+                    pThermBus->DebugPrintAddress(addrIdx);
+                    printf("\r\n");
+#endif
+                }
+            }                
+        }
+    }
+}
+
+int Thermometers::GetTemperatureValues(int maxTempValues, TemperatureValue* tempValues, int maxAgeInSecs)
+{
+    // Go through available values
+    int curTempValueIdx = 0;
+    for (int busIdx = 0; busIdx < _numThermometerBuses; busIdx++)
+    {
+        DS18B20* pThermBus = _thermometerBuses[busIdx];
+        for (int addrIdx = 0; addrIdx < pThermBus->GetNumAddresses(); addrIdx++)
+        {
+            time_t timeOfReading = 0;
+            double tempValue = pThermBus->GetLatestTemperature(addrIdx, timeOfReading);
+            if (tempValue != DS18B20::INVALID_TEMPERATURE)
+            {
+                if ((time(NULL) - timeOfReading) < maxAgeInSecs)
+                {
+                    tempValues[curTempValueIdx].timeStamp = timeOfReading;
+                    strncpy(tempValues[curTempValueIdx].address, pThermBus->GetAddressStr(addrIdx), DS18B20::ONEWIRE_ADDR_STRLEN-1);
+                    tempValues[curTempValueIdx].tempInCentigrade = tempValue;
+                    curTempValueIdx++;
+                    if (curTempValueIdx >= maxTempValues)
+                        break;
+                }
+            }
+        }
+        if (curTempValueIdx >= maxTempValues)
+            break;
+    }
+    return curTempValueIdx;
+}
+
+    
\ No newline at end of file