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

Committer:
Bobty
Date:
2015-02-22
Revision:
9:0e103c2f869a
Parent:
8:5980547ae71c
Child:
16:89778849e9f7

File content as of revision 9:0e103c2f869a:

// Handles temperature collection from a number of DS18B20 devices
// Rob Dobson, 2015

#include "Thermometers.h"

// #define SHOW_THERMOMETER_DEBUGGING 1

Thermometers::Thermometers(int numTempSensorPins, const PinName tempSensorPins[], int serviceIntervalInMs)
{
    _numTempSensorPins = numTempSensorPins;
    _tempSensorPins = tempSensorPins;
    _serviceIntervalInMs = serviceIntervalInMs;
    _numThermometerBuses = 0;
}

void Thermometers::Init()
{
    // Setup the thermometers
    for (int busIdx = 0; busIdx < _numTempSensorPins; busIdx++)
    {
        if (busIdx >= MAX_ONEWIRE_BUSES)
            break;
        _thermometerBuses[busIdx] = new DS18B20(_tempSensorPins[busIdx]);
        DS18B20* pThermBus = _thermometerBuses[busIdx];
        pThermBus->SearchToGetAddresses();
        pThermBus->ReqConvert();
        _numThermometerBuses++;
    }
}

void Thermometers::Service()
{
    int numLoopsPerThermReading = numSecondsBetweenThermReadings*1000/_serviceIntervalInMs;
    int loopCountForRequestingThermReading = numLoopsPerThermReading - (timeForThermReadingInSecs*1000/_serviceIntervalInMs);

    // Check if thermometer addresses need to be got
    if (_countForThermReadings++ == 0)
    {
        if (_countForGetThermometerAddresses++ == 0)
        {
#ifdef SHOW_THERMOMETER_DEBUGGING
            printf("Requested Addresses\r\n");
#endif
            for (int busIdx = 0; busIdx < _numThermometerBuses; busIdx++)
            {
                DS18B20* pThermBus = _thermometerBuses[busIdx];
                pThermBus->SearchToGetAddresses();
            }
        }
        else if (_countForGetThermometerAddresses > reGetThermometerAddressesAfterNumReadings)
        {
            _countForGetThermometerAddresses = 0;
        }
    }
    else
    {
        // Check if time to request thermometer readings
        if (_countForThermReadings == loopCountForRequestingThermReading)
        {
#ifdef SHOW_THERMOMETER_DEBUGGING
            printf("Requested Conversion\r\n");
#endif
            for (int busIdx = 0; busIdx < _numThermometerBuses; busIdx++)
            {
                DS18B20* pThermBus = _thermometerBuses[busIdx];
#ifdef SHOW_THERMOMETER_DEBUGGING
                printf("Bus %d Num therms %d\r\n", busIdx, pThermBus->GetNumAddresses());
#endif
                pThermBus->ReqConvert();
            }                
        }
    
        // Read thermometers
        if (_countForThermReadings > numLoopsPerThermReading)
        {
            _countForThermReadings = 0;
#ifdef SHOW_THERMOMETER_DEBUGGING
            printf("Reading Temp\r\n");
#endif
            for (int busIdx = 0; busIdx < _numThermometerBuses; busIdx++)
            {
                DS18B20* pThermBus = _thermometerBuses[busIdx];
                for (int addrIdx = 0; addrIdx < pThermBus->GetNumAddresses(); addrIdx++)
                {
                    double tempValue = pThermBus->ReadTemperature(addrIdx);
#ifdef SHOW_THERMOMETER_DEBUGGING                    
                    printf("Bus %d Therm %d === %.2fC ... Addr = ", busIdx, addrIdx, tempValue);
                    pThermBus->DebugPrintAddress(addrIdx);
                    printf("\r\n");
#endif
                }
            }                
        }
    }
}

int Thermometers::GetTemperatureValues(int maxTempValues, TemperatureValue* tempValues, int maxAgeInSecs)
{
    // Go through available values
    int curTempValueIdx = 0;
    for (int busIdx = 0; busIdx < _numThermometerBuses; busIdx++)
    {
        DS18B20* pThermBus = _thermometerBuses[busIdx];
        for (int addrIdx = 0; addrIdx < pThermBus->GetNumAddresses(); addrIdx++)
        {
            time_t timeOfReading = 0;
            double tempValue = pThermBus->GetLatestTemperature(addrIdx, timeOfReading);
            if (tempValue != DS18B20::INVALID_TEMPERATURE)
            {
                if ((time(NULL) - timeOfReading) < maxAgeInSecs)
                {
                    tempValues[curTempValueIdx].timeStamp = timeOfReading;
                    strncpy(tempValues[curTempValueIdx].address, pThermBus->GetAddressStr(addrIdx), DS18B20::ONEWIRE_ADDR_STRLEN-1);
                    tempValues[curTempValueIdx].tempInCentigrade = tempValue;
                    curTempValueIdx++;
                    if (curTempValueIdx >= maxTempValues)
                        break;
                }
            }
        }
        if (curTempValueIdx >= maxTempValues)
            break;
    }
    return curTempValueIdx;
}