Compare commits

...

2 Commits

Author SHA1 Message Date
11070fdaa6 Add Dallas_Temperature Lib 2025-05-14 23:17:02 +01:00
c203816f0d update gitignore 2025-05-14 22:54:03 +01:00
48 changed files with 3545 additions and 683 deletions

1
.gitignore vendored
View File

@ -1,4 +1,3 @@
build/
.vscode/
bin/

View File

@ -1,20 +0,0 @@
The MIT License (MIT)
Copyright (c) 2013 Mathias Munk Hansen
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,51 +0,0 @@
# DS18B20 #
Arduino library for the Maxim Integrated DS18B20 1-Wire temperature sensor. This library is very simple and intuitive to use, and supports auto-discovering sensors with an optional high/low condition or manually addressing individual sensors.
For example, we can get the temperature from every sensor on the wire with just a few lines of code:
```
#include <DS18B20.h>
DS18B20 ds(2);
void setup() {
Serial.begin(9600);
}
void loop() {
while (ds.selectNext()) {
Serial.println(ds.getTempC());
}
}
```
See the included [examples](/examples/) for more.
## Installation ##
This library uses the OneWire library, so you will need to have this installed. Install it using the Library Manager in the Arduino IDE or download the latest release from [GitHub](https://github.com/PaulStoffregen/OneWire).
In the **OneWire.h** file set `ONEWIRE_SEARCH` to 0 since the search functionality is also implemented in this library (don't do this if you need the search functionality for other 1-Wire devices). CRC must be enabled (choose whichever algorithm you prefer). This may save some space on your Arduino.
## Wiring the DS18B20 ##
The resistor shown in all the circuit diagrams is 4.7k Ohm pullup resistor.
### External Power Mode ###
#### Single ####
![A single externally powered DS18B20](/extras/single_external.png)
#### Multiple ####
![Multiple externally powered DS18B20s](/extras/multiple_external.png)
### Parasitic Power Mode ###
#### Single ####
![A single parasite powered DS18B20](/extras/single_parasite.png)
#### Multiple ####
![Multiple parasite powered DS18B20s](/extras/multiple_parasite.png)
### Mixed Power Mode ###
![Mixed mode DS18B20s](/extras/mixed_mode.png)

View File

@ -1,32 +0,0 @@
#include <DS18B20.h>
#define LOW_ALARM 20
#define HIGH_ALARM 25
DS18B20 ds(2);
void setup() {
Serial.begin(9600);
while (ds.selectNext()) {
ds.setAlarms(LOW_ALARM, HIGH_ALARM);
}
}
void loop() {
ds.doConversion();
while (ds.selectNextAlarm()) {
Serial.print("Alarm Low: ");
Serial.print(ds.getAlarmLow());
Serial.println(" C");
Serial.print("Alarm High: ");
Serial.print(ds.getAlarmHigh());
Serial.println(" C");
Serial.print("Temperature: ");
Serial.print(ds.getTempC());
Serial.println(" C\n");
}
delay(10000);
}

View File

@ -1,58 +0,0 @@
#include <DS18B20.h>
DS18B20 ds(2);
void setup() {
Serial.begin(9600);
Serial.print("Devices: ");
Serial.println(ds.getNumberOfDevices());
Serial.println();
}
void loop() {
while (ds.selectNext()) {
switch (ds.getFamilyCode()) {
case MODEL_DS18S20:
Serial.println("Model: DS18S20/DS1820");
break;
case MODEL_DS1822:
Serial.println("Model: DS1822");
break;
case MODEL_DS18B20:
Serial.println("Model: DS18B20");
break;
default:
Serial.println("Unrecognized Device");
break;
}
uint8_t address[8];
ds.getAddress(address);
Serial.print("Address:");
for (uint8_t i = 0; i < 8; i++) {
Serial.print(" ");
Serial.print(address[i]);
}
Serial.println();
Serial.print("Resolution: ");
Serial.println(ds.getResolution());
Serial.print("Power Mode: ");
if (ds.getPowerMode()) {
Serial.println("External");
} else {
Serial.println("Parasite");
}
Serial.print("Temperature: ");
Serial.print(ds.getTempC());
Serial.print(" C / ");
Serial.print(ds.getTempF());
Serial.println(" F");
Serial.println();
}
delay(10000);
}

View File

@ -1,33 +0,0 @@
#include <DS18B20.h>
#define LOW_ALARM 20
#define HIGH_ALARM 25
DS18B20 ds(2);
uint8_t address[] = {40, 250, 31, 218, 4, 0, 0, 52};
uint8_t selected;
void setup() {
Serial.begin(9600);
selected = ds.select(address);
if (selected) {
ds.setAlarms(LOW_ALARM, HIGH_ALARM);
} else {
Serial.println("Device not found!");
}
}
void loop() {
if (selected) {
if (ds.hasAlarm()) {
Serial.print("Warning! Temperature is ");
Serial.print(ds.getTempC());
Serial.println(" C");
}
} else {
Serial.println("Device not found!");
}
delay(10000);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 193 KiB

View File

@ -1,31 +0,0 @@
DS18B20 KEYWORD1
select KEYWORD2
selectNext KEYWORD2
selectNextAlarm KEYWORD2
resetSearch KEYWORD2
getTempC KEYWORD2
getTempF KEYWORD2
getResolution KEYWORD2
setResolution KEYWORD2
getPowerMode KEYWORD2
getFamilyCode KEYWORD2
getAddress KEYWORD2
doConversion KEYWORD2
getNumberOfDevices KEYWORD2
hasAlarm KEYWORD2
setAlarms KEYWORD2
getAlarmLow KEYWORD2
setAlarmLow KEYWORD2
getAlarmHigh KEYWORD2
setAlarmHigh KEYWORD2
setRegisters KEYWORD2
getLowRegister KEYWORD2
setLowRegister KEYWORD2
getHighRegister KEYWORD2
setHighRegister KEYWORD2
MODEL_DS1820 LITERAL1
MODEL_DS18S20 LITERAL1
MODEL_DS1822 LITERAL1
MODEL_DS18B20 LITERAL1

View File

@ -1,10 +0,0 @@
name=DS18B20
version=1.0.0
author=Mathias Munk Hansen
maintainer=Mathias Munk Hansen <matmunk@gmail.com>
sentence=Arduino library for the Maxim Integrated DS18B20 1-Wire temperature sensor.
paragraph=This library is very simple and intuitive to use, and supports auto-discovering sensors with an optional high/low condition or manually addressing individual sensors.
category=Sensors
url=https://github.com/matmunk/DS18B20
architectures=*
includes=DS18B20.h

View File

@ -1,361 +0,0 @@
#include <DS18B20.h>
DS18B20::DS18B20(uint8_t pin) : oneWire(OneWire(pin)) {
resetSearch();
sendCommand(SKIP_ROM, READ_POWER_SUPPLY);
globalPowerMode = oneWire.read_bit();
while (selectNext()) {
uint8_t resolution = getResolution();
if (resolution > globalResolution) {
globalResolution = resolution;
}
numberOfDevices++;
}
}
uint8_t DS18B20::select(uint8_t address[]) {
if (isConnected(address)) {
memcpy(selectedAddress, address, 8);
if (readScratchpad()) {
selectedResolution = getResolution();
sendCommand(MATCH_ROM, READ_POWER_SUPPLY);
selectedPowerMode = oneWire.read_bit();
return 1;
}
}
return 0;
}
uint8_t DS18B20::selectNext() {
if (oneWireSearch(SEARCH_ROM)) {
return select(searchAddress);
}
return 0;
}
uint8_t DS18B20::selectNextAlarm() {
if (oneWireSearch(ALARM_SEARCH)) {
return select(searchAddress);
}
return 0;
}
void DS18B20::resetSearch() {
lastDiscrepancy = 0;
lastDevice = 0;
}
float DS18B20::getTempC() {
sendCommand(MATCH_ROM, CONVERT_T, !selectedPowerMode);
delayForConversion(selectedResolution, selectedPowerMode);
readScratchpad();
uint8_t lsb = selectedScratchpad[TEMP_LSB];
uint8_t msb = selectedScratchpad[TEMP_MSB];
switch (selectedResolution) {
case 9:
lsb &= 0xF8;
break;
case 10:
lsb &= 0xFC;
break;
case 11:
lsb &= 0xFE;
break;
}
uint8_t sign = msb & 0x80;
int16_t temp = (msb << 8) + lsb;
if (sign) {
temp = ((temp ^ 0xffff) + 1) * -1;
}
return temp / 16.0;
}
float DS18B20::getTempF() {
return getTempC() * 1.8 + 32;
}
uint8_t DS18B20::getResolution() {
switch (selectedScratchpad[CONFIGURATION]) {
case RES_9_BIT:
return 9;
case RES_10_BIT:
return 10;
case RES_11_BIT:
return 11;
case RES_12_BIT:
return 12;
}
}
void DS18B20::setResolution(uint8_t resolution) {
resolution = constrain(resolution, 9, 12);
switch (resolution) {
case 9:
selectedScratchpad[CONFIGURATION] = RES_9_BIT;
break;
case 10:
selectedScratchpad[CONFIGURATION] = RES_10_BIT;
break;
case 11:
selectedScratchpad[CONFIGURATION] = RES_11_BIT;
break;
case 12:
selectedScratchpad[CONFIGURATION] = RES_12_BIT;
break;
}
if (resolution > globalResolution) {
globalResolution = resolution;
}
writeScratchpad();
}
uint8_t DS18B20::getPowerMode() {
return selectedPowerMode;
}
uint8_t DS18B20::getFamilyCode() {
return selectedAddress[0];
}
void DS18B20::getAddress(uint8_t address[]) {
memcpy(address, selectedAddress, 8);
}
void DS18B20::doConversion() {
sendCommand(SKIP_ROM, CONVERT_T, !globalPowerMode);
delayForConversion(globalResolution, globalPowerMode);
}
uint8_t DS18B20::getNumberOfDevices() {
return numberOfDevices;
}
uint8_t DS18B20::hasAlarm() {
uint8_t oldResolution = selectedResolution;
setResolution(9);
float temp = getTempC();
setResolution(oldResolution);
return ((temp <= selectedScratchpad[ALARM_LOW]) || (temp >= selectedScratchpad[ALARM_HIGH]));
}
void DS18B20::setAlarms(int8_t alarmLow, int8_t alarmHigh) {
setAlarmLow(alarmLow);
setAlarmHigh(alarmHigh);
writeScratchpad();
}
int8_t DS18B20::getAlarmLow() {
return selectedScratchpad[ALARM_LOW];
}
void DS18B20::setAlarmLow(int8_t alarmLow) {
alarmLow = constrain(alarmLow, -55, 125);
selectedScratchpad[ALARM_LOW] = alarmLow;
writeScratchpad();
}
int8_t DS18B20::getAlarmHigh() {
return selectedScratchpad[ALARM_HIGH];
}
void DS18B20::setAlarmHigh(int8_t alarmHigh) {
alarmHigh = constrain(alarmHigh, -55, 125);
selectedScratchpad[ALARM_HIGH] = alarmHigh;
writeScratchpad();
}
void DS18B20::setRegisters(int8_t lowRegister, int8_t highRegister) {
setAlarms(lowRegister, highRegister);
}
int8_t DS18B20::getLowRegister() {
return getAlarmLow();
}
void DS18B20::setLowRegister(int8_t lowRegister) {
setAlarmLow(lowRegister);
}
int8_t DS18B20::getHighRegister() {
return getAlarmHigh();
}
void DS18B20::setHighRegister(int8_t highRegister) {
setAlarmHigh(highRegister);
}
uint8_t DS18B20::readScratchpad() {
sendCommand(MATCH_ROM, READ_SCRATCHPAD);
for (uint8_t i = 0; i < SIZE_SCRATCHPAD; i++) {
selectedScratchpad[i] = oneWire.read();
}
return OneWire::crc8(selectedScratchpad, 8) == selectedScratchpad[CRC8];
}
void DS18B20::writeScratchpad() {
sendCommand(MATCH_ROM, WRITE_SCRATCHPAD);
oneWire.write(selectedScratchpad[ALARM_HIGH]);
oneWire.write(selectedScratchpad[ALARM_LOW]);
oneWire.write(selectedScratchpad[CONFIGURATION]);
sendCommand(MATCH_ROM, COPY_SCRATCHPAD, !selectedPowerMode);
if (!selectedPowerMode) {
delay(10);
}
}
uint8_t DS18B20::sendCommand(uint8_t romCommand) {
if (!oneWire.reset()) {
return 0;
}
switch (romCommand) {
case SEARCH_ROM:
case SKIP_ROM:
case ALARM_SEARCH:
oneWire.write(romCommand);
break;
case MATCH_ROM:
oneWire.select(selectedAddress);
break;
default:
return 0;
}
return 1;
}
uint8_t DS18B20::sendCommand(uint8_t romCommand, uint8_t functionCommand, uint8_t power) {
if (!sendCommand(romCommand)) {
return 0;
}
switch (functionCommand) {
case CONVERT_T:
case COPY_SCRATCHPAD:
oneWire.write(functionCommand, power);
break;
case WRITE_SCRATCHPAD:
case READ_SCRATCHPAD:
case READ_POWER_SUPPLY:
oneWire.write(functionCommand);
break;
default:
return 0;
}
return 1;
}
uint8_t DS18B20::oneWireSearch(uint8_t romCommand) {
if (lastDevice || !sendCommand(romCommand)) {
resetSearch();
return 0;
}
uint8_t lastZero = 0;
uint8_t direction, byteNumber, bitNumber, currentBit, currentBitComp;
for (uint8_t bitPosition = 0; bitPosition < 64; bitPosition++) {
currentBit = oneWire.read_bit();
currentBitComp = oneWire.read_bit();
if (currentBit && currentBitComp) {
lastDiscrepancy = 0;
return 0;
}
byteNumber = bitPosition / 8;
bitNumber = bitPosition % 8;
if (!currentBit && !currentBitComp) {
if (bitPosition == lastDiscrepancy) {
direction = 1;
} else if (bitPosition > lastDiscrepancy) {
direction = 0;
lastZero = bitPosition;
} else {
direction = bitRead(searchAddress[byteNumber], bitNumber);
if (!direction) {
lastZero = bitPosition;
}
}
} else {
direction = currentBit;
}
bitWrite(searchAddress[byteNumber], bitNumber, direction);
oneWire.write_bit(direction);
}
lastDiscrepancy = lastZero;
if (!lastDiscrepancy) {
lastDevice = 1;
}
return 1;
}
uint8_t DS18B20::isConnected(uint8_t address[]) {
if (!sendCommand(SEARCH_ROM)) {
return 0;
}
uint8_t currentBit, currentBitComp, byteNumber, bitNumber;
for (uint8_t bitPosition = 0; bitPosition < 64; bitPosition++) {
currentBit = oneWire.read_bit();
currentBitComp = oneWire.read_bit();
if (currentBit && currentBitComp) {
return 0;
}
byteNumber = bitPosition / 8;
bitNumber = bitPosition % 8;
oneWire.write_bit(bitRead(address[byteNumber], bitNumber));
}
return 1;
}
void DS18B20::delayForConversion(uint8_t resolution, uint8_t powerMode) {
if (powerMode) {
while (!oneWire.read_bit());
} else {
switch (resolution) {
case 9:
delay(CONV_TIME_9_BIT);
break;
case 10:
delay(CONV_TIME_10_BIT);
break;
case 11:
delay(CONV_TIME_11_BIT);
break;
case 12:
delay(CONV_TIME_12_BIT);
break;
}
}
}

View File

@ -1,86 +0,0 @@
#ifndef DS18B20_H
#define DS18B20_H
#include "Arduino.h"
#include <OneWire.h>
#define SEARCH_ROM 0xF0
#define READ_ROM 0x33
#define MATCH_ROM 0x55
#define SKIP_ROM 0xCC
#define ALARM_SEARCH 0xEC
#define CONVERT_T 0x44
#define WRITE_SCRATCHPAD 0x4E
#define READ_SCRATCHPAD 0xBE
#define COPY_SCRATCHPAD 0x48
#define RECALL 0xB8
#define READ_POWER_SUPPLY 0xB4
#define MODEL_DS1820 0x10
#define MODEL_DS18S20 0x10
#define MODEL_DS1822 0x22
#define MODEL_DS18B20 0x28
#define SIZE_SCRATCHPAD 9
#define TEMP_LSB 0
#define TEMP_MSB 1
#define ALARM_HIGH 2
#define ALARM_LOW 3
#define CONFIGURATION 4
#define CRC8 8
#define RES_9_BIT 0x1F
#define RES_10_BIT 0x3F
#define RES_11_BIT 0x5F
#define RES_12_BIT 0x7F
#define CONV_TIME_9_BIT 94
#define CONV_TIME_10_BIT 188
#define CONV_TIME_11_BIT 375
#define CONV_TIME_12_BIT 750
class DS18B20 {
public:
DS18B20(uint8_t pin);
uint8_t select(uint8_t address[]);
uint8_t selectNext();
uint8_t selectNextAlarm();
void resetSearch();
float getTempC();
float getTempF();
uint8_t getResolution();
void setResolution(uint8_t resolution);
uint8_t getPowerMode();
uint8_t getFamilyCode();
void getAddress(uint8_t address[]);
void doConversion();
uint8_t getNumberOfDevices();
uint8_t hasAlarm();
void setAlarms(int8_t alarmLow, int8_t alarmHigh);
int8_t getAlarmLow();
void setAlarmLow(int8_t alarmLow);
int8_t getAlarmHigh();
void setAlarmHigh(int8_t alarmHigh);
void setRegisters(int8_t lowRegister, int8_t highRegister);
int8_t getLowRegister();
void setLowRegister(int8_t lowRegister);
int8_t getHighRegister();
void setHighRegister(int8_t highRegister);
private:
OneWire oneWire;
uint8_t globalResolution;
uint8_t globalPowerMode;
uint8_t numberOfDevices;
uint8_t selectedAddress[8];
uint8_t selectedScratchpad[SIZE_SCRATCHPAD];
uint8_t selectedResolution;
uint8_t selectedPowerMode;
uint8_t searchAddress[8];
uint8_t lastDiscrepancy;
uint8_t lastDevice;
uint8_t readScratchpad();
void writeScratchpad();
uint8_t sendCommand(uint8_t romCommand);
uint8_t sendCommand(uint8_t romCommand, uint8_t functionCommand, uint8_t power = 0);
uint8_t oneWireSearch(uint8_t romCommand);
uint8_t isConnected(uint8_t address[]);
void delayForConversion(uint8_t resolution, uint8_t powerMode);
};
#endif

View File

@ -0,0 +1,10 @@
# Author: diplfranzhoepfinger
# reference: https://docs.espressif.com/projects/arduino-esp32/en/latest/esp-idf_component.html
# URL: https://github.com/milesburton/Arduino-Temperature-Control-Library
# DATE: 15.02.2023
idf_component_register(
SRCS "DallasTemperature.cpp"
INCLUDE_DIRS "."
PRIV_REQUIRES OneWire arduino
)

View File

@ -0,0 +1,809 @@
#include "DallasTemperature.h"
#if ARDUINO >= 100
#include "Arduino.h"
#else
extern "C" {
#include "WConstants.h"
}
#endif
// OneWire commands
#define STARTCONVO 0x44 // Tells device to take a temperature reading
#define COPYSCRATCH 0x48 // Copy scratchpad to EEPROM
#define READSCRATCH 0xBE // Read from scratchpad
#define WRITESCRATCH 0x4E // Write to scratchpad
#define RECALLSCRATCH 0xB8 // Recall from EEPROM to scratchpad
#define READPOWERSUPPLY 0xB4 // Determine if device needs parasite power
#define ALARMSEARCH 0xEC // Query bus for devices with an alarm condition
// Scratchpad locations
#define TEMP_LSB 0
#define TEMP_MSB 1
#define HIGH_ALARM_TEMP 2
#define LOW_ALARM_TEMP 3
#define CONFIGURATION 4
#define INTERNAL_BYTE 5
#define COUNT_REMAIN 6
#define COUNT_PER_C 7
#define SCRATCHPAD_CRC 8
// Device resolution
#define TEMP_9_BIT 0x1F
#define TEMP_10_BIT 0x3F
#define TEMP_11_BIT 0x5F
#define TEMP_12_BIT 0x7F
#define NO_ALARM_HANDLER ((AlarmHandler *)0)
// DSROM FIELDS
#define DSROM_FAMILY 0
#define DSROM_CRC 7
DallasTemperature::DallasTemperature() {
_wire = nullptr;
devices = 0;
ds18Count = 0;
parasite = false;
bitResolution = 9;
waitForConversion = true;
checkForConversion = true;
autoSaveScratchPad = true;
useExternalPullup = false;
#if REQUIRESALARMS
setAlarmHandler(NO_ALARM_HANDLER);
alarmSearchJunction = -1;
alarmSearchExhausted = 0;
#endif
}
DallasTemperature::DallasTemperature(OneWire* _oneWire) : DallasTemperature() {
setOneWire(_oneWire);
}
DallasTemperature::DallasTemperature(OneWire* _oneWire, uint8_t _pullupPin) : DallasTemperature(_oneWire) {
setPullupPin(_pullupPin);
}
void DallasTemperature::setOneWire(OneWire* _oneWire) {
_wire = _oneWire;
devices = 0;
ds18Count = 0;
parasite = false;
bitResolution = 9;
waitForConversion = true;
checkForConversion = true;
autoSaveScratchPad = true;
}
void DallasTemperature::setPullupPin(uint8_t _pullupPin) {
useExternalPullup = true;
pullupPin = _pullupPin;
pinMode(pullupPin, OUTPUT);
deactivateExternalPullup();
}
void DallasTemperature::begin(void) {
DeviceAddress deviceAddress;
for (uint8_t retry = 0; retry < MAX_INITIALIZATION_RETRIES; retry++) {
_wire->reset_search();
devices = 0;
ds18Count = 0;
delay(INITIALIZATION_DELAY_MS);
while (_wire->search(deviceAddress)) {
if (validAddress(deviceAddress)) {
devices++;
if (validFamily(deviceAddress)) {
ds18Count++;
if (!parasite && readPowerSupply(deviceAddress)) {
parasite = true;
}
uint8_t b = getResolution(deviceAddress);
if (b > bitResolution) {
bitResolution = b;
}
}
}
}
if (devices > 0) break;
}
}
void DallasTemperature::activateExternalPullup() {
if (useExternalPullup) digitalWrite(pullupPin, LOW);
}
void DallasTemperature::deactivateExternalPullup() {
if (useExternalPullup) digitalWrite(pullupPin, HIGH);
}
bool DallasTemperature::validFamily(const uint8_t* deviceAddress) {
switch (deviceAddress[0]) {
case DS18S20MODEL:
case DS18B20MODEL:
case DS1822MODEL:
case DS1825MODEL:
case DS28EA00MODEL:
return true;
default:
return false;
}
}
bool DallasTemperature::validAddress(const uint8_t* deviceAddress) {
return (_wire->crc8(const_cast<uint8_t*>(deviceAddress), 7) == deviceAddress[7]);
}
bool DallasTemperature::getAddress(uint8_t* deviceAddress, uint8_t index) {
if (index < devices) {
uint8_t depth = 0;
_wire->reset_search();
while (depth <= index && _wire->search(deviceAddress)) {
if (depth == index && validAddress(deviceAddress)) {
return true;
}
depth++;
}
}
return false;
}
uint8_t DallasTemperature::getDeviceCount(void) {
return devices;
}
uint8_t DallasTemperature::getDS18Count(void) {
return ds18Count;
}
bool DallasTemperature::isConnected(const uint8_t* deviceAddress) {
ScratchPad scratchPad;
return isConnected(deviceAddress, scratchPad);
}
bool DallasTemperature::isConnected(const uint8_t* deviceAddress, uint8_t* scratchPad) {
bool b = readScratchPad(deviceAddress, scratchPad);
return b && !isAllZeros(scratchPad) && (_wire->crc8(scratchPad, 8) == scratchPad[SCRATCHPAD_CRC]);
}
bool DallasTemperature::readPowerSupply(const uint8_t* deviceAddress) {
bool parasiteMode = false;
_wire->reset();
if (deviceAddress == nullptr) {
_wire->skip();
} else {
_wire->select(deviceAddress);
}
_wire->write(READPOWERSUPPLY);
if (_wire->read_bit() == 0) {
parasiteMode = true;
}
_wire->reset();
return parasiteMode;
}
bool DallasTemperature::isParasitePowerMode(void) {
return parasite;
}
bool DallasTemperature::isAllZeros(const uint8_t* const scratchPad, const size_t length) {
for (size_t i = 0; i < length; i++) {
if (scratchPad[i] != 0) return false;
}
return true;
}
bool DallasTemperature::readScratchPad(const uint8_t* deviceAddress, uint8_t* scratchPad) {
int b = _wire->reset();
if (b == 0) return false;
_wire->select(deviceAddress);
_wire->write(READSCRATCH);
for (uint8_t i = 0; i < 9; i++) {
scratchPad[i] = _wire->read();
}
b = _wire->reset();
return (b == 1);
}
void DallasTemperature::writeScratchPad(const uint8_t* deviceAddress, const uint8_t* scratchPad) {
_wire->reset();
_wire->select(deviceAddress);
_wire->write(WRITESCRATCH);
_wire->write(scratchPad[HIGH_ALARM_TEMP]); // high alarm temp
_wire->write(scratchPad[LOW_ALARM_TEMP]); // low alarm temp
// DS1820 and DS18S20 have no configuration register
if (deviceAddress[0] != DS18S20MODEL) {
_wire->write(scratchPad[CONFIGURATION]);
}
if (autoSaveScratchPad) {
saveScratchPad(deviceAddress);
} else {
_wire->reset();
}
}
bool DallasTemperature::saveScratchPad(const uint8_t* deviceAddress) {
if (_wire->reset() == 0) return false;
if (deviceAddress == nullptr)
_wire->skip();
else
_wire->select(deviceAddress);
_wire->write(COPYSCRATCH, parasite);
// Specification: NV Write Cycle Time is typically 2ms, max 10ms
// Waiting 20ms to allow for sensors that take longer in practice
if (!parasite) {
delay(20);
} else {
activateExternalPullup();
delay(20);
deactivateExternalPullup();
}
return (_wire->reset() == 1);
}
bool DallasTemperature::recallScratchPad(const uint8_t* deviceAddress) {
if (_wire->reset() == 0) return false;
if (deviceAddress == nullptr)
_wire->skip();
else
_wire->select(deviceAddress);
_wire->write(RECALLSCRATCH, parasite);
// Specification: Strong pullup only needed when writing to EEPROM
unsigned long start = millis();
while (_wire->read_bit() == 0) {
if (millis() - start > 20) return false;
yield();
}
return (_wire->reset() == 1);
}
int32_t DallasTemperature::getTemp(const uint8_t* deviceAddress, byte retryCount) {
ScratchPad scratchPad;
byte retries = 0;
while (retries++ <= retryCount) {
if (isConnected(deviceAddress, scratchPad)) {
return calculateTemperature(deviceAddress, scratchPad);
}
}
return DEVICE_DISCONNECTED_RAW;
}
float DallasTemperature::getTempC(const uint8_t* deviceAddress, byte retryCount) {
return rawToCelsius(getTemp(deviceAddress, retryCount));
}
float DallasTemperature::getTempF(const uint8_t* deviceAddress) {
return rawToFahrenheit(getTemp(deviceAddress));
}
float DallasTemperature::getTempCByIndex(uint8_t index) {
DeviceAddress deviceAddress;
if (!getAddress(deviceAddress, index)) {
return DEVICE_DISCONNECTED_C;
}
return getTempC((uint8_t*)deviceAddress);
}
float DallasTemperature::getTempFByIndex(uint8_t index) {
DeviceAddress deviceAddress;
if (!getAddress(deviceAddress, index)) {
return DEVICE_DISCONNECTED_F;
}
return getTempF((uint8_t*)deviceAddress);
}
void DallasTemperature::setResolution(uint8_t newResolution) {
bitResolution = constrain(newResolution, 9, 12);
DeviceAddress deviceAddress;
_wire->reset_search();
for (uint8_t i = 0; i < devices; i++) {
if (_wire->search(deviceAddress) && validAddress(deviceAddress)) {
setResolution(deviceAddress, bitResolution, true);
}
}
}
bool DallasTemperature::setResolution(const uint8_t* deviceAddress, uint8_t newResolution, bool skipGlobalBitResolutionCalculation) {
bool success = false;
if (deviceAddress[0] == DS18S20MODEL) {
success = true;
} else {
newResolution = constrain(newResolution, 9, 12);
uint8_t newValue = 0;
ScratchPad scratchPad;
if (isConnected(deviceAddress, scratchPad)) {
switch (newResolution) {
case 12: newValue = TEMP_12_BIT; break;
case 11: newValue = TEMP_11_BIT; break;
case 10: newValue = TEMP_10_BIT; break;
case 9:
default: newValue = TEMP_9_BIT; break;
}
if (scratchPad[CONFIGURATION] != newValue) {
scratchPad[CONFIGURATION] = newValue;
writeScratchPad(deviceAddress, scratchPad);
}
success = true;
}
}
if (!skipGlobalBitResolutionCalculation && success) {
bitResolution = newResolution;
if (devices > 1) {
DeviceAddress deviceAddr;
_wire->reset_search();
for (uint8_t i = 0; i < devices; i++) {
if (bitResolution == 12) break;
if (_wire->search(deviceAddr) && validAddress(deviceAddr)) {
uint8_t b = getResolution(deviceAddr);
if (b > bitResolution) bitResolution = b;
}
}
}
}
return success;
}
uint8_t DallasTemperature::getResolution() {
return bitResolution;
}
uint8_t DallasTemperature::getResolution(const uint8_t* deviceAddress) {
if (deviceAddress[0] == DS18S20MODEL) return 12;
ScratchPad scratchPad;
if (isConnected(deviceAddress, scratchPad)) {
if (deviceAddress[0] == DS1825MODEL && scratchPad[CONFIGURATION] & 0x80) {
return 12;
}
switch (scratchPad[CONFIGURATION]) {
case TEMP_12_BIT: return 12;
case TEMP_11_BIT: return 11;
case TEMP_10_BIT: return 10;
case TEMP_9_BIT: return 9;
}
}
return 0;
}
float DallasTemperature::toFahrenheit(float celsius) {
return (celsius * 1.8f) + 32.0f;
}
float DallasTemperature::toCelsius(float fahrenheit) {
return (fahrenheit - 32.0f) * 0.555555556f;
}
float DallasTemperature::rawToCelsius(int32_t raw) {
if (raw <= DEVICE_DISCONNECTED_RAW)
return DEVICE_DISCONNECTED_C;
return (float)raw * 0.0078125f; // 1/128
}
float DallasTemperature::rawToFahrenheit(int32_t raw) {
if (raw <= DEVICE_DISCONNECTED_RAW)
return DEVICE_DISCONNECTED_F;
return rawToCelsius(raw) * 1.8f + 32.0f;
}
int16_t DallasTemperature::celsiusToRaw(float celsius) {
return static_cast<int16_t>(celsius * 128.0f);
}
uint16_t DallasTemperature::millisToWaitForConversion(uint8_t bitResolution) {
switch (bitResolution) {
case 9: return 94;
case 10: return 188;
case 11: return 375;
default: return 750;
}
}
uint16_t DallasTemperature::millisToWaitForConversion() {
return millisToWaitForConversion(bitResolution);
}
void DallasTemperature::setWaitForConversion(bool flag) {
waitForConversion = flag;
}
bool DallasTemperature::getWaitForConversion() {
return waitForConversion;
}
void DallasTemperature::setCheckForConversion(bool flag) {
checkForConversion = flag;
}
bool DallasTemperature::getCheckForConversion() {
return checkForConversion;
}
bool DallasTemperature::isConversionComplete() {
uint8_t b = _wire->read_bit();
return (b == 1);
}
void DallasTemperature::setAutoSaveScratchPad(bool flag) {
autoSaveScratchPad = flag;
}
bool DallasTemperature::getAutoSaveScratchPad() {
return autoSaveScratchPad;
}
DallasTemperature::request_t DallasTemperature::requestTemperatures() {
request_t req = {};
req.result = true;
_wire->reset();
_wire->skip();
_wire->write(STARTCONVO, parasite);
req.timestamp = millis();
if (!waitForConversion) return req;
blockTillConversionComplete(bitResolution, req.timestamp);
return req;
}
DallasTemperature::request_t DallasTemperature::requestTemperaturesByAddress(const uint8_t* deviceAddress) {
request_t req = {};
uint8_t deviceBitResolution = getResolution(deviceAddress);
if (deviceBitResolution == 0) {
req.result = false;
return req;
}
_wire->reset();
_wire->select(deviceAddress);
_wire->write(STARTCONVO, parasite);
req.timestamp = millis();
req.result = true;
if (!waitForConversion) return req;
blockTillConversionComplete(deviceBitResolution, req.timestamp);
return req;
}
DallasTemperature::request_t DallasTemperature::requestTemperaturesByIndex(uint8_t index) {
DeviceAddress deviceAddress;
getAddress(deviceAddress, index);
return requestTemperaturesByAddress(deviceAddress);
}
void DallasTemperature::blockTillConversionComplete(uint8_t bitResolution) {
unsigned long start = millis();
blockTillConversionComplete(bitResolution, start);
}
void DallasTemperature::blockTillConversionComplete(uint8_t bitResolution, unsigned long start) {
if (checkForConversion && !parasite) {
while (!isConversionComplete() && ((unsigned long)(millis() - start) < (unsigned long)MAX_CONVERSION_TIMEOUT)) {
yield();
}
} else {
unsigned long delayInMillis = millisToWaitForConversion(bitResolution);
activateExternalPullup();
delay(delayInMillis);
deactivateExternalPullup();
}
}
void DallasTemperature::blockTillConversionComplete(uint8_t bitResolution, request_t req) {
if (req.result) {
blockTillConversionComplete(bitResolution, req.timestamp);
}
}
int32_t DallasTemperature::calculateTemperature(const uint8_t* deviceAddress, uint8_t* scratchPad) {
int32_t fpTemperature = 0;
// looking thru the spec sheets of all supported devices, bit 15 is always the signing bit
int32_t neg = 0x0;
if (scratchPad[TEMP_MSB] & 0x80)
neg = 0xFFF80000;
// detect MAX31850
if (deviceAddress[0] == DS1825MODEL && scratchPad[CONFIGURATION] & 0x80) {
if (scratchPad[TEMP_LSB] & 1) { // Fault Detected
if (scratchPad[HIGH_ALARM_TEMP] & 1) {
return DEVICE_FAULT_OPEN_RAW;
} else if (scratchPad[HIGH_ALARM_TEMP] >> 1 & 1) {
return DEVICE_FAULT_SHORTGND_RAW;
} else if (scratchPad[HIGH_ALARM_TEMP] >> 2 & 1) {
return DEVICE_FAULT_SHORTVDD_RAW;
} else {
return DEVICE_DISCONNECTED_RAW;
}
}
// We must mask out bit 1 (reserved) and 0 (fault) on TEMP_LSB
fpTemperature = (((int32_t)scratchPad[TEMP_MSB]) << 11)
| (((int32_t)scratchPad[TEMP_LSB] & 0xFC) << 3)
| neg;
} else {
fpTemperature = (((int16_t)scratchPad[TEMP_MSB]) << 11)
| (((int16_t)scratchPad[TEMP_LSB]) << 3)
| neg;
}
/*
DS1820 and DS18S20 have a 9-bit temperature register.
Resolutions greater than 9-bit can be calculated using the data from
the temperature, and COUNT REMAIN and COUNT PER °C registers in the
scratchpad. The resolution of the calculation depends on the model.
While the COUNT PER °C register is hard-wired to 16 (10h) in a
DS18S20, it changes with temperature in DS1820.
After reading the scratchpad, the TEMP_READ value is obtained by
truncating the 0.5°C bit (bit 0) from the temperature data. The
extended resolution temperature can then be calculated using the
following equation:
COUNT_PER_C - COUNT_REMAIN
TEMPERATURE = TEMP_READ - 0.25 + --------------------------
COUNT_PER_C
Hagai Shatz simplified this to integer arithmetic for a 12 bits
value for a DS18S20, and James Cameron added legacy DS1820 support.
See - http://myarduinotoy.blogspot.co.uk/2013/02/12bit-result-from-ds18s20.html
*/
if ((deviceAddress[DSROM_FAMILY] == DS18S20MODEL) && (scratchPad[COUNT_PER_C] != 0)) {
fpTemperature = (((fpTemperature & 0xfff0) << 3) - 32
+ (((scratchPad[COUNT_PER_C] - scratchPad[COUNT_REMAIN]) << 7)
/ scratchPad[COUNT_PER_C])) | neg;
}
return fpTemperature;
}
#if REQUIRESALARMS
void DallasTemperature::setAlarmHandler(const AlarmHandler* handler) {
_AlarmHandler = handler;
}
void DallasTemperature::setHighAlarmTemp(const uint8_t* deviceAddress, int8_t celsius) {
// make sure the alarm temperature is within the device's range
if (celsius > 125) celsius = 125;
else if (celsius < -55) celsius = -55;
ScratchPad scratchPad;
if (isConnected(deviceAddress, scratchPad)) {
scratchPad[HIGH_ALARM_TEMP] = (uint8_t)celsius;
writeScratchPad(deviceAddress, scratchPad);
}
}
void DallasTemperature::setLowAlarmTemp(const uint8_t* deviceAddress, int8_t celsius) {
// make sure the alarm temperature is within the device's range
if (celsius > 125) celsius = 125;
else if (celsius < -55) celsius = -55;
ScratchPad scratchPad;
if (isConnected(deviceAddress, scratchPad)) {
scratchPad[LOW_ALARM_TEMP] = (uint8_t)celsius;
writeScratchPad(deviceAddress, scratchPad);
}
}
int8_t DallasTemperature::getHighAlarmTemp(const uint8_t* deviceAddress) {
ScratchPad scratchPad;
if (isConnected(deviceAddress, scratchPad))
return (int8_t)scratchPad[HIGH_ALARM_TEMP];
return DEVICE_DISCONNECTED_C;
}
int8_t DallasTemperature::getLowAlarmTemp(const uint8_t* deviceAddress) {
ScratchPad scratchPad;
if (isConnected(deviceAddress, scratchPad))
return (int8_t)scratchPad[LOW_ALARM_TEMP];
return DEVICE_DISCONNECTED_C;
}
void DallasTemperature::resetAlarmSearch() {
alarmSearchJunction = -1;
alarmSearchExhausted = 0;
for (uint8_t i = 0; i < 7; i++) {
alarmSearchAddress[i] = 0;
}
}
bool DallasTemperature::alarmSearch(uint8_t* newAddr) {
uint8_t i;
int8_t lastJunction = -1;
uint8_t done = 1;
if (alarmSearchExhausted)
return false;
if (!_wire->reset())
return false;
_wire->write(ALARMSEARCH);
for (i = 0; i < 64; i++) {
uint8_t a = _wire->read_bit();
uint8_t nota = _wire->read_bit();
uint8_t ibyte = i / 8;
uint8_t ibit = 1 << (i & 7);
if (a && nota)
return false;
if (!a && !nota) {
if (i == alarmSearchJunction) {
a = 1;
alarmSearchJunction = lastJunction;
} else if (i < alarmSearchJunction) {
if (alarmSearchAddress[ibyte] & ibit) {
a = 1;
} else {
a = 0;
done = 0;
lastJunction = i;
}
} else {
a = 0;
alarmSearchJunction = i;
done = 0;
}
}
if (a)
alarmSearchAddress[ibyte] |= ibit;
else
alarmSearchAddress[ibyte] &= ~ibit;
_wire->write_bit(a);
}
if (done)
alarmSearchExhausted = 1;
for (i = 0; i < 8; i++)
newAddr[i] = alarmSearchAddress[i];
return true;
}
bool DallasTemperature::hasAlarm(const uint8_t* deviceAddress) {
ScratchPad scratchPad;
if (isConnected(deviceAddress, scratchPad)) {
int8_t temp = calculateTemperature(deviceAddress, scratchPad) >> 7;
return (temp <= (int8_t)scratchPad[LOW_ALARM_TEMP] ||
temp >= (int8_t)scratchPad[HIGH_ALARM_TEMP]);
}
return false;
}
bool DallasTemperature::hasAlarm(void) {
DeviceAddress deviceAddress;
resetAlarmSearch();
return alarmSearch(deviceAddress);
}
void DallasTemperature::processAlarms(void) {
if (!hasAlarmHandler())
return;
resetAlarmSearch();
DeviceAddress alarmAddr;
while (alarmSearch(alarmAddr)) {
if (validAddress(alarmAddr)) {
_AlarmHandler(alarmAddr);
}
}
}
bool DallasTemperature::hasAlarmHandler() {
return (_AlarmHandler != NO_ALARM_HANDLER);
}
#endif
#if REQUIRESNEW
void* DallasTemperature::operator new(unsigned int size) {
void* p = malloc(size);
memset(p, 0, size);
return p;
}
void DallasTemperature::operator delete(void* p) {
free(p);
}
#endif
bool DallasTemperature::verifyDeviceCount(void) {
uint8_t actualCount = 0;
float temp;
requestTemperatures();
do {
temp = getTempCByIndex(actualCount);
if (temp > DEVICE_DISCONNECTED_C) {
actualCount++;
}
} while (temp > DEVICE_DISCONNECTED_C && actualCount < 255);
if (actualCount > devices) {
devices = actualCount;
begin();
return true;
}
return false;
}
void DallasTemperature::setUserData(const uint8_t* deviceAddress, int16_t data) {
// return when stored value == new value
if (getUserData(deviceAddress) == data)
return;
ScratchPad scratchPad;
if (isConnected(deviceAddress, scratchPad)) {
scratchPad[HIGH_ALARM_TEMP] = data >> 8;
scratchPad[LOW_ALARM_TEMP] = data & 255;
writeScratchPad(deviceAddress, scratchPad);
}
}
void DallasTemperature::setUserDataByIndex(uint8_t deviceIndex, int16_t data) {
DeviceAddress deviceAddress;
if (getAddress(deviceAddress, deviceIndex)) {
setUserData((uint8_t*)deviceAddress, data);
}
}
int16_t DallasTemperature::getUserData(const uint8_t* deviceAddress) {
int16_t data = 0;
ScratchPad scratchPad;
if (isConnected(deviceAddress, scratchPad)) {
data = scratchPad[HIGH_ALARM_TEMP] << 8;
data += scratchPad[LOW_ALARM_TEMP];
}
return data;
}
int16_t DallasTemperature::getUserDataByIndex(uint8_t deviceIndex) {
DeviceAddress deviceAddress;
getAddress(deviceAddress, deviceIndex);
return getUserData((uint8_t*)deviceAddress);
}

View File

@ -0,0 +1,192 @@
#ifndef DallasTemperature_h
#define DallasTemperature_h
#define DALLASTEMPLIBVERSION "4.0.3"
// Configuration
#ifndef REQUIRESNEW
#define REQUIRESNEW false
#endif
#ifndef REQUIRESALARMS
#define REQUIRESALARMS true
#endif
// Includes
#include <inttypes.h>
#include <Arduino.h>
#ifdef __STM32F1__
#include <OneWireSTM.h>
#else
#include <OneWire.h>
#endif
// Constants for device models
#define DS18S20MODEL 0x10 // also DS1820
#define DS18B20MODEL 0x28 // also MAX31820
#define DS1822MODEL 0x22
#define DS1825MODEL 0x3B // also MAX31850
#define DS28EA00MODEL 0x42
// Error Codes
#define DEVICE_DISCONNECTED_C -127
#define DEVICE_DISCONNECTED_F -196.6
#define DEVICE_DISCONNECTED_RAW -7040
#define DEVICE_FAULT_OPEN_C -254
#define DEVICE_FAULT_OPEN_F -425.199982
#define DEVICE_FAULT_OPEN_RAW -32512
#define DEVICE_FAULT_SHORTGND_C -253
#define DEVICE_FAULT_SHORTGND_F -423.399994
#define DEVICE_FAULT_SHORTGND_RAW -32384
#define DEVICE_FAULT_SHORTVDD_C -252
#define DEVICE_FAULT_SHORTVDD_F -421.599976
#define DEVICE_FAULT_SHORTVDD_RAW -32256
// Configuration Constants
#define MAX_CONVERSION_TIMEOUT 750
#define MAX_INITIALIZATION_RETRIES 3
#define INITIALIZATION_DELAY_MS 50
typedef uint8_t DeviceAddress[8];
class DallasTemperature {
public:
struct request_t {
bool result;
unsigned long timestamp;
operator bool() { return result; }
};
// Constructors
DallasTemperature();
DallasTemperature(OneWire*);
DallasTemperature(OneWire*, uint8_t);
// Setup & Configuration
void setOneWire(OneWire*);
void setPullupPin(uint8_t);
void begin(void);
bool verifyDeviceCount(void);
// Device Information
uint8_t getDeviceCount(void);
uint8_t getDS18Count(void);
bool validAddress(const uint8_t*);
bool validFamily(const uint8_t* deviceAddress);
bool getAddress(uint8_t*, uint8_t);
bool isConnected(const uint8_t*);
bool isConnected(const uint8_t*, uint8_t*);
// Scratchpad Operations
bool readScratchPad(const uint8_t*, uint8_t*);
void writeScratchPad(const uint8_t*, const uint8_t*);
bool readPowerSupply(const uint8_t* deviceAddress = nullptr);
// Resolution Control
uint8_t getResolution();
void setResolution(uint8_t);
uint8_t getResolution(const uint8_t*);
bool setResolution(const uint8_t*, uint8_t, bool skipGlobalBitResolutionCalculation = false);
// Conversion Configuration
void setWaitForConversion(bool);
bool getWaitForConversion(void);
void setCheckForConversion(bool);
bool getCheckForConversion(void);
// Temperature Operations
request_t requestTemperatures(void);
request_t requestTemperaturesByAddress(const uint8_t*);
request_t requestTemperaturesByIndex(uint8_t);
int32_t getTemp(const uint8_t*, byte retryCount = 0);
float getTempC(const uint8_t*, byte retryCount = 0);
float getTempF(const uint8_t*);
float getTempCByIndex(uint8_t);
float getTempFByIndex(uint8_t);
// Conversion Status
bool isParasitePowerMode(void);
bool isConversionComplete(void);
static uint16_t millisToWaitForConversion(uint8_t);
uint16_t millisToWaitForConversion();
// EEPROM Operations
bool saveScratchPadByIndex(uint8_t);
bool saveScratchPad(const uint8_t* = nullptr);
bool recallScratchPadByIndex(uint8_t);
bool recallScratchPad(const uint8_t* = nullptr);
void setAutoSaveScratchPad(bool);
bool getAutoSaveScratchPad(void);
#if REQUIRESALARMS
typedef void AlarmHandler(const uint8_t*);
void setHighAlarmTemp(const uint8_t*, int8_t);
void setLowAlarmTemp(const uint8_t*, int8_t);
int8_t getHighAlarmTemp(const uint8_t*);
int8_t getLowAlarmTemp(const uint8_t*);
void resetAlarmSearch(void);
bool alarmSearch(uint8_t*);
bool hasAlarm(const uint8_t*);
bool hasAlarm(void);
void processAlarms(void);
void setAlarmHandler(const AlarmHandler*);
bool hasAlarmHandler();
#endif
// User Data Operations
void setUserData(const uint8_t*, int16_t);
void setUserDataByIndex(uint8_t, int16_t);
int16_t getUserData(const uint8_t*);
int16_t getUserDataByIndex(uint8_t);
// Temperature Conversion Utilities
static float toFahrenheit(float);
static float toCelsius(float);
static float rawToCelsius(int32_t);
static int16_t celsiusToRaw(float);
static float rawToFahrenheit(int32_t);
#if REQUIRESNEW
void* operator new(unsigned int);
void operator delete(void*);
#endif
// Conversion Completion Methods
void blockTillConversionComplete(uint8_t);
void blockTillConversionComplete(uint8_t, unsigned long);
void blockTillConversionComplete(uint8_t, request_t);
private:
typedef uint8_t ScratchPad[9];
// Internal State
bool parasite;
bool useExternalPullup;
uint8_t pullupPin;
uint8_t bitResolution;
bool waitForConversion;
bool checkForConversion;
bool autoSaveScratchPad;
uint8_t devices;
uint8_t ds18Count;
OneWire* _wire;
// Internal Methods
int32_t calculateTemperature(const uint8_t*, uint8_t*);
bool isAllZeros(const uint8_t* const scratchPad, const size_t length = 9);
void activateExternalPullup(void);
void deactivateExternalPullup(void);
#if REQUIRESALARMS
uint8_t alarmSearchAddress[8];
int8_t alarmSearchJunction;
uint8_t alarmSearchExhausted;
AlarmHandler* _AlarmHandler;
#endif
};
#endif // DallasTemperature_h

View File

@ -0,0 +1,10 @@
MIT License
Copyright (c) 2024 Miles Burton
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,123 @@
# 🌡️ Arduino Temperature Control Library
[![Arduino CI](https://github.com/milesburton/Arduino-Temperature-Control-Library/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
[![Arduino-lint](https://github.com/milesburton/Arduino-Temperature-Control-Library/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/AS5600/actions/workflows/arduino-lint.yml)
[![JSON check](https://github.com/milesburton/Arduino-Temperature-Control-Library/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/AS5600/actions/workflows/jsoncheck.yml)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/milesburton/Arduino-Temperature-Control-Library/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/release/milesburton/Arduino-Temperature-Control-Library.svg?maxAge=3600)](https://github.com/milesburton/Arduino-Temperature-Control-Library/releases)
A robust and feature-complete Arduino library for Maxim Temperature Integrated Circuits.
## 📌 Supported Devices
- DS18B20
- DS18S20 (⚠️ Known issues with this series)
- DS1822
- DS1820
- MAX31820
- MAX31850
## 🚀 Installation
### Using Arduino IDE Library Manager (Recommended)
1. Open Arduino IDE
2. Go to Tools > Manage Libraries...
3. Search for "DallasTemperature"
4. Click Install
5. Also install the required "OneWire" library by Paul Stoffregen using the same method
### Manual Installation
1. Download the latest release from [GitHub releases](https://github.com/milesburton/Arduino-Temperature-Control-Library/releases)
2. In Arduino IDE, go to Sketch > Include Library > Add .ZIP Library...
3. Select the downloaded ZIP file
4. Repeat steps 1-3 for the required "OneWire" library
## 📝 Basic Usage
1. **Hardware Setup**
- Connect a 4k7 kΩ pull-up resistor between the 1-Wire data line and 5V power. Note this applies to the Arduino platform, for ESP32 and 8266 you'll need to adjust the resistor value accordingly.
- For DS18B20: Ground pins 1 and 3 (the centre pin is the data line)
- For reliable readings, see pull-up requirements in the [DS18B20 datasheet](https://datasheets.maximintegrated.com/en/ds/DS18B20.pdf) (page 7)
2. **Code Example**
```cpp
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is connected to GPIO 4
#define ONE_WIRE_BUS 4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
void setup(void) {
Serial.begin(9600);
sensors.begin();
}
void loop(void) {
sensors.requestTemperatures();
delay(750);
float tempC = sensors.getTempCByIndex(0);
Serial.print("Temperature: ");
Serial.print(tempC);
Serial.println("°C");
delay(1000);
}
```
## 🛠️ Advanced Features
- Multiple sensors on the same bus
- Temperature conversion by address (`getTempC(address)` and `getTempF(address)`)
- Asynchronous mode (added in v3.7.0)
- Configurable resolution
### Configuration Options
You can slim down the code by defining the following at the top of DallasTemperature.h:
```cpp
#define REQUIRESNEW // Use if you want to minimise code size
#define REQUIRESALARMS // Use if you need alarm functionality
```
## 📚 Additional Documentation
Visit our [Wiki](https://www.milesburton.com/w/index.php/Dallas_Temperature_Control_Library) for detailed documentation.
## 🔧 Library Development
If you want to contribute to the library development:
### Using Dev Container
The project includes a development container configuration for VS Code that provides a consistent development environment.
1. **Prerequisites**
- Visual Studio Code
- Docker
- VS Code Remote - Containers extension
2. **Development Commands**
Within the dev container, use:
- `arduino-build` - Compile the library and examples
- `arduino-test` - Run the test suite
- `arduino-build-test` - Complete build and test process
> Note: Currently compiling against arduino:avr:uno environment
## ✨ Credits
- Original development by Miles Burton <mail@milesburton.com>
- Multiple sensor support by Tim Newsome <nuisance@casualhacker.net>
- Address-based temperature reading by Guil Barros [gfbarros@bappos.com]
- Async mode by Rob Tillaart [rob.tillaart@gmail.com]
## 📄 License
MIT License | Copyright (c) 2025 Miles Burton
Full license text available in [LICENSE](LICENSE) file.

View File

@ -0,0 +1,19 @@
board_manager:
additional_urls: []
daemon:
port: "50051"
directories:
data: $GITHUB_WORKSPACE/.arduino15
downloads: $GITHUB_WORKSPACE/.arduino15/staging
user: $GITHUB_WORKSPACE/libraries
library:
enable_unsafe_install: true
logging:
file: ""
format: text
level: info
metrics:
addr: :9090
enabled: true
sketch:
always_export_binaries: false

View File

@ -0,0 +1,66 @@
#!/bin/bash
# Set error handling
set -e
# Function to display usage
show_usage() {
echo "Usage: ./build.sh [option]"
echo "Options:"
echo " build - Only compile library and examples"
echo " test - Only compile and run tests"
echo " all - Build everything and run tests (default)"
}
# Function to compile for a specific board
compile_for_board() {
local fqbn=$1
local sketch=$2
echo "📦 Compiling $sketch for $fqbn..."
arduino-cli compile --fqbn $fqbn "$sketch" --library .
}
# Function to build library and examples
build() {
echo "🔨 Building library and examples..."
# Compile all examples
echo "🔍 Compiling examples..."
for example in examples/*/*.ino; do
if [ -f "$example" ]; then
echo "Building example: $example"
compile_for_board "arduino:avr:uno" "$example"
fi
done
}
# Function to run tests
run_tests() {
echo "🧪 Running tests..."
for test in test/*/*.ino; do
if [ -f "$test" ]; then
echo "Running test: $test"
compile_for_board "arduino:avr:uno" "$test"
fi
done
}
# Main execution
case "${1:-all}" in
"build")
build
;;
"test")
run_tests
;;
"all")
build
run_tests
;;
*)
show_usage
exit 1
;;
esac
echo "✅ Process completed!"

View File

@ -0,0 +1,161 @@
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// arrays to hold device addresses
DeviceAddress insideThermometer, outsideThermometer;
void setup(void)
{
// start serial port
Serial.begin(9600);
Serial.println("Dallas Temperature IC Control Library Demo");
// Start up the library
sensors.begin();
// locate devices on the bus
Serial.print("Found ");
Serial.print(sensors.getDeviceCount(), DEC);
Serial.println(" devices.");
// search for devices on the bus and assign based on an index.
if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0");
if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1");
// show the addresses we found on the bus
Serial.print("Device 0 Address: ");
printAddress(insideThermometer);
Serial.println();
Serial.print("Device 0 Alarms: ");
printAlarms(insideThermometer);
Serial.println();
Serial.print("Device 1 Address: ");
printAddress(outsideThermometer);
Serial.println();
Serial.print("Device 1 Alarms: ");
printAlarms(outsideThermometer);
Serial.println();
Serial.println("Setting alarm temps...");
// alarm when temp is higher than 30C
sensors.setHighAlarmTemp(insideThermometer, 30);
// alarm when temp is lower than -10C
sensors.setLowAlarmTemp(insideThermometer, -10);
// alarm when temp is higher than 31C
sensors.setHighAlarmTemp(outsideThermometer, 31);
// alarn when temp is lower than 27C
sensors.setLowAlarmTemp(outsideThermometer, 27);
Serial.print("New Device 0 Alarms: ");
printAlarms(insideThermometer);
Serial.println();
Serial.print("New Device 1 Alarms: ");
printAlarms(outsideThermometer);
Serial.println();
}
// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
for (uint8_t i = 0; i < 8; i++)
{
if (deviceAddress[i] < 16) Serial.print("0");
Serial.print(deviceAddress[i], HEX);
}
}
// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress);
Serial.print("Temp C: ");
Serial.print(tempC);
Serial.print(" Temp F: ");
Serial.print(DallasTemperature::toFahrenheit(tempC));
}
void printAlarms(uint8_t deviceAddress[])
{
char temp;
temp = sensors.getHighAlarmTemp(deviceAddress);
Serial.print("High Alarm: ");
Serial.print(temp, DEC);
Serial.print("C/");
Serial.print(DallasTemperature::toFahrenheit(temp));
Serial.print("F | Low Alarm: ");
temp = sensors.getLowAlarmTemp(deviceAddress);
Serial.print(temp, DEC);
Serial.print("C/");
Serial.print(DallasTemperature::toFahrenheit(temp));
Serial.print("F");
}
// main function to print information about a device
void printData(DeviceAddress deviceAddress)
{
Serial.print("Device Address: ");
printAddress(deviceAddress);
Serial.print(" ");
printTemperature(deviceAddress);
Serial.println();
}
void checkAlarm(DeviceAddress deviceAddress)
{
if (sensors.hasAlarm(deviceAddress))
{
Serial.print("ALARM: ");
printData(deviceAddress);
}
}
void loop(void)
{
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
Serial.print("Requesting temperatures...");
sensors.requestTemperatures();
Serial.println("DONE");
// Method 1:
// check each address individually for an alarm condition
checkAlarm(insideThermometer);
checkAlarm(outsideThermometer);
/*
// Alternate method:
// Search the bus and iterate through addresses of devices with alarms
// space for the alarm device's address
DeviceAddress alarmAddr;
Serial.println("Searching for alarms...");
// resetAlarmSearch() must be called before calling alarmSearch()
sensors.resetAlarmSearch();
// alarmSearch() returns 0 when there are no devices with alarms
while (sensors.alarmSearch(alarmAddr))
{
Serial.print("ALARM: ");
printData(alarmAddr);
}
*/
}

View File

@ -0,0 +1,143 @@
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// arrays to hold device addresses
DeviceAddress insideThermometer, outsideThermometer;
// function that will be called when an alarm condition exists during DallasTemperatures::processAlarms();
void newAlarmHandler(const uint8_t* deviceAddress)
{
Serial.println("Alarm Handler Start");
printAlarmInfo(deviceAddress);
printTemp(deviceAddress);
Serial.println();
Serial.println("Alarm Handler Finish");
}
void printCurrentTemp(DeviceAddress deviceAddress)
{
printAddress(deviceAddress);
printTemp(deviceAddress);
Serial.println();
}
void printAddress(const DeviceAddress deviceAddress)
{
Serial.print("Address: ");
for (uint8_t i = 0; i < 8; i++)
{
if (deviceAddress[i] < 16) Serial.print("0");
Serial.print(deviceAddress[i], HEX);
}
Serial.print(" ");
}
void printTemp(const DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress);
if (tempC != DEVICE_DISCONNECTED_C)
{
Serial.print("Current Temp C: ");
Serial.print(tempC);
}
else Serial.print("DEVICE DISCONNECTED");
Serial.print(" ");
}
void printAlarmInfo(const DeviceAddress deviceAddress)
{
char temp;
printAddress(deviceAddress);
temp = sensors.getHighAlarmTemp(deviceAddress);
Serial.print("High Alarm: ");
Serial.print(temp, DEC);
Serial.print("C");
Serial.print(" Low Alarm: ");
temp = sensors.getLowAlarmTemp(deviceAddress);
Serial.print(temp, DEC);
Serial.print("C");
Serial.print(" ");
}
void setup(void)
{
// start serial port
Serial.begin(9600);
Serial.println("Dallas Temperature IC Control Library Demo");
// Start up the library
sensors.begin();
// locate devices on the bus
Serial.print("Found ");
Serial.print(sensors.getDeviceCount(), DEC);
Serial.println(" devices.");
// search for devices on the bus and assign based on an index
if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0");
if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1");
Serial.print("Device insideThermometer ");
printAlarmInfo(insideThermometer);
Serial.println();
Serial.print("Device outsideThermometer ");
printAlarmInfo(outsideThermometer);
Serial.println();
// set alarm ranges
Serial.println("Setting alarm temps...");
sensors.setHighAlarmTemp(insideThermometer, 26);
sensors.setLowAlarmTemp(insideThermometer, 22);
sensors.setHighAlarmTemp(outsideThermometer, 25);
sensors.setLowAlarmTemp(outsideThermometer, 21);
Serial.print("New insideThermometer ");
printAlarmInfo(insideThermometer);
Serial.println();
Serial.print("New outsideThermometer ");
printAlarmInfo(outsideThermometer);
Serial.println();
// attach alarm handler
sensors.setAlarmHandler(&newAlarmHandler);
}
void loop(void)
{
// ask the devices to measure the temperature
sensors.requestTemperatures();
// if an alarm condition exists as a result of the most recent
// requestTemperatures() request, it exists until the next time
// requestTemperatures() is called AND there isn't an alarm condition
// on the device
if (sensors.hasAlarm())
{
Serial.println("Oh noes! There is at least one alarm on the bus.");
}
// call alarm handler function defined by sensors.setAlarmHandler
// for each device reporting an alarm
sensors.processAlarms();
if (!sensors.hasAlarm())
{
// just print out the current temperature
printCurrentTemp(insideThermometer);
printCurrentTemp(outsideThermometer);
}
delay(1000);
}

View File

@ -0,0 +1,375 @@
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <OneWire.h>
#include <DallasTemperature.h>
/*
SETUP INSTRUCTIONS
1) Change WiFi SSID and Password:
const char* ssid = "YourSSID";
const char* password = "YourPassword";
2) Polling Interval (milliseconds):
const unsigned long READ_INTERVAL = 10000; // 10 seconds
3) Number of Readings (History Length):
const int HISTORY_LENGTH = 360; // 1 hour at 10-second intervals
*/
const char* ssid = "YourSSID";
const char* password = "YourPassword";
const int oneWireBus = 4;
const int MAX_SENSORS = 8;
const int HISTORY_LENGTH = 360;
const unsigned long READ_INTERVAL = 10000;
DeviceAddress sensorAddresses[MAX_SENSORS];
float tempHistory[MAX_SENSORS][HISTORY_LENGTH];
int historyIndex = 0;
int numberOfDevices = 0;
unsigned long lastReadTime = 0;
OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);
ESP8266WebServer server(80);
String getAddressString(DeviceAddress deviceAddress);
void handleRoot();
void handleSensorList();
void handleTemperature();
void handleHistory();
void updateHistory();
const char MAIN_page[] PROGMEM = R"=====(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
<title>Arduino Temperature Control Library - Sensor Data Graph</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1"></script>
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.1.2/dist/tailwind.min.css"
rel="stylesheet">
</head>
<body class="bg-gray-100 font-sans min-h-screen flex flex-col">
<div class="container mx-auto p-6 flex-grow">
<h1 class="text-2xl font-semibold text-gray-800 mb-4">
Arduino Temperature Control Library - Sensor Data
</h1>
<div class="flex mb-6">
<div class="cursor-pointer px-4 py-2 bg-blue-500 text-white rounded-lg shadow
hover:bg-blue-400 active:scale-95"
onclick="showTab('dashboard')">
Dashboard
</div>
<div class="cursor-pointer px-4 py-2 bg-gray-200 rounded-lg shadow
hover:bg-gray-300 active:scale-95 ml-4"
onclick="showTab('api')">
API Docs
</div>
<div class="cursor-pointer px-4 py-2 bg-gray-200 rounded-lg shadow
hover:bg-gray-300 active:scale-95 ml-4"
onclick="showTab('setup')">
Setup
</div>
</div>
<div id="dashboard" class="tab-content">
<button class="px-6 py-2 bg-green-500 text-white rounded-lg shadow
hover:bg-green-400 active:scale-95"
onclick="refreshData()">
Refresh Data
</button>
<div id="sensors" class="mt-6">
<div class="text-gray-600">Loading sensor data...</div>
</div>
</div>
<div id="api" class="tab-content hidden mt-8">
<h2 class="text-xl font-semibold text-gray-800 mb-4">API</h2>
<div class="bg-white p-6 rounded-lg shadow">
<div class="mb-4">
<span class="font-semibold text-blue-500">GET</span>
<a href="/temperature" class="text-blue-500 hover:underline">/temperature</a>
<pre class="bg-gray-100 p-4 rounded mt-2">
{
"sensors": [
{
"id": 0,
"address": "28FF457D1234AB12",
"celsius": 23.45,
"fahrenheit": 74.21
}
]
}
</pre>
</div>
<div class="mb-4">
<span class="font-semibold text-blue-500">GET</span>
<a href="/sensors" class="text-blue-500 hover:underline">/sensors</a>
<pre class="bg-gray-100 p-4 rounded mt-2">
{
"sensors": [
{
"id": 0,
"address": "28FF457D1234AB12"
}
]
}
</pre>
</div>
<div>
<span class="font-semibold text-blue-500">GET</span>
<a href="/history" class="text-blue-500 hover:underline">/history</a>
<pre class="bg-gray-100 p-4 rounded mt-2">
{
"interval_ms": 10000,
"sensors": [
{
"id": 0,
"address": "28FF457D1234AB12",
"history": [23.45, 23.50, 23.48]
}
]
}
</pre>
</div>
</div>
</div>
<div id="setup" class="tab-content hidden mt-8">
<h2 class="text-xl font-semibold text-gray-800 mb-4">Setup Instructions</h2>
<div class="bg-white p-6 rounded-lg shadow leading-relaxed">
<p class="mb-4">
Edit the .ino code to change SSID, password, read interval, and number
of stored readings (HISTORY_LENGTH).
</p>
</div>
</div>
</div>
<footer class="bg-gray-800 text-white p-4 mt-auto text-center">
<p>&copy; 2025 Miles Burton. All Rights Reserved.</p>
<p>
Licensed under the
<a href="https://opensource.org/licenses/MIT" class="text-blue-400 hover:underline">
MIT License
</a>.
</p>
</footer>
<script>
const showTab = (name) => {
document.querySelectorAll('.tab-content').forEach(c => c.classList.add('hidden'));
document.getElementById(name).classList.remove('hidden');
};
const buildSensorsHTML = (sensors) => {
return sensors.map(s => {
const chartId = "chart-" + s.id;
return `
<div class="bg-white p-6 rounded-lg shadow mb-6">
<div class="text-lg font-semibold text-blue-500">
${s.celsius.toFixed(2)}°C / ${s.fahrenheit.toFixed(2)}°F
</div>
<div class="text-sm text-gray-600 mt-2">
Sensor ID: ${s.id} (${s.address})
</div>
<div class="mt-4" style="height: 300px;">
<canvas id="${chartId}"></canvas>
</div>
</div>
`;
}).join('');
};
const drawChart = (chartId, dataPoints) => {
const ctx = document.getElementById(chartId);
if (!ctx) return;
new Chart(ctx, {
type: 'line',
data: {
labels: dataPoints.map(p => p.x),
datasets: [{
label: 'Temp (°C)',
data: dataPoints,
borderColor: 'red',
backgroundColor: 'rgba(255,0,0,0.1)',
borderWidth: 2,
pointRadius: 3,
lineTension: 0.1,
fill: true
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
tooltip: {
mode: 'index',
intersect: false,
callbacks: {
label: (ctx) => {
const t = ctx.parsed.x;
const d = new Date(t);
return `${ctx.dataset.label}: ${ctx.parsed.y.toFixed(2)}°C at ${d.toLocaleTimeString()}`;
}
}
}
},
interaction: { mode: 'nearest', intersect: true },
scales: {
x: {
type: 'linear',
position: 'bottom',
ticks: {
autoSkip: true,
maxTicksLimit: 10,
callback: (v) => new Date(v).toLocaleTimeString()
}
},
y: {
grid: { color: 'rgba(0,0,0,0.05)' }
}
}
}
});
};
const refreshData = async () => {
try {
const sensorsDiv = document.getElementById('sensors');
sensorsDiv.innerHTML = '<div class="text-gray-600">Loading sensor data...</div>';
const td = await fetch('/temperature');
const tempData = await td.json();
const hd = await fetch('/history');
const historyData = await hd.json();
sensorsDiv.innerHTML = buildSensorsHTML(tempData.sensors);
tempData.sensors.forEach(s => {
const chartId = "chart-" + s.id;
const sensorHist = historyData.sensors.find(h => h.id === s.id);
if (!sensorHist) return;
const total = sensorHist.history.length;
const arr = sensorHist.history.map((v, i) => {
return { x: Date.now() - (total - 1 - i)*10000, y: v };
});
drawChart(chartId, arr);
});
} catch(e) {
console.error(e);
document.getElementById('sensors').innerHTML =
'<div class="text-gray-600">Error loading data.</div>';
}
};
refreshData();
setInterval(refreshData, 30000);
</script>
</body>
</html>
)=====";
void setup() {
Serial.begin(115200);
sensors.begin();
for (int i = 0; i < MAX_SENSORS; i++) {
for (int j = 0; j < HISTORY_LENGTH; j++) {
tempHistory[i][j] = 0;
}
}
numberOfDevices = sensors.getDeviceCount();
if (numberOfDevices > MAX_SENSORS) {
numberOfDevices = MAX_SENSORS;
}
for (int i = 0; i < numberOfDevices; i++) {
sensors.getAddress(sensorAddresses[i], i);
}
sensors.setResolution(12);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
server.on("/", HTTP_GET, handleRoot);
server.on("/temperature", HTTP_GET, handleTemperature);
server.on("/sensors", HTTP_GET, handleSensorList);
server.on("/history", HTTP_GET, handleHistory);
server.begin();
}
void loop() {
server.handleClient();
unsigned long t = millis();
if (t - lastReadTime >= READ_INTERVAL) {
updateHistory();
lastReadTime = t;
}
}
void updateHistory() {
sensors.requestTemperatures();
for (int i = 0; i < numberOfDevices; i++) {
float tempC = sensors.getTempC(sensorAddresses[i]);
tempHistory[i][historyIndex] = tempC;
}
historyIndex = (historyIndex + 1) % HISTORY_LENGTH;
}
void handleRoot() {
server.send(200, "text/html", MAIN_page);
}
void handleSensorList() {
String json = "{\"sensors\":[";
for (int i = 0; i < numberOfDevices; i++) {
if (i > 0) json += ",";
json += "{\"id\":" + String(i) + ",\"address\":\"" + getAddressString(sensorAddresses[i]) + "\"}";
}
json += "]}";
server.send(200, "application/json", json);
}
void handleTemperature() {
sensors.requestTemperatures();
String json = "{\"sensors\":[";
for (int i = 0; i < numberOfDevices; i++) {
if (i > 0) json += ",";
float c = sensors.getTempC(sensorAddresses[i]);
float f = sensors.toFahrenheit(c);
json += "{\"id\":" + String(i) + ",\"address\":\"" + getAddressString(sensorAddresses[i]) + "\",";
json += "\"celsius\":" + String(c) + ",\"fahrenheit\":" + String(f) + "}";
}
json += "]}";
server.send(200, "application/json", json);
}
void handleHistory() {
String json = "{\"interval_ms\":" + String(READ_INTERVAL) + ",\"sensors\":[";
for (int i = 0; i < numberOfDevices; i++) {
if (i > 0) json += ",";
json += "{\"id\":" + String(i) + ",\"address\":\"" + getAddressString(sensorAddresses[i]) + "\",\"history\":[";
for (int j = 0; j < HISTORY_LENGTH; j++) {
int idx = (historyIndex - j + HISTORY_LENGTH) % HISTORY_LENGTH;
if (j > 0) json += ",";
json += String(tempHistory[i][idx]);
}
json += "]}";
}
json += "]}";
server.send(200, "application/json", json);
}
String getAddressString(DeviceAddress deviceAddress) {
String addr;
for (uint8_t i = 0; i < 8; i++) {
if (deviceAddress[i] < 16) addr += "0";
addr += String(deviceAddress[i], HEX);
}
return addr;
}

View File

@ -0,0 +1,61 @@
# 🌡️ Arduino Sketch: DS18B20 Sensor via Wi-Fi (REST Endpoints & Dashboard)
This **example Sketch** demonstrates how to use the [Arduino Temperature Control Library](https://github.com/milesburton/Arduino-Temperature-Control-Library) on an **ESP8266** or **ESP32** to read temperature data from **Maxim (Dallas) DS18B20** sensors. The Sketch publishes the readings via Wi-Fi in two ways:
1. **REST Endpoints** - Ideal for Node-RED, Home Assistant, or other automation platforms.
2. **A Human-Friendly Dashboard** - A simple web interface, powered by [Chart.js](https://www.chartjs.org/) and [Tailwind CSS](https://tailwindcss.com/), displaying current and historical temperatures.
---
## 🔎 Features
- Reads from one or more **DS18B20** temperature sensors
- Configurable **polling interval** (in milliseconds) and **history length** (number of readings)
- **Lightweight dashboard** that visualizes the last N readings
- **REST endpoints** for easy integration:
- `/temperature` - current readings
- `/sensors` - sensor addresses
- `/history` - historical data
---
## 📚 Potential Use Cases
- **Node-RED** automation flows: Perform regular HTTP GET requests against `/temperature` or `/history`
- **Home Assistant** integrations: Use built-in REST sensors to track temperature over time
- **Extensible to other sensor types** (humidity, light, pressure, etc.) by following the same approach
---
## 🛠️ Getting Started
1. **Clone or download** this repository
2. **Open the Sketch** (the `.ino` file) in the Arduino IDE (or other environment)
3. **Install dependencies**:
- [Arduino Temperature Control Library](https://github.com/milesburton/Arduino-Temperature-Control-Library)
- ESP8266 or ESP32 core for Arduino
4. **Set your Wi-Fi credentials** in the code:
```cpp
const char* ssid = "YourNetwork";
const char* password = "YourPassword";
```
5. **Adjust** the interval and history:
```cpp
// Configuration
const unsigned long READ_INTERVAL = 10000; // e.g. 10 seconds
const int HISTORY_LENGTH = 360; // 1 hour at 10-second intervals
```
6. **Connect** the DS18B20 sensor(s) to the ESP, using OneWire with a pull-up resistor
7. **Upload** the Sketch to your device
8. **Check** the serial monitor for the IP
9. **Navigate** to that IP in your browser to see the chart-based interface
---
## ❓ Questions & Support
- **Library Matters**: If you have issues with the **Arduino Temperature Control Library** itself, please open a ticket in the [official repository](https://github.com/milesburton/Arduino-Temperature-Control-Library/issues)
- **This Sketch**: For help customizing this example, dealing with Wi-Fi issues, or setting up the chart dashboard, and other device-specific tweaks, please visit the [Arduino Forum](https://forum.arduino.cc/). You will find many friendly developers there ready to help.
---
## 📜 License
This project is distributed under the [MIT License](https://opensource.org/licenses/MIT).
> We hope you find this Sketch useful for monitoring temperatures - both in a machine-readable (REST) and human-friendly (web dashboard) format. Happy hacking! 🚀

View File

@ -0,0 +1,35 @@
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into port 2 on the Arduino, while external pullup P-MOSFET gate into port 3
#define ONE_WIRE_BUS 2
#define ONE_WIRE_PULLUP 3
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire, ONE_WIRE_PULLUP);
void setup(void)
{
// start serial port
Serial.begin(9600);
Serial.println("Dallas Temperature IC Control Library Demo");
// Start up the library
sensors.begin();
}
void loop(void)
{
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
Serial.print("Requesting temperatures...");
sensors.requestTemperatures(); // Send the command to get temperatures
Serial.println("DONE");
for (int i = 0; i < sensors.getDeviceCount(); i++) {
Serial.println("Temperature for Device " + String(i) + " is: " + String(sensors.getTempCByIndex(i)));
}
}

View File

@ -0,0 +1,43 @@
#include <OneWire.h>
#include <DallasTemperature.h>
OneWire ds18x20[] = { 3, 7 };
const int oneWireCount = sizeof(ds18x20) / sizeof(OneWire);
DallasTemperature sensor[oneWireCount];
void setup(void) {
// start serial port
Serial.begin(9600);
Serial.println("Dallas Temperature Multiple Bus Control Library Simple Demo");
Serial.print("============Ready with ");
Serial.print(oneWireCount);
Serial.println(" Sensors================");
// Start up the library on all defined bus-wires
DeviceAddress deviceAddress;
for (int i = 0; i < oneWireCount; i++) {
sensor[i].setOneWire(&ds18x20[i]);
sensor[i].begin();
if (sensor[i].getAddress(deviceAddress, 0)) sensor[i].setResolution(deviceAddress, 12);
}
}
void loop(void) {
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
Serial.print("Requesting temperatures...");
for (int i = 0; i < oneWireCount; i++) {
sensor[i].requestTemperatures();
}
Serial.println("DONE");
delay(1000);
for (int i = 0; i < oneWireCount; i++) {
float temperature = sensor[i].getTempCByIndex(0);
Serial.print("Temperature for the sensor ");
Serial.print(i);
Serial.print(" is ");
Serial.println(temperature);
}
Serial.println();
}

View File

@ -0,0 +1,148 @@
// Include the libraries we need
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
#define TEMPERATURE_PRECISION 9
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// arrays to hold device addresses
DeviceAddress insideThermometer, outsideThermometer;
// Assign address manually. The addresses below will need to be changed
// to valid device addresses on your bus. Device address can be retrieved
// by using either oneWire.search(deviceAddress) or individually via
// sensors.getAddress(deviceAddress, index)
// DeviceAddress insideThermometer = { 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 };
// DeviceAddress outsideThermometer = { 0x28, 0x3F, 0x1C, 0x31, 0x2, 0x0, 0x0, 0x2 };
void setup(void)
{
// start serial port
Serial.begin(9600);
Serial.println("Dallas Temperature IC Control Library Demo");
// Start up the library
sensors.begin();
// locate devices on the bus
Serial.print("Locating devices...");
Serial.print("Found ");
Serial.print(sensors.getDeviceCount(), DEC);
Serial.println(" devices.");
// report parasite power requirements
Serial.print("Parasite power is: ");
if (sensors.isParasitePowerMode()) Serial.println("ON");
else Serial.println("OFF");
// Search for devices on the bus and assign based on an index. Ideally,
// you would do this to initially discover addresses on the bus and then
// use those addresses and manually assign them (see above) once you know
// the devices on your bus (and assuming they don't change).
//
// method 1: by index
if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0");
if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1");
// method 2: search()
// search() looks for the next device. Returns 1 if a new address has been
// returned. A zero might mean that the bus is shorted, there are no devices,
// or you have already retrieved all of them. It might be a good idea to
// check the CRC to make sure you didn't get garbage. The order is
// deterministic. You will always get the same devices in the same order
//
// Must be called before search()
//oneWire.reset_search();
// assigns the first address found to insideThermometer
//if (!oneWire.search(insideThermometer)) Serial.println("Unable to find address for insideThermometer");
// assigns the seconds address found to outsideThermometer
//if (!oneWire.search(outsideThermometer)) Serial.println("Unable to find address for outsideThermometer");
// show the addresses we found on the bus
Serial.print("Device 0 Address: ");
printAddress(insideThermometer);
Serial.println();
Serial.print("Device 1 Address: ");
printAddress(outsideThermometer);
Serial.println();
// set the resolution to 9 bit per device
sensors.setResolution(insideThermometer, TEMPERATURE_PRECISION);
sensors.setResolution(outsideThermometer, TEMPERATURE_PRECISION);
Serial.print("Device 0 Resolution: ");
Serial.print(sensors.getResolution(insideThermometer), DEC);
Serial.println();
Serial.print("Device 1 Resolution: ");
Serial.print(sensors.getResolution(outsideThermometer), DEC);
Serial.println();
}
// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
for (uint8_t i = 0; i < 8; i++)
{
// zero pad the address if necessary
if (deviceAddress[i] < 16) Serial.print("0");
Serial.print(deviceAddress[i], HEX);
}
}
// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress);
if (tempC == DEVICE_DISCONNECTED_C)
{
Serial.println("Error: Could not read temperature data");
return;
}
Serial.print("Temp C: ");
Serial.print(tempC);
Serial.print(" Temp F: ");
Serial.print(DallasTemperature::toFahrenheit(tempC));
}
// function to print a device's resolution
void printResolution(DeviceAddress deviceAddress)
{
Serial.print("Resolution: ");
Serial.print(sensors.getResolution(deviceAddress));
Serial.println();
}
// main function to print information about a device
void printData(DeviceAddress deviceAddress)
{
Serial.print("Device Address: ");
printAddress(deviceAddress);
Serial.print(" ");
printTemperature(deviceAddress);
Serial.println();
}
/*
Main function, calls the temperatures in a loop.
*/
void loop(void)
{
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
Serial.print("Requesting temperatures...");
sensors.requestTemperatures();
Serial.println("DONE");
// print the device information
printData(insideThermometer);
printData(outsideThermometer);
}

View File

@ -0,0 +1,106 @@
//
// FILE: SaveRecallScratchPad.ino
// AUTHOR: GitKomodo
// VERSION: 0.0.1
// PURPOSE: Show DallasTemperature lib functionality to
// save/recall ScratchPad values to/from EEPROM
//
// HISTORY:
// 0.0.1 = 2020-02-18 initial version
//
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress deviceAddress;
void setup()
{
Serial.begin(9600);
Serial.println(__FILE__);
Serial.println("Dallas Temperature Demo");
sensors.begin();
// Get ID of first sensor (at index 0)
sensors.getAddress(deviceAddress, 0);
// By default configuration and alarm/userdata registers are also saved to EEPROM
// when they're changed. Sensors recall these values automatically when powered up.
// Turn OFF automatic saving of configuration and alarm/userdata registers to EEPROM
sensors.setAutoSaveScratchPad(false);
// Change configuration and alarm/userdata registers on the scratchpad
int8_t resolution = 12;
sensors.setResolution(deviceAddress, resolution);
int16_t userdata = 24680;
sensors.setUserData(deviceAddress, userdata);
// Save configuration and alarm/userdata registers to EEPROM
sensors.saveScratchPad(deviceAddress);
// saveScratchPad can also be used without a parameter to save the configuration
// and alarm/userdata registers of ALL connected sensors to EEPROM:
//
// sensors.saveScratchPad();
//
// Or the configuration and alarm/userdata registers of a sensor can be saved to
// EEPROM by index:
//
// sensors.saveScratchPadByIndex(0);
// Print current values on the scratchpad (resolution = 12, userdata = 24680)
printValues();
}
void loop() {
// Change configuration and alarm/userdata registers on the scratchpad
int8_t resolution = 10;
sensors.setResolution(deviceAddress, resolution);
int16_t userdata = 12345;
sensors.setUserData(deviceAddress, userdata);
// Print current values on the scratchpad (resolution = 10, userdata = 12345)
printValues();
delay(2000);
// Recall configuration and alarm/userdata registers from EEPROM
sensors.recallScratchPad(deviceAddress);
// recallScratchPad can also be used without a parameter to recall the configuration
// and alarm/userdata registers of ALL connected sensors from EEPROM:
//
// sensors.recallScratchPad();
//
// Or the configuration and alarm/userdata registers of a sensor can be recalled
// from EEPROM by index:
//
// sensors.recallScratchPadByIndex(0);
// Print current values on the scratchpad (resolution = 12, userdata = 24680)
printValues();
delay(2000);
}
void printValues() {
Serial.println();
Serial.println("Current values on the scratchpad:");
Serial.print("Resolution:\t");
Serial.println(sensors.getResolution(deviceAddress));
Serial.print("User data:\t");
Serial.println(sensors.getUserData(deviceAddress));
}

View File

@ -0,0 +1,47 @@
//
// This sketch does not use the ALARM registers and uses those 2 bytes as a counter
// these 2 bytes can be used for other purposes as well e.g. last temperature or
// a specific ID.
//
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
int count = 0;
void setup(void)
{
// start serial port
Serial.begin(9600);
Serial.println("Dallas Temperature IC Control Library Demo");
// Start up the library
sensors.begin();
}
void loop(void)
{
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
Serial.print("Requesting temperatures...");
sensors.requestTemperatures(); // Send the command to get temperatures
Serial.println("DONE");
Serial.print("Temperature for the device 1 (index 0) is: ");
Serial.println(sensors.getTempCByIndex(0));
count++;
sensors.setUserDataByIndex(0, count);
int x = sensors.getUserDataByIndex(0);
Serial.println(count);
}

View File

@ -0,0 +1,52 @@
// Include the libraries we need
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
/*
* The setup function. We only start the sensors here
*/
void setup(void)
{
// start serial port
Serial.begin(9600);
Serial.println("Dallas Temperature IC Control Library Demo");
// Start up the library
sensors.begin();
}
/*
* Main function, get and show the temperature
*/
void loop(void)
{
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
Serial.print("Requesting temperatures...");
sensors.requestTemperatures(); // Send the command to get temperatures
Serial.println("DONE");
delay(1500);
// After we got the temperatures, we can print them here.
// We use the function ByIndex, and as an example get the temperature from the first sensor only.
float tempC = sensors.getTempCByIndex(0);
// Check if reading was successful
if (tempC != DEVICE_DISCONNECTED_C)
{
Serial.print("Temperature for the device 1 (index 0) is: ");
Serial.println(tempC);
}
else
{
Serial.println("Error: Could not read temperature data");
}
}

View File

@ -0,0 +1,122 @@
// Include the libraries we need
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// arrays to hold device address
DeviceAddress insideThermometer;
/*
* Setup function. Here we do the basics
*/
void setup(void)
{
// start serial port
Serial.begin(9600);
Serial.println("Dallas Temperature IC Control Library Demo");
// locate devices on the bus
Serial.print("Locating devices...");
sensors.begin();
Serial.print("Found ");
Serial.print(sensors.getDeviceCount(), DEC);
Serial.println(" devices.");
// report parasite power requirements
Serial.print("Parasite power is: ");
if (sensors.isParasitePowerMode()) Serial.println("ON");
else Serial.println("OFF");
// Assign address manually. The addresses below will need to be changed
// to valid device addresses on your bus. Device address can be retrieved
// by using either oneWire.search(deviceAddress) or individually via
// sensors.getAddress(deviceAddress, index)
// Note that you will need to use your specific address here
//insideThermometer = { 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 };
// Method 1:
// Search for devices on the bus and assign based on an index. Ideally,
// you would do this to initially discover addresses on the bus and then
// use those addresses and manually assign them (see above) once you know
// the devices on your bus (and assuming they don't change).
if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0");
// method 2: search()
// search() looks for the next device. Returns 1 if a new address has been
// returned. A zero might mean that the bus is shorted, there are no devices,
// or you have already retrieved all of them. It might be a good idea to
// check the CRC to make sure you didn't get garbage. The order is
// deterministic. You will always get the same devices in the same order
//
// Must be called before search()
//oneWire.reset_search();
// assigns the first address found to insideThermometer
//if (!oneWire.search(insideThermometer)) Serial.println("Unable to find address for insideThermometer");
// show the addresses we found on the bus
Serial.print("Device 0 Address: ");
printAddress(insideThermometer);
Serial.println();
// set the resolution to 9 bit (Each Dallas/Maxim device is capable of several different resolutions)
sensors.setResolution(insideThermometer, 9);
Serial.print("Device 0 Resolution: ");
Serial.print(sensors.getResolution(insideThermometer), DEC);
Serial.println();
}
// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress)
{
// method 1 - slower
//Serial.print("Temp C: ");
//Serial.print(sensors.getTempC(deviceAddress));
//Serial.print(" Temp F: ");
//Serial.print(sensors.getTempF(deviceAddress)); // Makes a second call to getTempC and then converts to Fahrenheit
// method 2 - faster
float tempC = sensors.getTempC(deviceAddress);
if (tempC == DEVICE_DISCONNECTED_C)
{
Serial.println("Error: Could not read temperature data");
return;
}
Serial.print("Temp C: ");
Serial.print(tempC);
Serial.print(" Temp F: ");
Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
}
/*
* Main function. It will request the tempC from the sensors and display on Serial.
*/
void loop(void)
{
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
Serial.print("Requesting temperatures...");
sensors.requestTemperatures(); // Send the command to get temperatures
Serial.println("DONE");
delay(1500);
// It responds almost immediately. Let's print out the data
printTemperature(insideThermometer); // Use a simple function to print out the data
}
// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
for (uint8_t i = 0; i < 8; i++)
{
if (deviceAddress[i] < 16) Serial.print("0");
Serial.print(deviceAddress[i], HEX);
}
}

View File

@ -0,0 +1,129 @@
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
#define TEMPERATURE_PRECISION 9 // Lower resolution
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
int numberOfDevices; // Number of temperature devices found
DeviceAddress tempDeviceAddress; // We'll use this variable to store a found device address
void setup(void)
{
// start serial port
Serial.begin(9600);
Serial.println("Dallas Temperature IC Control Library Demo");
// Start up the library
sensors.begin();
// Grab a count of devices on the wire
numberOfDevices = sensors.getDeviceCount();
// locate devices on the bus
Serial.print("Locating devices...");
Serial.print("Found ");
Serial.print(numberOfDevices, DEC);
Serial.println(" devices.");
// report parasite power requirements
Serial.print("Parasite power is: ");
if (sensors.isParasitePowerMode()) Serial.println("ON");
else Serial.println("OFF");
// Loop through each device, print out address
for (int i = 0; i < numberOfDevices; i++)
{
// Search the wire for address
if (sensors.getAddress(tempDeviceAddress, i))
{
Serial.print("Found device ");
Serial.print(i, DEC);
Serial.print(" with address: ");
printAddress(tempDeviceAddress);
Serial.println();
Serial.print("Setting resolution to ");
Serial.println(TEMPERATURE_PRECISION, DEC);
// set the resolution to TEMPERATURE_PRECISION bit (Each Dallas/Maxim device is capable of several different resolutions)
sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION);
Serial.print("Resolution actually set to: ");
Serial.print(sensors.getResolution(tempDeviceAddress), DEC);
Serial.println();
} else {
Serial.print("Found ghost device at ");
Serial.print(i, DEC);
Serial.print(" but could not detect address. Check power and cabling");
}
}
}
// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress)
{
// method 1 - slower
//Serial.print("Temp C: ");
//Serial.print(sensors.getTempC(deviceAddress));
//Serial.print(" Temp F: ");
//Serial.print(sensors.getTempF(deviceAddress)); // Makes a second call to getTempC and then converts to Fahrenheit
// method 2 - faster
float tempC = sensors.getTempC(deviceAddress);
if (tempC == DEVICE_DISCONNECTED_C)
{
Serial.println("Error: Could not read temperature data");
return;
}
Serial.print("Temp C: ");
Serial.print(tempC);
Serial.print(" Temp F: ");
Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
}
void loop(void)
{
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
Serial.print("Requesting temperatures...");
sensors.requestTemperatures(); // Send the command to get temperatures
Serial.println("DONE");
// Loop through each device, print out temperature data
for (int i = 0; i < numberOfDevices; i++)
{
// Search the wire for address
if (sensors.getAddress(tempDeviceAddress, i))
{
// Output the device ID
Serial.print("Temperature for device: ");
Serial.println(i, DEC);
// It responds almost immediately. Let's print out the data
printTemperature(tempDeviceAddress); // Use a simple function to print out the data
}
//else ghost device! Check your power requirements and cabling
}
}
// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
for (uint8_t i = 0; i < 8; i++)
{
if (deviceAddress[i] < 16) Serial.print("0");
Serial.print(deviceAddress[i], HEX);
}
}

View File

@ -0,0 +1,77 @@
//
// FILE: Timing.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.0.3
// PURPOSE: show performance of DallasTemperature lib
// compared to datasheet times per resolution
//
// HISTORY:
// 0.0.1 2017-07-25 initial version
// 0.0.2 2020-02-13 updates to work with current lib version
// 0.0.3 2020-02-20 added timing measurement of setResolution
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensor(&oneWire);
uint32_t start, stop;
void setup()
{
Serial.begin(9600);
Serial.println(__FILE__);
Serial.print("DallasTemperature Library version: ");
Serial.println(DALLASTEMPLIBVERSION);
sensor.begin();
}
void loop()
{
float ti[4] = { 94, 188, 375, 750 };
Serial.println();
Serial.println("Test takes about 30 seconds for 4 resolutions");
Serial.println("RES\tTIME\tACTUAL\tGAIN");
for (int r = 9; r < 13; r++)
{
start = micros();
sensor.setResolution(r);
Serial.println(micros() - start);
start = micros();
sensor.setResolution(r);
Serial.println(micros() - start);
uint32_t duration = run(20);
float avgDuration = duration / 20.0;
Serial.print(r);
Serial.print("\t");
Serial.print(ti[r - 9]);
Serial.print("\t");
Serial.print(avgDuration, 2);
Serial.print("\t");
Serial.print(avgDuration * 100 / ti[r - 9], 1);
Serial.println("%");
}
delay(1000);
}
uint32_t run(int runs)
{
float t;
start = millis();
for (int i = 0; i < runs; i++)
{
sensor.requestTemperatures();
t = sensor.getTempCByIndex(0);
}
stop = millis();
return stop - start;
}

View File

@ -0,0 +1,45 @@
//
// FILE: TwoPin_DS18B20.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.00
// PURPOSE: two pins for two sensors demo
// DATE: 2014-06-13
// URL: http://forum.arduino.cc/index.php?topic=216835.msg1764333#msg1764333
//
// Released to the public domain
//
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS_1 2
#define ONE_WIRE_BUS_2 4
OneWire oneWire_in(ONE_WIRE_BUS_1);
OneWire oneWire_out(ONE_WIRE_BUS_2);
DallasTemperature sensor_inhouse(&oneWire_in);
DallasTemperature sensor_outhouse(&oneWire_out);
void setup(void)
{
Serial.begin(9600);
Serial.println("Dallas Temperature Control Library Demo - TwoPin_DS18B20");
sensor_inhouse.begin();
sensor_outhouse.begin();
}
void loop(void)
{
Serial.print("Requesting temperatures...");
sensor_inhouse.requestTemperatures();
sensor_outhouse.requestTemperatures();
Serial.println(" done");
Serial.print("Inhouse: ");
Serial.println(sensor_inhouse.getTempCByIndex(0));
Serial.print("Outhouse: ");
Serial.println(sensor_outhouse.getTempCByIndex(0));
}

View File

@ -0,0 +1,115 @@
//
// FILE: UserDataDemo.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: use of alarm field as user identification demo
// DATE: 2019-12-23
// URL:
//
// Released to the public domain
//
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
uint8_t deviceCount = 0;
// Add 4 prepared sensors to the bus
// use the UserDataWriteBatch demo to prepare 4 different labeled sensors
struct
{
int id;
DeviceAddress addr;
} T[4];
float getTempByID(int id)
{
for (uint8_t index = 0; index < deviceCount; index++)
{
if (T[index].id == id)
{
return sensors.getTempC(T[index].addr);
}
}
return -999;
}
void printAddress(DeviceAddress deviceAddress)
{
for (uint8_t i = 0; i < 8; i++)
{
// zero pad the address if necessary
if (deviceAddress[i] < 16) Serial.print("0");
Serial.print(deviceAddress[i], HEX);
}
}
void setup(void)
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.println("Dallas Temperature Demo");
sensors.begin();
// count devices
deviceCount = sensors.getDeviceCount();
Serial.print("#devices: ");
Serial.println(deviceCount);
// Read ID's per sensor
// and put them in T array
for (uint8_t index = 0; index < deviceCount; index++)
{
// go through sensors
sensors.getAddress(T[index].addr, index);
T[index].id = sensors.getUserData(T[index].addr);
}
// Check all 4 sensors are set
for (uint8_t index = 0; index < deviceCount; index++)
{
Serial.println();
Serial.println(T[index].id);
printAddress(T[index].addr);
Serial.println();
}
Serial.println();
}
void loop(void)
{
Serial.println();
Serial.print(millis());
Serial.println("\treq temp");
sensors.requestTemperatures();
Serial.print(millis());
Serial.println("\tGet temp by address");
for (int i = 0; i < 4; i++)
{
Serial.print(millis());
Serial.print("\t temp:\t");
Serial.println(sensors.getTempC(T[i].addr));
}
Serial.print(millis());
Serial.println("\tGet temp by ID"); // assume ID = 0, 1, 2, 3
for (int id = 0; id < 4; id++)
{
Serial.print(millis());
Serial.print("\t temp:\t");
Serial.println(getTempByID(id));
}
delay(1000);
}
// END OF FILE

View File

@ -0,0 +1,107 @@
//
// FILE: UserDataWriteBatch.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: use of alarm field as user identification demo
// DATE: 2019-12-23
// URL:
//
// Released to the public domain
//
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
uint8_t deviceCount = 0;
void printAddress(DeviceAddress deviceAddress)
{
for (uint8_t i = 0; i < 8; i++)
{
// zero pad the address if necessary
if (deviceAddress[i] < 16) Serial.print("0");
Serial.print(deviceAddress[i], HEX);
}
}
void setup(void)
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.println("Write user ID to DS18B20\n");
sensors.begin();
// count devices
deviceCount = sensors.getDeviceCount();
Serial.print("#devices: ");
Serial.println(deviceCount);
Serial.println();
Serial.println("current ID's");
for (uint8_t index = 0; index < deviceCount; index++)
{
DeviceAddress t;
sensors.getAddress(t, index);
printAddress(t);
Serial.print("\t\tID: ");
int id = sensors.getUserData(t);
Serial.println(id);
}
Serial.println();
Serial.print("Enter ID for batch: ");
int c = 0;
int id = 0;
while (c != '\n' && c != '\r')
{
c = Serial.read();
switch (c)
{
case '0'...'9':
id *= 10;
id += (c - '0');
break;
default:
break;
}
}
Serial.println();
Serial.println(id);
Serial.println();
Serial.println("Start labeling ...");
for (uint8_t index = 0; index < deviceCount; index++)
{
Serial.print(".");
DeviceAddress t;
sensors.getAddress(t, index);
sensors.setUserData(t, id);
}
Serial.println();
Serial.println();
Serial.println("Show results ...");
for (uint8_t index = 0; index < deviceCount; index++)
{
DeviceAddress t;
sensors.getAddress(t, index);
printAddress(t);
Serial.print("\t\tID: ");
int id = sensors.getUserData(t);
Serial.println(id);
}
Serial.println("Done ...");
}
void loop(void) {}
// END OF FILE

View File

@ -0,0 +1,66 @@
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
void setup(void)
{
// start serial port
Serial.begin(115200);
Serial.println("Dallas Temperature Control Library - Async Demo");
Serial.println("\nDemo shows the difference in length of the call\n\n");
// Start up the library
sensors.begin();
}
void loop(void)
{
// Request temperature conversion (traditional)
Serial.println("Before blocking requestForConversion");
unsigned long start = millis();
sensors.requestTemperatures();
unsigned long stop = millis();
Serial.println("After blocking requestForConversion");
Serial.print("Time used: ");
Serial.println(stop - start);
// get temperature
Serial.print("Temperature: ");
Serial.println(sensors.getTempCByIndex(0));
Serial.println("\n");
// Request temperature conversion - non-blocking / async
Serial.println("Before NON-blocking/async requestForConversion");
start = millis();
sensors.setWaitForConversion(false); // makes it async
sensors.requestTemperatures();
sensors.setWaitForConversion(true);
stop = millis();
Serial.println("After NON-blocking/async requestForConversion");
Serial.print("Time used: ");
Serial.println(stop - start);
// 9 bit resolution by default
// Note the programmer is responsible for the right delay
// we could do something usefull here instead of the delay
int resolution = 9;
delay(750 / (1 << (12 - resolution)));
// get temperature
Serial.print("Temperature: ");
Serial.println(sensors.getTempCByIndex(0));
Serial.println("\n\n\n\n");
delay(1500);
}

View File

@ -0,0 +1,80 @@
//
// Sample of using Async reading of Dallas Temperature Sensors
//
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
DeviceAddress tempDeviceAddress;
int resolution = 12;
unsigned long lastTempRequest = 0;
int delayInMillis = 0;
float temperature = 0.0;
int idle = 0;
//
// SETUP
//
void setup(void)
{
Serial.begin(115200);
Serial.println("Dallas Temperature Control Library - Async Demo");
Serial.print("Library Version: ");
Serial.println(DALLASTEMPLIBVERSION);
Serial.println("\n");
sensors.begin();
sensors.getAddress(tempDeviceAddress, 0);
sensors.setResolution(tempDeviceAddress, resolution);
sensors.setWaitForConversion(false);
sensors.requestTemperatures();
delayInMillis = 750 / (1 << (12 - resolution));
lastTempRequest = millis();
pinMode(13, OUTPUT);
}
void loop(void)
{
if (millis() - lastTempRequest >= delayInMillis) // waited long enough??
{
digitalWrite(13, LOW);
Serial.print(" Temperature: ");
temperature = sensors.getTempCByIndex(0);
Serial.println(temperature, resolution - 8);
Serial.print(" Resolution: ");
Serial.println(resolution);
Serial.print("Idle counter: ");
Serial.println(idle);
Serial.println();
idle = 0;
// immediately after fetching the temperature we request a new sample
// in the async modus
// for the demo we let the resolution change to show differences
resolution++;
if (resolution > 12) resolution = 9;
sensors.setResolution(tempDeviceAddress, resolution);
sensors.requestTemperatures();
delayInMillis = 750 / (1 << (12 - resolution));
lastTempRequest = millis();
}
digitalWrite(13, HIGH);
// we can do usefull things here
// for the demo we just count the idle time in millis
delay(1);
idle++;
}

View File

@ -0,0 +1,67 @@
//
// FILE: oneWireSearch.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.02
// PURPOSE: scan for 1-Wire devices + code snippet generator
// DATE: 2015-june-30
// URL: http://forum.arduino.cc/index.php?topic=333923
//
// inspired by http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html
//
// Released to the public domain
//
// 0.1.00 initial version
// 0.1.01 first published version
// 0.1.02 small output changes
#include <OneWire.h>
void setup()
{
Serial.begin(115200);
Serial.println("//\n// Start oneWireSearch.ino \n//");
for (uint8_t pin = 2; pin < 13; pin++)
{
findDevices(pin);
}
Serial.println("\n//\n// End oneWireSearch.ino \n//");
}
void loop()
{
}
uint8_t findDevices(int pin)
{
OneWire ow(pin);
uint8_t address[8];
uint8_t count = 0;
if (ow.search(address))
{
Serial.print("\nuint8_t pin");
Serial.print(pin, DEC);
Serial.println("[][8] = {");
do {
count++;
Serial.println(" {");
for (uint8_t i = 0; i < 8; i++)
{
Serial.print("0x");
if (address[i] < 0x10) Serial.print("0");
Serial.print(address[i], HEX);
if (i < 7) Serial.print(", ");
}
Serial.println(" },");
} while (ow.search(address));
Serial.println("};");
Serial.print("// nr devices found: ");
Serial.println(count);
}
return count;
}

View File

@ -0,0 +1,92 @@
//
// FILE: readPowerSupply.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: demo
// DATE: 2020-02-10
//
// Released to the public domain
//
// Include the libraries we need
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// arrays to hold device addresses
DeviceAddress insideThermometer, outsideThermometer;
// Assign address manually. The addresses below will beed to be changed
// to valid device addresses on your bus. Device address can be retrieved
// by using either oneWire.search(deviceAddress) or individually via
// sensors.getAddress(deviceAddress, index)
// DeviceAddress insideThermometer = { 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 };
// DeviceAddress outsideThermometer = { 0x28, 0x3F, 0x1C, 0x31, 0x2, 0x0, 0x0, 0x2 };
int devCount = 0;
/*
* The setup function. We only start the sensors here
*/
void setup(void)
{
Serial.begin(115200);
Serial.println("Arduino Temperature Control Library Demo - readPowerSupply");
sensors.begin();
devCount = sensors.getDeviceCount();
Serial.print("#devices: ");
Serial.println(devCount);
// report parasite power requirements
Serial.print("Parasite power is: ");
if (sensors.readPowerSupply()) Serial.println("ON"); // no address means "scan all devices for parasite mode"
else Serial.println("OFF");
// Search for devices on the bus and assign based on an index.
if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0");
if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1");
// show the addresses we found on the bus
Serial.print("Device 0 Address: ");
printAddress(insideThermometer);
Serial.println();
Serial.print("Power = parasite: ");
Serial.println(sensors.readPowerSupply(insideThermometer));
Serial.println();
Serial.println();
Serial.print("Device 1 Address: ");
printAddress(outsideThermometer);
Serial.println();
Serial.print("Power = parasite: ");
Serial.println(sensors.readPowerSupply(outsideThermometer));
Serial.println();
Serial.println();
}
// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
for (uint8_t i = 0; i < 8; i++)
{
// zero pad the address if necessary
if (deviceAddress[i] < 0x10) Serial.print("0");
Serial.print(deviceAddress[i], HEX);
}
}
// empty on purpose
void loop(void)
{
}
// END OF FILE

View File

@ -0,0 +1,87 @@
#######################################
# Syntax Coloring Map For DallasTemperature
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
DallasTemperature KEYWORD1
OneWire KEYWORD1
AlarmHandler KEYWORD1
DeviceAddress KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
setOneWire KEYWORD2
setPullupPin KEYWORD2
setResolution KEYWORD2
getResolution KEYWORD2
getTemp KEYWORD2
getTempC KEYWORD2
toFahrenheit KEYWORD2
getTempF KEYWORD2
getTempCByIndex KEYWORD2
getTempFByIndex KEYWORD2
rawToCelsius KEYWORD2
rawToFahrenheit KEYWORD2
setWaitForConversion KEYWORD2
getWaitForConversion KEYWORD2
requestTemperatures KEYWORD2
requestTemperaturesByAddress KEYWORD2
requestTemperaturesByIndex KEYWORD2
setCheckForConversion KEYWORD2
getCheckForConversion KEYWORD2
isConversionComplete KEYWORD2
millisToWaitForConversion KEYWORD2
isParasitePowerMode KEYWORD2
begin KEYWORD2
getDeviceCount KEYWORD2
getDS18Count KEYWORD2
getAddress KEYWORD2
validAddress KEYWORD2
validFamily KEYWORD2
isConnected KEYWORD2
readScratchPad KEYWORD2
writeScratchPad KEYWORD2
readPowerSupply KEYWORD2
saveScratchPadByIndex KEYWORD2
saveScratchPad KEYWORD2
recallScratchPadByIndex KEYWORD2
recallScratchPad KEYWORD2
setAutoSaveScratchPad KEYWORD2
getAutoSaveScratchPad KEYWORD2
setHighAlarmTemp KEYWORD2
setLowAlarmTemp KEYWORD2
getHighAlarmTemp KEYWORD2
getLowAlarmTemp KEYWORD2
resetAlarmSearch KEYWORD2
alarmSearch KEYWORD2
hasAlarm KEYWORD2
toCelsius KEYWORD2
processAlarms KEYWORD2
setAlarmHandler KEYWORD2
hasAlarmHandler KEYWORD2
setUserData KEYWORD2
setUserDataByIndex KEYWORD2
getUserData KEYWORD2
getUserDataByIndex KEYWORD2
calculateTemperature KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
DEVICE_DISCONNECTED_C LITERAL1
DEVICE_DISCONNECTED_F LITERAL1
DEVICE_DISCONNECTED_RAW LITERAL1
DEVICE_FAULT_OPEN_C LITERAL1
DEVICE_FAULT_OPEN_F LITERAL1
DEVICE_FAULT_OPEN_RAW LITERAL1
DEVICE_FAULT_SHORTGND_C LITERAL1
DEVICE_FAULT_SHORTGND_F LITERAL1
DEVICE_FAULT_SHORTGND_RAW LITERAL1
DEVICE_FAULT_SHORTVDD_C LITERAL1
DEVICE_FAULT_SHORTVDD_F LITERAL1
DEVICE_FAULT_SHORTVDD_RAW LITERAL1

View File

@ -0,0 +1,38 @@
{
"name": "DallasTemperature",
"keywords": "onewire, 1-wire, bus, sensor, temperature, DS18B20, DS18S20, DS1822, DS1820, MAX31850",
"description": "Arduino Library for Dallas Temperature ICs (DS18B20, DS18S20, DS1822, DS1820, MAX31850)",
"repository":
{
"type": "git",
"url": "https://github.com/milesburton/Arduino-Temperature-Control-Library.git"
},
"authors":
[
{
"name": "Miles Burton",
"email": "mail@milesburton.com",
"url": "http://www.milesburton.com",
"maintainer": true
},
{
"name": "Tim Newsome",
"email": "nuisance@casualhacker.net"
},
{
"name": "Guil Barros",
"email": "gfbarros@bappos.com"
},
{
"name": "Rob Tillaart",
"email": "rob.tillaart@gmail.com"
}
],
"dependencies":
{
"paulstoffregen/OneWire": "^2.3.5"
},
"version": "4.0.3",
"frameworks": "arduino",
"platforms": "*"
}

View File

@ -0,0 +1,9 @@
name=DallasTemperature
version=4.0.3
author=Miles Burton <mail@milesburton.com>, Tim Newsome <nuisance@casualhacker.net>, Guil Barros <gfbarros@bappos.com>, Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Miles Burton <mail@milesburton.com>
sentence=Arduino library for Dallas/Maxim temperature ICs
paragraph=Support for DS18B20 and other Dallas/Maxim 1-Wire temperature sensors
category=Sensors
url=https://github.com/milesburton/Arduino-Temperature-Control-Library
architectures=*

View File

@ -0,0 +1,22 @@
// DISABLED AS NOT ALL STD LIBRARIES ARE MOCKED / INCLUDEABLE
// #include <DallasTemperature.h>
// #include <ArduinoUnitTests.h>
// unittest(test_initialization) {
// OneWire oneWire(2); // Simulate OneWire on pin 2
// DallasTemperature sensors(&oneWire);
// sensors.begin();
// assertEqual(0, sensors.getDeviceCount());
// }
// unittest(test_parasite_power_mode) {
// OneWire oneWire(2);
// DallasTemperature sensors(&oneWire);
// sensors.begin();
// assertFalse(sensors.isParasitePowerMode());
// }
// --------

View File

@ -0,0 +1,8 @@
#include <ArduinoUnitTests.h>
#include <Arduino.h>
unittest(basic_sanity_check) {
assertTrue(true);
}
unittest_main()

View File

@ -0,0 +1,81 @@
// DISABLED AS NOT ALL STD LIBRARIES ARE MOCKED / INCLUDEABLE
//
// FILE: unit_test_001.cpp
// AUTHOR: Miles Burton / Rob Tillaart
// DATE: 2021-01-10
// PURPOSE: unit tests for the Arduino-Temperature-Control-Library
// https://github.com/MilesBurton/Arduino-Temperature-Control-Library
//
// #include <ArduinoUnitTests.h>
// #include <Arduino.h>
// #include <OneWire.h>
// #include <DallasTemperature.h>
// // Mock pin for testing
// #define ONE_WIRE_BUS 2
// unittest_setup() {
// fprintf(stderr, "VERSION: %s\n", DALLASTEMPLIBVERSION);
// }
// unittest_teardown() {
// fprintf(stderr, "\n");
// }
// // Test constants defined in the library
// unittest(test_models) {
// assertEqual(0x10, DS18S20MODEL);
// assertEqual(0x28, DS18B20MODEL);
// assertEqual(0x22, DS1822MODEL);
// assertEqual(0x3B, DS1825MODEL);
// assertEqual(0x42, DS28EA00MODEL);
// }
// // Test error codes defined in the library
// unittest(test_error_code) {
// assertEqual(DEVICE_DISCONNECTED_C, -127);
// assertEqual(DEVICE_DISCONNECTED_F, -196.6);
// assertEqual(DEVICE_DISCONNECTED_RAW, -7040);
// assertEqual(DEVICE_FAULT_OPEN_C, -254);
// assertEqualFloat(DEVICE_FAULT_OPEN_F, -425.2, 0.1);
// assertEqual(DEVICE_FAULT_OPEN_RAW, -32512);
// assertEqual(DEVICE_FAULT_SHORTGND_C, -253);
// assertEqualFloat(DEVICE_FAULT_SHORTGND_F, -423.4, 0.1);
// assertEqual(DEVICE_FAULT_SHORTGND_RAW, -32384);
// assertEqual(DEVICE_FAULT_SHORTVDD_C, -252);
// assertEqualFloat(DEVICE_FAULT_SHORTVDD_F, -421.6, 0.1);
// assertEqual(DEVICE_FAULT_SHORTVDD_RAW, -32256);
// }
// // Test basic initialization and functionality of the DallasTemperature library
// unittest(test_initialization) {
// OneWire oneWire(ONE_WIRE_BUS);
// DallasTemperature sensors(&oneWire);
// sensors.begin();
// // Initially, there should be no devices detected
// assertEqual(0, sensors.getDeviceCount());
// assertFalse(sensors.isParasitePowerMode());
// }
// // Simulate a basic temperature read (mocked)
// unittest(test_temperature_read) {
// OneWire oneWire(ONE_WIRE_BUS);
// DallasTemperature sensors(&oneWire);
// sensors.begin();
// // Mock reading temperature
// float tempC = sensors.getTempCByIndex(0);
// assertEqual(DEVICE_DISCONNECTED_C, tempC); // Simulated no device connected
// }
// unittest_main()
// --------