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
Thermometers.cpp
- Committer:
- Bobty
- Date:
- 2015-10-16
- Revision:
- 22:14b4060dd027
- Parent:
- 21:ccf053bab795
File content as of revision 22:14b4060dd027:
// Handles temperature collection from a number of DS18B20 devices
// Rob Dobson, 2015
#include "Thermometers.h"
#define SHOW_THERMOMETER_DEBUGGING 1
const int DEBUG_EXPECTED_THERMOMETER_COUNT = 3;
Thermometers::Thermometers(int numTempSensorPins, const PinName tempSensorPins[], int serviceIntervalInMs, Logger &logger) :
_logger(logger)
{
_numTempSensorPins = numTempSensorPins;
_tempSensorPins = tempSensorPins;
_serviceIntervalInMs = serviceIntervalInMs;
_numThermometerBuses = 0;
_failAddrCount = 0;
_failReadCount = 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], _logger);
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
_logger.LogDebug("ThermReqAddr");
#endif
for (int busIdx = 0; busIdx < _numThermometerBuses; busIdx++)
{
DS18B20* pThermBus = _thermometerBuses[busIdx];
int numTherms = pThermBus->SearchToGetAddresses();
if (numTherms != DEBUG_EXPECTED_THERMOMETER_COUNT)
_failAddrCount++;
}
#ifdef SHOW_THERMOMETER_DEBUGGING
for (int busIdx = 0; busIdx < _numThermometerBuses; busIdx++)
{
DS18B20* pThermBus = _thermometerBuses[busIdx];
if(_failAddrCount == 0 && _failReadCount == 0)
{
_logger.LogDebug("Therm B%d N%d OK", busIdx, pThermBus->GetNumAddresses());
}
else
{
_logger.LogDebug("Therm B%d N%d FailAddr %d FailRead %d", busIdx, pThermBus->GetNumAddresses(),
_failAddrCount, _failReadCount);
}
for (int addrIdx = 0; addrIdx < pThermBus->GetNumAddresses(); addrIdx++)
{
char buf [40];
pThermBus->DebugGetAddress(addrIdx, buf);
_logger.LogDebug("Therm B%d N%d %s", busIdx, addrIdx, buf);
}
}
#endif
}
else if (_countForGetThermometerAddresses > reGetThermometerAddressesAfterNumReadings)
{
_countForGetThermometerAddresses = 0;
}
}
else
{
// Check if time to request thermometers to take readings
if (_countForThermReadings == loopCountForRequestingThermReading)
{
#ifdef SHOW_THERMOMETER_DEBUGGING
// _logger.LogDebug("ThermReqConv");
#endif
for (int busIdx = 0; busIdx < _numThermometerBuses; busIdx++)
{
DS18B20* pThermBus = _thermometerBuses[busIdx];
pThermBus->ReqConvert();
}
}
// Check if it is time to get the values from the thermometers
if (_countForThermReadings > numLoopsPerThermReading)
{
_countForThermReadings = 0;
for (int busIdx = 0; busIdx < _numThermometerBuses; busIdx++)
{
DS18B20* pThermBus = _thermometerBuses[busIdx];
for (int addrIdx = 0; addrIdx < pThermBus->GetNumAddresses(); addrIdx++)
{
double tempValue = pThermBus->ReadTemperature(addrIdx);
if (tempValue == DS18B20::INVALID_TEMPERATURE)
_failReadCount++;
}
}
#ifdef SHOW_THERMOMETER_DEBUGGING
char tempStrBuf[140];
tempStrBuf[0] = 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);
int ageInSecs = time(NULL) - timeOfReading;
if (tempValue == DS18B20::INVALID_TEMPERATURE)
sprintf(tempStrBuf+strlen(tempStrBuf), "%.1fC (INVALID) ", tempValue);
else if (ageInSecs <= 2)
sprintf(tempStrBuf+strlen(tempStrBuf), "%.1fC ", tempValue);
else
sprintf(tempStrBuf+strlen(tempStrBuf), "%.1fC (%dS ago) ", tempValue, ageInSecs);
}
}
_logger.LogDebug("Therm %s", tempStrBuf);
#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;
}