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

Files at this revision

API Documentation at this revision

Comitter:
Bobty
Date:
Sat Feb 21 19:00:08 2015 +0000
Parent:
7:113c68639d10
Child:
9:0e103c2f869a
Commit message:
Working with thermometer test code

Changed in this revision

Onewire.lib Show annotated file Show diff for this revision Revisions of this file
RdDS18B20.cpp Show annotated file Show diff for this revision Revisions of this file
RdDS18B20.h Show annotated file Show diff for this revision Revisions of this file
Thermometers.cpp Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Onewire.lib	Sat Feb 21 19:00:08 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/simonbarker/code/Onewire/#b678c7c8203c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RdDS18B20.cpp	Sat Feb 21 19:00:08 2015 +0000
@@ -0,0 +1,143 @@
+// Handles OneWire temperature sensors DB18S20
+// Can handle multiple devices per pin
+// Rob Dobson, 2015
+
+#include "RdDS18B20.h"
+
+// #define SHOW_18B20_DEBUGGING 1
+
+// Construct onewire bus with desired pin
+DS18B20::DS18B20(PinName mbedPin) : _oneWire(mbedPin)
+{
+    _numValidAddresses = 0;
+}
+
+// Request conversion
+void DS18B20::ReqConvert()
+{
+    // Request conversion begins
+    _oneWire.init();
+    _oneWire.writeByte(0xCC);
+    _oneWire.writeByte(0x44);
+}
+
+// Get temperature
+double DS18B20::GetTemperature(int addrIdx)
+{
+    // Check valid address
+    if ((addrIdx >= _numValidAddresses) || (addrIdx < 0))
+        return -1000.0;
+    
+    // Init the bus and req reading
+    _oneWire.init();
+    _oneWire.writeByte(0x55);
+    
+    // Send the address
+    for (int i = 0; i < 8; i++)
+        _oneWire.writeByte(_addrTable[addrIdx][i]);
+    _oneWire.writeByte(0xBE);
+
+    // Temperature val
+    int temperatureVals[] = {0,0};
+
+    // Read values back
+    for (int i = 0; i < sizeof(temperatureVals)/sizeof(int); i++)
+    {
+        temperatureVals[i] = _oneWire.readByte();
+    }
+    _oneWire.init();
+    
+    // Convert temperature
+    double temperature = ((temperatureVals[1] * 256) + temperatureVals[0])*0.0625;
+    return temperature; 
+}
+
+// Get address for a device
+uint8_t* DS18B20::GetAddress(int addrIdx)
+{
+    if ((addrIdx >= _numValidAddresses) || (addrIdx < 0))
+        return _addrTable[0];
+    return _addrTable[addrIdx];
+}
+
+// Get address as a string
+char* DS18B20::GetAddressStr(int addrIdx)
+{
+    if ((addrIdx >= _numValidAddresses) || (addrIdx < 0))
+        return "";
+    sprintf(_addrStr, "%02x %02x %02x %02x %02x %02x %02x %02x", 
+        _addrTable[addrIdx][0], _addrTable[addrIdx][1], _addrTable[addrIdx][2], 
+        _addrTable[addrIdx][3], _addrTable[addrIdx][4], _addrTable[addrIdx][5], 
+        _addrTable[addrIdx][6], _addrTable[addrIdx][7]);
+    return _addrStr;
+}
+    
+// Debug print address
+void DS18B20::DebugPrintAddress(int addrIdx)
+{
+    // Check valid address
+    if ((addrIdx >= _numValidAddresses) || (addrIdx < 0))
+    {
+        printf("Invalid addrIdx %d", addrIdx);
+        return;
+    }
+    // Write out address
+    printf(GetAddressStr(addrIdx));
+}
+
+void DS18B20::SearchToGetAddresses()
+{
+    _numValidAddresses = 0;
+    for (int addrIdx = 0; addrIdx < MAX_BUS_DEVICES; addrIdx++)
+    {
+        uint8_t addr[8];
+
+        if ( !_oneWire.search(addr))
+        {
+#ifdef SHOW_18B20_DEBUGGING
+            printf("No more addresses.\r\n");
+#endif
+            _oneWire.reset_search();
+            break;
+        }
+        
+#ifdef SHOW_18B20_DEBUGGING
+        printf("Found device addr (ROM) =");
+#endif
+        for( int i = 0; i < 8; i++) 
+        {
+            // Copy to table
+            _addrTable[_numValidAddresses][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++;
+#ifdef SHOW_18B20_DEBUGGING
+        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;
+        } 
+#endif
+    }  
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RdDS18B20.h	Sat Feb 21 19:00:08 2015 +0000
@@ -0,0 +1,35 @@
+// Handles OneWire temperature sensors DB18S20
+// Can handle multiple devices per pin
+// Rob Dobson, 2015
+
+#ifndef RdDS18B20__H
+#define RdDS18B20__H
+
+#include "mbed.h"
+#include "Onewire.h"
+
+#define MAX_BUS_DEVICES 8
+
+class DS18B20
+{
+public:
+    DS18B20(PinName mbedPin);
+    void ReqConvert();
+    double GetTemperature(int addrIdx);
+    void DebugPrintAddress(int addrIdx);
+    void SearchToGetAddresses();
+    int GetNumAddresses()
+    {
+        return _numValidAddresses;
+    }
+    uint8_t* GetAddress(int addrIdx);
+    char* GetAddressStr(int addrIdx);
+    
+private:
+    int _numValidAddresses;
+    uint8_t _addrTable[MAX_BUS_DEVICES][ONEWIRE_ADDR_BYTES];
+    Onewire _oneWire;
+    char _addrStr[3 * ONEWIRE_ADDR_BYTES + 1];
+};
+
+#endif
\ No newline at end of file
--- a/main.cpp	Fri Feb 20 22:53:28 2015 +0000
+++ b/main.cpp	Sat Feb 21 19:00:08 2015 +0000
@@ -3,10 +3,9 @@
 #include "NTPClient.h"
 #include "RdWebServer.h"
 #include "GasUseCounter.h"
+#include "RdDS18B20.h"
 #include <stdarg.h>
 
-//#define TEST_REMOVE_UDP_AND_NTP 1
-
 // Web and UDB ports 
 const int WEBPORT = 80; // Port for web server
 const int BROADCAST_PORT = 42853; // Arbitrarily chosen port number
@@ -37,6 +36,11 @@
 const char* logFilename = "/sd/log.txt";
 GasUseCounter gasUseCounter(gasPulseFileName, gasPulsePin, pc);
 
+// Thermometers - DS18B20 OneWire Thermometer connections
+const PinName tempSensorPins[] = { p22 };
+const int NUM_THERM_BUSES = sizeof(tempSensorPins)/sizeof(int);
+DS18B20* thermometerBuses[NUM_THERM_BUSES];
+
 void LogData(const char* format, ...)
 {
     FILE* fp = fopen(logFilename, "a");
@@ -156,9 +160,7 @@
             }
             pc.printf("Waited %d mins\r\n", i);
         }
-#ifndef TEST_REMOVE_UDP_AND_NTP
         break;
-#endif                
     }
 }
     
@@ -169,6 +171,18 @@
 
 //    ticker.attach(&TickFunction,TICK_MS / 1000.0);
 
+    // Setup the thermometers
+    for (int thermIdx = 0; thermIdx < NUM_THERM_BUSES; thermIdx++)
+        thermometerBuses[thermIdx] = new DS18B20(tempSensorPins[thermIdx]);
+        
+    // Initialise thermometers   
+    for (int thermIdx = 0; thermIdx < NUM_THERM_BUSES; thermIdx++)
+    {
+        DS18B20* pThermBus = thermometerBuses[thermIdx];
+        pThermBus->SearchToGetAddresses();
+        pThermBus->ReqConvert();
+    }
+
     // Get the current count from the SD Card
     gasUseCounter.Init();
     
@@ -177,22 +191,77 @@
     eth.connect();
     
     pc.printf("IP Address is %s\n\r", eth.getIPAddress());
-
-#ifndef TEST_REMOVE_UDP_AND_NTP
+    
+    // NTP Time setter
     Thread ntpTimeSetter(&ntp_thread);
-#endif
     
+    // Web Server
     Thread httpServer(&http_thread, NULL, osPriorityNormal, (DEFAULT_STACK_SIZE * 3));
     
+    const int loopDelayInMs = 250;
+    const int numSecondsBetweenThermReadings = 10;
+    const int numLoopsPerThermReading = numSecondsBetweenThermReadings*1000/loopDelayInMs;
+    const int timeForThermReadingInSecs = 2;
+    const int loopCountForRequestingThermReading = numLoopsPerThermReading - (timeForThermReadingInSecs*1000/loopDelayInMs);
+    int countForThermReadings = 0;
+    const int reGetThermometerAddressesAfterNumReadings = 100;
+    int countForGetThermometerAddresses = 0;
     while(true)
     {
-        osDelay(250);
+        osDelay(loopDelayInMs);
         led1 = !led1;
 
         // Service gas count
-#ifndef TEST_REMOVE_UDP_AND_NTP
         if (gasUseCounter.Service())
             SendInfoBroadcast();
-#endif
+        
+        // Check if thermometer addresses need to be got
+        if (countForThermReadings++ == 0)
+        {
+            if (countForGetThermometerAddresses++ == 0)
+            {
+                printf("Requested Addresses\n\r");
+                for (int thermIdx = 0; thermIdx < NUM_THERM_BUSES; thermIdx++)
+                {
+                    DS18B20* pThermBus = thermometerBuses[thermIdx];
+                    pThermBus->SearchToGetAddresses();
+                }
+            }
+            else if (countForGetThermometerAddresses > reGetThermometerAddressesAfterNumReadings)
+            {
+                countForGetThermometerAddresses = 0;
+            }
+        }
+        else
+        {
+            // Check if time to request thermometer readings
+            if (countForThermReadings == loopCountForRequestingThermReading)
+            {
+                printf("Requested Convert\n\r");
+                for (int thermIdx = 0; thermIdx < NUM_THERM_BUSES; thermIdx++)
+                {
+                    DS18B20* pThermBus = thermometerBuses[thermIdx];
+                    printf("Bus %d Num therms %d\n\r", thermIdx, pThermBus->GetNumAddresses());
+                    pThermBus->ReqConvert();
+                }                
+            }
+        
+            // Read thermometers
+            if (countForThermReadings > numLoopsPerThermReading)
+            {
+                countForThermReadings = 0;
+                printf("Reading Temp\n\r");
+                for (int thermIdx = 0; thermIdx < NUM_THERM_BUSES; thermIdx++)
+                {
+                    DS18B20* pThermBus = thermometerBuses[thermIdx];
+                    for (int addrIdx = 0; addrIdx < pThermBus->GetNumAddresses(); addrIdx++)
+                    {
+                        printf("Bus %d Therm %d === %.2fC ... Addr = ", thermIdx, addrIdx, pThermBus->GetTemperature(addrIdx));
+                        pThermBus->DebugPrintAddress(addrIdx);
+                        printf("\r\n");
+                    }
+                }                
+            }
+        }
     }
 }