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
Thermometers.cpp
00001 // Handles temperature collection from a number of DS18B20 devices 00002 // Rob Dobson, 2015 00003 00004 #include "Thermometers.h" 00005 00006 #define SHOW_THERMOMETER_DEBUGGING 1 00007 const int DEBUG_EXPECTED_THERMOMETER_COUNT = 3; 00008 00009 Thermometers::Thermometers(int numTempSensorPins, const PinName tempSensorPins[], int serviceIntervalInMs, Logger &logger) : 00010 _logger(logger) 00011 { 00012 _numTempSensorPins = numTempSensorPins; 00013 _tempSensorPins = tempSensorPins; 00014 _serviceIntervalInMs = serviceIntervalInMs; 00015 _numThermometerBuses = 0; 00016 _failAddrCount = 0; 00017 _failReadCount = 0; 00018 } 00019 00020 void Thermometers::Init() 00021 { 00022 // Setup the thermometers 00023 for (int busIdx = 0; busIdx < _numTempSensorPins; busIdx++) 00024 { 00025 if (busIdx >= MAX_ONEWIRE_BUSES) 00026 break; 00027 _thermometerBuses[busIdx] = new DS18B20(_tempSensorPins[busIdx], _logger); 00028 DS18B20* pThermBus = _thermometerBuses[busIdx]; 00029 pThermBus->SearchToGetAddresses(); 00030 pThermBus->ReqConvert(); 00031 _numThermometerBuses++; 00032 } 00033 } 00034 00035 void Thermometers::Service() 00036 { 00037 int numLoopsPerThermReading = numSecondsBetweenThermReadings*1000/_serviceIntervalInMs; 00038 int loopCountForRequestingThermReading = numLoopsPerThermReading - (timeForThermReadingInSecs*1000/_serviceIntervalInMs); 00039 00040 // Check if thermometer addresses need to be got 00041 if (_countForThermReadings++ == 0) 00042 { 00043 if (_countForGetThermometerAddresses++ == 0) 00044 { 00045 #ifdef SHOW_THERMOMETER_DEBUGGING 00046 _logger.LogDebug("ThermReqAddr"); 00047 #endif 00048 for (int busIdx = 0; busIdx < _numThermometerBuses; busIdx++) 00049 { 00050 DS18B20* pThermBus = _thermometerBuses[busIdx]; 00051 int numTherms = pThermBus->SearchToGetAddresses(); 00052 if (numTherms != DEBUG_EXPECTED_THERMOMETER_COUNT) 00053 _failAddrCount++; 00054 } 00055 00056 #ifdef SHOW_THERMOMETER_DEBUGGING 00057 for (int busIdx = 0; busIdx < _numThermometerBuses; busIdx++) 00058 { 00059 DS18B20* pThermBus = _thermometerBuses[busIdx]; 00060 if(_failAddrCount == 0 && _failReadCount == 0) 00061 { 00062 _logger.LogDebug("Therm B%d N%d OK", busIdx, pThermBus->GetNumAddresses()); 00063 } 00064 else 00065 { 00066 _logger.LogDebug("Therm B%d N%d FailAddr %d FailRead %d", busIdx, pThermBus->GetNumAddresses(), 00067 _failAddrCount, _failReadCount); 00068 } 00069 for (int addrIdx = 0; addrIdx < pThermBus->GetNumAddresses(); addrIdx++) 00070 { 00071 char buf [40]; 00072 pThermBus->DebugGetAddress(addrIdx, buf); 00073 _logger.LogDebug("Therm B%d N%d %s", busIdx, addrIdx, buf); 00074 } 00075 } 00076 #endif 00077 } 00078 else if (_countForGetThermometerAddresses > reGetThermometerAddressesAfterNumReadings) 00079 { 00080 _countForGetThermometerAddresses = 0; 00081 } 00082 } 00083 else 00084 { 00085 // Check if time to request thermometers to take readings 00086 if (_countForThermReadings == loopCountForRequestingThermReading) 00087 { 00088 #ifdef SHOW_THERMOMETER_DEBUGGING 00089 // _logger.LogDebug("ThermReqConv"); 00090 #endif 00091 for (int busIdx = 0; busIdx < _numThermometerBuses; busIdx++) 00092 { 00093 DS18B20* pThermBus = _thermometerBuses[busIdx]; 00094 pThermBus->ReqConvert(); 00095 } 00096 } 00097 00098 // Check if it is time to get the values from the thermometers 00099 if (_countForThermReadings > numLoopsPerThermReading) 00100 { 00101 _countForThermReadings = 0; 00102 for (int busIdx = 0; busIdx < _numThermometerBuses; busIdx++) 00103 { 00104 DS18B20* pThermBus = _thermometerBuses[busIdx]; 00105 for (int addrIdx = 0; addrIdx < pThermBus->GetNumAddresses(); addrIdx++) 00106 { 00107 double tempValue = pThermBus->ReadTemperature(addrIdx); 00108 if (tempValue == DS18B20::INVALID_TEMPERATURE) 00109 _failReadCount++; 00110 } 00111 } 00112 00113 #ifdef SHOW_THERMOMETER_DEBUGGING 00114 char tempStrBuf[140]; 00115 tempStrBuf[0] = 0; 00116 for (int busIdx = 0; busIdx < _numThermometerBuses; busIdx++) 00117 { 00118 DS18B20* pThermBus = _thermometerBuses[busIdx]; 00119 for (int addrIdx = 0; addrIdx < pThermBus->GetNumAddresses(); addrIdx++) 00120 { 00121 time_t timeOfReading = 0; 00122 double tempValue = pThermBus->GetLatestTemperature(addrIdx, timeOfReading); 00123 int ageInSecs = time(NULL) - timeOfReading; 00124 if (tempValue == DS18B20::INVALID_TEMPERATURE) 00125 sprintf(tempStrBuf+strlen(tempStrBuf), "%.1fC (INVALID) ", tempValue); 00126 else if (ageInSecs <= 2) 00127 sprintf(tempStrBuf+strlen(tempStrBuf), "%.1fC ", tempValue); 00128 else 00129 sprintf(tempStrBuf+strlen(tempStrBuf), "%.1fC (%dS ago) ", tempValue, ageInSecs); 00130 } 00131 } 00132 _logger.LogDebug("Therm %s", tempStrBuf); 00133 #endif 00134 00135 } 00136 } 00137 } 00138 00139 int Thermometers::GetTemperatureValues(int maxTempValues, TemperatureValue* tempValues, int maxAgeInSecs) 00140 { 00141 // Go through available values 00142 int curTempValueIdx = 0; 00143 for (int busIdx = 0; busIdx < _numThermometerBuses; busIdx++) 00144 { 00145 DS18B20* pThermBus = _thermometerBuses[busIdx]; 00146 for (int addrIdx = 0; addrIdx < pThermBus->GetNumAddresses(); addrIdx++) 00147 { 00148 time_t timeOfReading = 0; 00149 double tempValue = pThermBus->GetLatestTemperature(addrIdx, timeOfReading); 00150 if (tempValue != DS18B20::INVALID_TEMPERATURE) 00151 { 00152 if ((time(NULL) - timeOfReading) < maxAgeInSecs) 00153 { 00154 tempValues[curTempValueIdx].timeStamp = timeOfReading; 00155 strncpy(tempValues[curTempValueIdx].address, pThermBus->GetAddressStr(addrIdx), DS18B20::ONEWIRE_ADDR_STRLEN-1); 00156 tempValues[curTempValueIdx].tempInCentigrade = tempValue; 00157 curTempValueIdx++; 00158 if (curTempValueIdx >= maxTempValues) 00159 break; 00160 } 00161 } 00162 } 00163 if (curTempValueIdx >= maxTempValues) 00164 break; 00165 } 00166 return curTempValueIdx; 00167 } 00168 00169
Generated on Tue Jul 12 2022 18:43:11 by 1.7.2