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-02-22
Revision:
9:0e103c2f869a
Parent:
8:5980547ae71c
Child:
10:72eb217def1f

File content as of revision 9:0e103c2f869a:

// 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
    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;
    _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];
}

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 < ONEWIRE_ADDR_BYTES; 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
    }  
}