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 8:5980547ae71c, committed 2015-02-21
- 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
--- /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");
+ }
+ }
+ }
+ }
}
}