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"); + } + } + } + } } }