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
- Committer:
- Bobty
- Date:
- 2015-10-05
- Revision:
- 19:0367cb46d003
- Parent:
- 16:89778849e9f7
- Child:
- 20:7933076df5af
File content as of revision 19:0367cb46d003:
// 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; for (int i = 0; i < MAX_BUS_DEVICES; i++) { _temperatureTable[i] = INVALID_TEMPERATURE; _timeOfReadingTable[i] = 0; } } // Request conversion void DS18B20::ReqConvert() { // Request conversion begins _oneWire.init(); _oneWire.writeByte(0xCC); _oneWire.writeByte(0x44); } // Get temperature double DS18B20::ReadTemperature(int addrIdx) { // Check valid address if ((addrIdx >= _numValidAddresses) || (addrIdx < 0)) return INVALID_TEMPERATURE; // 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 unsigned char temperatureVals[9]; // Read values back for (int i = 0; i < sizeof(temperatureVals)/sizeof(int); i++) { temperatureVals[i] = _oneWire.readByte(); } _oneWire.init(); // Check the CRC if (_oneWire.CRC(temperatureVals, sizeof(temperatureVals)/sizeof(int)-1) == temperatureVals[sizeof(temperatureVals)/sizeof(int)-1]) { #ifdef SHOW_18B20_DEBUGGING printf("Temp CRC Fail\r\n"); #endif return INVALID_TEMPERATURE; } else { #ifdef SHOW_18B20_DEBUGGING double temperature = ((((int)(temperatureVals[1])) * 256) + temperatureVals[0])*0.0625; printf("Temp = %0.1f", temperature); #endif } // Convert temperature double temperature = ((((int)(temperatureVals[1])) * 256) + temperatureVals[0])*0.0625; // Do a bounds check if ((temperature < -10) || (temperature > 100)) { #ifdef SHOW_18B20_DEBUGGING printf("Temp out of bounds\r\n"); #endif return INVALID_TEMPERATURE; } _temperatureTable[addrIdx] = temperature; _timeOfReadingTable[addrIdx] = time(NULL); return temperature; } // Get address for a device uint8_t* DS18B20::GetAddress(int addrIdx, uint8_t* addrBufPtr) { if ((addrIdx >= _numValidAddresses) || (addrIdx < 0)) return _addrTable[0]; // Make a copy if non-null pointer passed in if (addrBufPtr != NULL) { for( int i = 0; i < ONEWIRE_ADDR_BYTES; i++) addrBufPtr[i] = _addrTable[addrIdx][i]; } 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)); } double DS18B20::GetLatestTemperature(int addrIdx, time_t& timeOfReading) { if ((addrIdx >= _numValidAddresses) || (addrIdx < 0)) return INVALID_TEMPERATURE; timeOfReading = _timeOfReadingTable[addrIdx]; return _temperatureTable[addrIdx]; } int DS18B20::SearchToGetAddresses() { const int MAX_ADDR_SEARCH_RETRIES = 5; // Address Table uint8_t tmpAddrTable[MAX_BUS_DEVICES][ONEWIRE_ADDR_BYTES]; int validAddresses = 0; bool okResultAchieved = false; // Try a number of times for (int retryCount = 0; retryCount < MAX_ADDR_SEARCH_RETRIES; retryCount++) { // Check if the last search was ok (if there was one) if (okResultAchieved) { // Copy found addresses for (int addrIdx = 0; addrIdx < validAddresses; addrIdx++) { for( int i = 0; i < ONEWIRE_ADDR_BYTES; i++) _addrTable[addrIdx][i] = tmpAddrTable[addrIdx][i]; } _numValidAddresses = validAddresses; break; } // Start another search validAddresses = 0; _oneWire.reset_search(); for (int addrIdx = 0; addrIdx < MAX_BUS_DEVICES; addrIdx++) { uint8_t addr[8]; uint8_t rslt = _oneWire.search(addr); if (rslt == ONEWIRE_SEARCH_ALL_DONE) { if (validAddresses >= _numValidAddresses) okResultAchieved = true; break; } if (rslt != ONEWIRE_OK) { #ifdef SHOW_18B20_DEBUGGING printf("Search returned %s\r\n", (rslt == ONEWIRE_SEARCH_INIT_FAIL) ? "InitFail" : ((rslt == ONEWIRE_SEARCH_NOT_FOUND) ? "NotFound" : "UnknownError")); #endif break; } #ifdef SHOW_18B20_DEBUGGING printf("Found device addr (ROM) ="); #endif for( int i = 0; i < ONEWIRE_ADDR_BYTES; i++) { // Copy to table tmpAddrTable[validAddresses][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]) validAddresses++; #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 } } return validAddresses; }