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
RdDS18B20.cpp
00001 // Handles OneWire temperature sensors DB18S20 00002 // Can handle multiple devices per pin 00003 // Rob Dobson, 2015 00004 00005 #include "RdDS18B20.h" 00006 00007 // #define SHOW_18B20_DEBUGGING 1 00008 00009 // Construct onewire bus with desired pin 00010 DS18B20::DS18B20(PinName mbedPin, Logger &logger) : _oneWire(mbedPin), _logger(logger) 00011 { 00012 _numValidAddresses = 0; 00013 for (int i = 0; i < MAX_BUS_DEVICES; i++) 00014 { 00015 _temperatureTable[i] = INVALID_TEMPERATURE; 00016 _timeOfReadingTable[i] = 0; 00017 } 00018 } 00019 00020 // Request conversion 00021 void DS18B20::ReqConvert() 00022 { 00023 // Request conversion begins 00024 _oneWire.init(); 00025 _oneWire.writeByte(0xCC); 00026 _oneWire.writeByte(0x44); 00027 } 00028 00029 // Get temperature 00030 double DS18B20::ReadTemperature(int addrIdx) 00031 { 00032 // Check valid address 00033 if ((addrIdx >= _numValidAddresses) || (addrIdx < 0)) 00034 return INVALID_TEMPERATURE; 00035 00036 // Init the bus and req reading 00037 _oneWire.init(); 00038 _oneWire.writeByte(0x55); 00039 00040 // Send the address 00041 for (int i = 0; i < 8; i++) 00042 _oneWire.writeByte(_addrTable[addrIdx][i]); 00043 _oneWire.writeByte(0xBE); 00044 00045 // Temperature val 00046 unsigned char temperatureVals[9]; 00047 00048 // Read values back 00049 for (int i = 0; i < sizeof(temperatureVals)/sizeof(int); i++) 00050 { 00051 temperatureVals[i] = _oneWire.readByte(); 00052 } 00053 _oneWire.init(); 00054 00055 // Check the CRC 00056 if (_oneWire.CRC(temperatureVals, sizeof(temperatureVals)/sizeof(int)-1) == temperatureVals[sizeof(temperatureVals)/sizeof(int)-1]) 00057 { 00058 #ifdef SHOW_18B20_DEBUGGING 00059 _logger.LogDebug("Temp CRC Fail addr %d", addrIdx); 00060 #endif 00061 return INVALID_TEMPERATURE; 00062 } 00063 else 00064 { 00065 #ifdef SHOW_18B20_DEBUGGING 00066 double temperature = ((((int)(temperatureVals[1])) * 256) + temperatureVals[0])*0.0625; 00067 _logger.LogDebug("Temp = %0.1f", temperature); 00068 #endif 00069 } 00070 00071 // Convert temperature 00072 double temperature = ((((int)(temperatureVals[1])) * 256) + temperatureVals[0])*0.0625; 00073 00074 // Do a bounds check 00075 if ((temperature < -10) || (temperature > 100)) 00076 { 00077 #ifdef SHOW_18B20_DEBUGGING 00078 _logger.LogDebug("Temp out of bounds"); 00079 #endif 00080 return INVALID_TEMPERATURE; 00081 } 00082 _temperatureTable[addrIdx] = temperature; 00083 _timeOfReadingTable[addrIdx] = time(NULL); 00084 return temperature; 00085 } 00086 00087 // Get address for a device 00088 uint8_t* DS18B20::GetAddress(int addrIdx, uint8_t* addrBufPtr) 00089 { 00090 if ((addrIdx >= _numValidAddresses) || (addrIdx < 0)) 00091 return _addrTable[0]; 00092 // Make a copy if non-null pointer passed in 00093 if (addrBufPtr != NULL) 00094 { 00095 for( int i = 0; i < ONEWIRE_ADDR_BYTES; i++) 00096 addrBufPtr[i] = _addrTable[addrIdx][i]; 00097 } 00098 return _addrTable[addrIdx]; 00099 } 00100 00101 // Get address as a string 00102 char* DS18B20::GetAddressStr(int addrIdx) 00103 { 00104 if ((addrIdx >= _numValidAddresses) || (addrIdx < 0)) 00105 return ""; 00106 sprintf(_addrStr, "%02x%02x%02x%02x%02x%02x%02x%02x", 00107 _addrTable[addrIdx][0], _addrTable[addrIdx][1], _addrTable[addrIdx][2], 00108 _addrTable[addrIdx][3], _addrTable[addrIdx][4], _addrTable[addrIdx][5], 00109 _addrTable[addrIdx][6], _addrTable[addrIdx][7]); 00110 return _addrStr; 00111 } 00112 00113 // Debug print address 00114 void DS18B20::DebugGetAddress(int addrIdx, char* buf) 00115 { 00116 // Check valid address 00117 if ((addrIdx >= _numValidAddresses) || (addrIdx < 0)) 00118 { 00119 sprintf(buf, "Invalid addrIdx %d", addrIdx); 00120 return; 00121 } 00122 // Write out address 00123 strcpy(buf, GetAddressStr(addrIdx)); 00124 } 00125 00126 double DS18B20::GetLatestTemperature(int addrIdx, time_t& timeOfReading) 00127 { 00128 if ((addrIdx >= _numValidAddresses) || (addrIdx < 0)) 00129 return INVALID_TEMPERATURE; 00130 timeOfReading = _timeOfReadingTable[addrIdx]; 00131 return _temperatureTable[addrIdx]; 00132 } 00133 00134 int DS18B20::SearchToGetAddresses() 00135 { 00136 const int MAX_ADDR_SEARCH_RETRIES = 5; 00137 00138 // Address Table 00139 uint8_t tmpAddrTable[MAX_BUS_DEVICES][ONEWIRE_ADDR_BYTES]; 00140 int validAddresses = 0; 00141 bool okResultAchieved = false; 00142 00143 // Try a number of times 00144 for (int retryCount = 0; retryCount < MAX_ADDR_SEARCH_RETRIES; retryCount++) 00145 { 00146 // Check if the last search was ok (if there was one) 00147 if (okResultAchieved) 00148 { 00149 // Copy found addresses 00150 for (int addrIdx = 0; addrIdx < validAddresses; addrIdx++) 00151 { 00152 for( int i = 0; i < ONEWIRE_ADDR_BYTES; i++) 00153 _addrTable[addrIdx][i] = tmpAddrTable[addrIdx][i]; 00154 } 00155 _numValidAddresses = validAddresses; 00156 break; 00157 } 00158 00159 // Start another search 00160 validAddresses = 0; 00161 _oneWire.reset_search(); 00162 for (int addrIdx = 0; addrIdx < MAX_BUS_DEVICES; addrIdx++) 00163 { 00164 uint8_t addr[8]; 00165 uint8_t rslt = _oneWire.search(addr); 00166 if (rslt == ONEWIRE_SEARCH_ALL_DONE) 00167 { 00168 if (validAddresses >= _numValidAddresses) 00169 okResultAchieved = true; 00170 break; 00171 } 00172 if (rslt != ONEWIRE_OK) 00173 { 00174 #ifdef SHOW_18B20_DEBUGGING 00175 // _logger.LogDebug("Search returned %s", _oneWire.GetErrorStr(rslt)); 00176 _logger.LogDebug("Search returned %d", rslt); 00177 #endif 00178 break; 00179 } 00180 00181 for( int i = 0; i < ONEWIRE_ADDR_BYTES; i++) 00182 { 00183 // Copy to table 00184 tmpAddrTable[validAddresses][i] = addr[i]; 00185 } 00186 00187 // Check CRC - only include if CRC is valid 00188 bool addrValid = (_oneWire.CRC(addr, ONEWIRE_ADDR_BYTES-1) == addr[ONEWIRE_ADDR_BYTES-1]); 00189 if (addrValid) 00190 validAddresses++; 00191 00192 #ifdef SHOW_18B20_DEBUGGING 00193 _logger.LogDebug("Found addr (ROM) = %02x%02x%02x%02x%02x%02x%02x%02x %s %s", 00194 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], 00195 (addrValid ? "CRC OK" : "CRC INVALID"), 00196 GetChipId(addr[0])); 00197 #endif 00198 } 00199 00200 } 00201 return validAddresses; 00202 } 00203 00204 char* DS18B20::GetChipId(int val) 00205 { 00206 // the first ROM byte indicates which chip 00207 switch (val) 00208 { 00209 case 0x10: 00210 return("Chip = DS18S20"); // or old DS1820 00211 case 0x28: 00212 return("Chip = DS18B20"); 00213 case 0x22: 00214 return("Chip = DS1822"); 00215 } 00216 return("Chip NOT DS18x20 FAMILY"); 00217 }
Generated on Tue Jul 12 2022 18:43:11 by 1.7.2