mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
286 lines
5.7 KiB
C++
286 lines
5.7 KiB
C++
//
|
|
// FILE: DS1821.cpp
|
|
// AUTHOR: Rob Tillaart
|
|
// VERSION: 0.3.2
|
|
// DATE: 2014-10-05
|
|
// PURPOSE: Arduino library for DS1821 temperature sensor
|
|
// URL: https://github.com/RobTillaart/DS1821
|
|
//
|
|
// HISTORY:
|
|
// 0.0.1 2014-10-05 initial version
|
|
// 0.1.00 2015-05-14 added prescale support
|
|
// 0.2.0 2020-08-05 initial release; refactored ad fundum.
|
|
// 0.3.0 2020-08-07 add continuous mode, alarm level, polarity, thermostat etc
|
|
// 0.3.1 2020-12-20 arduino-CI + unit test (frame)
|
|
// 0.3.2 2021-05-27 arduio-lint fixes
|
|
|
|
|
|
#include "DS1821.h"
|
|
|
|
|
|
// CONFIG REGISTER MASKS... P7-8 datasheet
|
|
#define DS1821_CONF_1SHOT 0x01
|
|
#define DS1821_CONF_POL 0x02
|
|
#define DS1821_CONF_TR 0x04
|
|
#define DS1821_CONF_TLF 0x08
|
|
#define DS1821_CONF_THF 0x10
|
|
#define DS1821_CONF_NVB 0x20
|
|
// skip always one 0x40
|
|
#define DS1821_CONF_DONE 0x80
|
|
|
|
|
|
// COMMANDS P10-11 datasheet
|
|
#define START_CONVERT 0xEE
|
|
#define STOP_CONVERT 0x22
|
|
#define READ_CONFIG_REG 0xAC
|
|
#define WRITE_CONFIG_REG 0x0C
|
|
#define READ_TEMPERATURE 0xAA
|
|
#define READ_COUNTER 0xA0
|
|
#define LOAD_COUNTER 0x41
|
|
#define WRITE_TH 0x01
|
|
#define WRITE_TL 0x02
|
|
#define READ_TH 0xA1
|
|
#define READ_TL 0xA2
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// PUBLIC
|
|
//
|
|
DS1821::DS1821(OneWire *ow)
|
|
{
|
|
_ow = ow;
|
|
_err = DS1821_RESET_OK;
|
|
}
|
|
|
|
|
|
// P5 - Operation measuring temperature
|
|
int DS1821::requestTemperature()
|
|
{
|
|
if (_reset() != DS1821_RESET_OK) return DS1821_RESET_ERROR;
|
|
_command(START_CONVERT);
|
|
return DS1821_RESET_OK;
|
|
}
|
|
|
|
|
|
int DS1821::requestContinuous()
|
|
{
|
|
_clrConfigFlag(DS1821_CONF_1SHOT);
|
|
return requestTemperature();
|
|
}
|
|
|
|
|
|
int DS1821::stopContinuous()
|
|
{
|
|
if (_reset() != DS1821_RESET_OK) return DS1821_RESET_ERROR;
|
|
_command(STOP_CONVERT);
|
|
return DS1821_RESET_OK;
|
|
}
|
|
|
|
|
|
int DS1821::conversionReady()
|
|
{
|
|
return _getConfigFlag(DS1821_CONF_DONE);
|
|
}
|
|
|
|
|
|
// P5 - Operation measuring temperature
|
|
float DS1821::readTemperature()
|
|
{
|
|
if (_reset() != DS1821_RESET_OK) return DS1821_RESET_ERROR;
|
|
_command(READ_TEMPERATURE);
|
|
int temperature = _readByte();
|
|
|
|
// Handle negative values: >= 200 ==> subtract 256;
|
|
if (temperature >= 200) temperature -= 256;
|
|
|
|
if (_reset() != DS1821_RESET_OK) return DS1821_RESET_ERROR;
|
|
_command(READ_COUNTER);
|
|
int countRemain = _readByte() * 256;
|
|
countRemain += _readByte();
|
|
|
|
// Load counter to populate the slope accumulator into counter register
|
|
// Q: is this a fixed number? if so it could be hard coded...
|
|
if (_reset() != DS1821_RESET_OK) return DS1821_RESET_ERROR;
|
|
_command(LOAD_COUNTER);
|
|
|
|
if (_reset() != DS1821_RESET_OK) return DS1821_RESET_ERROR;
|
|
_command(READ_COUNTER);
|
|
|
|
int countPerC = _readByte() * 256;
|
|
countPerC += _readByte();
|
|
|
|
return temperature + 0.5 - (1.0 * countRemain) / countPerC;
|
|
}
|
|
|
|
|
|
int DS1821::setLow(int8_t lo)
|
|
{
|
|
if (_reset() != DS1821_RESET_OK) return DS1821_RESET_ERROR;
|
|
_command(WRITE_TL);
|
|
_command(lo);
|
|
return DS1821_RESET_OK;
|
|
}
|
|
|
|
|
|
int DS1821::getLow()
|
|
{
|
|
if (_reset() != DS1821_RESET_OK) return DS1821_RESET_ERROR;
|
|
_command(READ_TL);
|
|
return _readByte();
|
|
}
|
|
|
|
|
|
int DS1821::setHigh(int8_t hi)
|
|
{
|
|
if (_reset() != DS1821_RESET_OK) return DS1821_RESET_ERROR;
|
|
_command(WRITE_TH);
|
|
_command(hi);
|
|
return DS1821_RESET_OK;
|
|
}
|
|
|
|
|
|
int DS1821::getHigh()
|
|
{
|
|
if (_reset() != DS1821_RESET_OK) return DS1821_RESET_ERROR;
|
|
_command(READ_TL);
|
|
return _readByte();
|
|
}
|
|
|
|
|
|
int DS1821::getHighFlag()
|
|
{
|
|
return _getConfigFlag(DS1821_CONF_THF);
|
|
}
|
|
|
|
|
|
int DS1821::clrHighFlag()
|
|
{
|
|
return _clrConfigFlag(DS1821_CONF_THF);
|
|
}
|
|
|
|
|
|
int DS1821::getLowFlag()
|
|
{
|
|
return _getConfigFlag(DS1821_CONF_TLF);
|
|
}
|
|
|
|
|
|
int DS1821::clrLowFlag()
|
|
{
|
|
return _clrConfigFlag(DS1821_CONF_TLF);
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////
|
|
//
|
|
// THERMOSTAT CONFIG
|
|
//
|
|
int DS1821::setOneWireMode(uint8_t VDD, uint8_t DQ)
|
|
{
|
|
_VDD = VDD;
|
|
_DQ = DQ;
|
|
// switch off power
|
|
pinMode(_VDD, OUTPUT);
|
|
digitalWrite(_VDD, LOW);
|
|
pinMode(_DQ, OUTPUT);
|
|
digitalWrite(_DQ, HIGH);
|
|
delay(1);
|
|
// toggle 16 times.
|
|
for(uint8_t i = 0; i < 16; i++)
|
|
{
|
|
digitalWrite(_DQ, LOW);
|
|
digitalWrite(_DQ, HIGH);
|
|
}
|
|
pinMode(_DQ, INPUT);
|
|
// switch power on again.
|
|
digitalWrite(_VDD, HIGH);
|
|
delay(1);
|
|
return _clrConfigFlag(DS1821_CONF_TR);
|
|
}
|
|
|
|
|
|
int DS1821::setPolarity(int activstate)
|
|
{
|
|
if (activstate == HIGH) return _setConfigFlag(DS1821_CONF_POL);
|
|
return _clrConfigFlag(DS1821_CONF_POL);
|
|
}
|
|
|
|
|
|
int DS1821::getPolarity()
|
|
{
|
|
return _getConfigFlag(DS1821_CONF_POL);
|
|
}
|
|
|
|
|
|
int DS1821::setThermostatMode()
|
|
{
|
|
int rv = _setConfigFlag(DS1821_CONF_TR);
|
|
delay(10); // wait for copy to NVRAM
|
|
digitalWrite(_VDD, LOW);
|
|
delay(1000);
|
|
digitalWrite(_VDD, HIGH);
|
|
return rv;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// PRIVATE
|
|
//
|
|
int DS1821::_getConfigFlag(uint8_t flag)
|
|
{
|
|
return ((_readConfig() & flag) > 0); // true = 1 / false = 0
|
|
}
|
|
|
|
|
|
// See page 4 datasheet
|
|
uint8_t DS1821::_waitForNVB()
|
|
{
|
|
uint8_t config = 0;
|
|
for (uint8_t i = 0; i < 10; i++)
|
|
{
|
|
config = _readConfig();
|
|
if (!(config & DS1821_CONF_NVB)) break;
|
|
delay(1);
|
|
}
|
|
return config;
|
|
}
|
|
|
|
|
|
int DS1821::_setConfigFlag(uint8_t flag)
|
|
{
|
|
uint8_t config = _waitForNVB();
|
|
config |= flag;
|
|
return _writeConfig(config);
|
|
}
|
|
|
|
|
|
int DS1821::_clrConfigFlag(uint8_t flag)
|
|
{
|
|
uint8_t config = _waitForNVB();
|
|
config &= ~flag;
|
|
return _writeConfig(config);
|
|
}
|
|
|
|
|
|
int DS1821::_readConfig()
|
|
{
|
|
if (_reset() != DS1821_RESET_OK) return DS1821_RESET_ERROR;
|
|
_command(READ_CONFIG_REG);
|
|
return _readByte();
|
|
}
|
|
|
|
|
|
int DS1821::_writeConfig(uint8_t val)
|
|
{
|
|
while (_getConfigFlag(DS1821_CONF_NVB)) delay(1);
|
|
if (_reset() != DS1821_RESET_OK) return DS1821_RESET_ERROR;
|
|
_command(WRITE_CONFIG_REG);
|
|
_command(val);
|
|
return DS1821_RESET_OK;
|
|
}
|
|
|
|
|
|
// -- END OF FILE --
|