Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: EthernetInterfacePlusHostname NTPClient Onewire RdWebServer SDFileSystem-RTOS mbed-rtos mbed-src
RdDS18B20.cpp
- Committer:
- Bobty
- Date:
- 2015-10-16
- Revision:
- 22:14b4060dd027
- Parent:
- 21:ccf053bab795
File content as of revision 22:14b4060dd027:
// 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, Logger &logger) : _oneWire(mbedPin), _logger(logger)
{
_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
_logger.LogDebug("Temp CRC Fail addr %d", addrIdx);
#endif
return INVALID_TEMPERATURE;
}
else
{
#ifdef SHOW_18B20_DEBUGGING
double temperature = ((((int)(temperatureVals[1])) * 256) + temperatureVals[0])*0.0625;
_logger.LogDebug("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
_logger.LogDebug("Temp out of bounds");
#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::DebugGetAddress(int addrIdx, char* buf)
{
// Check valid address
if ((addrIdx >= _numValidAddresses) || (addrIdx < 0))
{
sprintf(buf, "Invalid addrIdx %d", addrIdx);
return;
}
// Write out address
strcpy(buf, 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
// _logger.LogDebug("Search returned %s", _oneWire.GetErrorStr(rslt));
_logger.LogDebug("Search returned %d", rslt);
#endif
break;
}
for( int i = 0; i < ONEWIRE_ADDR_BYTES; i++)
{
// Copy to table
tmpAddrTable[validAddresses][i] = addr[i];
}
// Check CRC - only include if CRC is valid
bool addrValid = (_oneWire.CRC(addr, ONEWIRE_ADDR_BYTES-1) == addr[ONEWIRE_ADDR_BYTES-1]);
if (addrValid)
validAddresses++;
#ifdef SHOW_18B20_DEBUGGING
_logger.LogDebug("Found addr (ROM) = %02x%02x%02x%02x%02x%02x%02x%02x %s %s",
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7],
(addrValid ? "CRC OK" : "CRC INVALID"),
GetChipId(addr[0]));
#endif
}
}
return validAddresses;
}
char* DS18B20::GetChipId(int val)
{
// the first ROM byte indicates which chip
switch (val)
{
case 0x10:
return("Chip = DS18S20"); // or old DS1820
case 0x28:
return("Chip = DS18B20");
case 0x22:
return("Chip = DS1822");
}
return("Chip NOT DS18x20 FAMILY");
}