DS18B20 удобный цифровой термосенсор. В промышленной эксплуатации обычно используются датчики в водонепроницаемой капсуле из нержавеющей стали. Характеристики датчиков:
- Диапазон измеряемых температур -55 ° ~ +125 °.
- Напряжение питания 3.0V ~ 5.5V
- Низкая стоимость (~1,3 USD)
- Однопроводной интерфейс 1Wire.
- Точность ±0.5°C в диапазоне от -10°C до +85°C.
- Программируемое разрешение от 9 Bits до 12 Bits.
- Уникальный 64 битный серийный номер у каждого датчика исключающий конфликты на одной шине.
- Можно напрямую подключать к микроконтроллерам без дополнительных конвертеров.

Выходы у датчика в нержавейке : Red (VCC), yellow (DATA), black (GND)
Схема подключения крайне простая. Датчик подключается к цифровому входу через резистор 4,7 К на +питания.

Я приобретал датчики в металлических водонепроницаемых капсулах оптом, 10 шт. у этого продавца на Aliexpress. Цена ~1,3 USD за шт. с оперативной доставкой в Россию. Если время доставки не критично, то датчик можно заказать по цене порядка 1 USD у множества продавцов на Aliexpress с бесплатной доставкой.
Получение адресов датчиков DS18B20
#include <OneWire.h>
OneWire ds(15); //data wire connected to GPIO15
void setup(void) {
Serial.begin(9600);
}
void loop(void) {
byte i;
byte addr[8];
if (!ds.search(addr)) {
Serial.println(" No more addresses.");
Serial.println();
ds.reset_search();
delay(250);
return;
}
Serial.print(" ROM =");
for (i = 0; i < 8; i++) {
Serial.write(' ');
Serial.print(addr[i], HEX);
}
}Опрос датчиков DS18B20
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is connected to GPIO15
#define ONE_WIRE_BUS 15
// Setup a oneWire instance to communicate with a OneWire device
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature sensor
DallasTemperature sensors(&oneWire);
DeviceAddress sensor1 = { 0x28, 0xB1, 0x13, 0x46, 0x92, 0xD, 0x2, 0xA7 };
void setup(void)
{
Serial.begin(115200);
sensors.begin();
}
void loop(void)
{
//Serial.print("Requesting temperatures...");
sensors.requestTemperatures(); // Send the command to get temperatures
//Serial.println("DONE");
Serial.print("Sensor 1: ");
Serial.print(String(sensors.getTempC(sensor1)) + " C, ");
Serial.println(String(sensors.getTempF(sensor1)) + " F");
// tempSensor.requestTemperaturesByIndex(0);
//Get single sensor value
Serial.print("Temperature: ");
Serial.print(sensors.getTempCByIndex(0));
Serial.print(" C, ");
Serial.print(sensors.getTempFByIndex(0));
Serial.println(" F");
delay(1000);
}Если на одной шине висит несколько сенсоров, код будет несколько посложнее. В данном случае тестируется два DS18B20 датчиков подключенных к GPIO32 микроконтроллера ESP32.
#include "OneWire_Scanner.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#define OneWire_PIN 32
OneWire ds(OneWire_PIN);
// Pass our oneWire reference to Dallas Temperature sensor
DallasTemperature sensors(&ds);
// count of DS18xxx Family devices on bus
uint8_t devices = 0; // Reset the number of devices when we enumerate wire devices
uint8_t ds18Count = 0; // Reset number of DS18xxx Family devices
void setup()
{
sensors.begin();
ScanOneWireDevicesAndShowTemp();
// выведем общее количество найденных устройств
Serial.println("Found [" + String(ds18Count) + "] DS18XXX sensors of [" + String(devices) + "] iWare devices.");
//Serial.print(sensors.getDeviceCount(), DEC);
//Serial.print(sensors.getDS18Count(), DEC);
// проверяем способ подключения питания
Serial.print("Parasite power is: ");
Serial.println(sensors.isParasitePowerMode() ? "ON" : "OFF");
}
void loop()
{
ScanOneWireDevicesAndShowTemp();
delay(1000);
}
String getSensorModel(uint8_t modelByte)
{
//deviceAddress[0]
String res = "";
switch (modelByte)
{
case DS18S20MODEL:
return "DS18S20";
case DS18B20MODEL:
return "DS18B20";
case DS1822MODEL:
return "DS1822";
case DS1825MODEL:
return "DS1825";
case DS28EA00MODEL:
return "DS28EA00";
default:
return "Unknown";
}
}
void ScanOneWireDevicesAndShowTemp()
{
DeviceAddress deviceAddress;
while (ds.search(deviceAddress))
{
if (sensors.validAddress(deviceAddress))
{
//bitResolution = max(bitResolution, sensors.getResolution(deviceAddress));
devices++;
if (sensors.validFamily(deviceAddress))
{
sensors.requestTemperatures(); // Send the command to get temperatures
Serial.print("Sensor ");
printAddress(deviceAddress);
Serial.println(". Temp: " + String(sensors.getTempC(deviceAddress)) + " oC with resolution " + String(sensors.getResolution(deviceAddress)) + " bit. Sensor " + getSensorModel(deviceAddress[0]) + ".");
ds18Count++;
}
}
}
}
void printAddress(DeviceAddress deviceAddress)
{
for (uint8_t i = 0; i < 8; i++)
{
if (deviceAddress[i] < 16) Serial.print("0");
Serial.print(deviceAddress[i], HEX);
}
}Результат работы кода опроса датчиков DS18B20:
11:42:18.863 -> Sensor 28B11346920D02A7. Temp: 24.19 oC with resolution 12 bit. Sensor DS18B20. 11:42:18.999 -> Sensor 28FF6C7997090341. Temp: 28.12 oC with resolution 12 bit. Sensor DS18B20. 11:42:20.022 -> Found [2] DS18XXX sensors of [2] iWare devices. 11:42:20.022 -> Parasite power is: OFF
Разброс показаний датчиков DS18B20
Не смотря на то, что датчики цифровые — они не калиброванные. Для примера снятие данных с 12 датчиков DS18B20 в течении 8 часов.

Как видно по графикам, разброс в показаниях составляет почти 2 градуса. Я не нашел в командах DS18B20 вариантов прописать калибровочные коэффициенты непосредственно в датчик, так что придется поправлять значения «снаружи».
Полезные ссылки
- ESP32 with Multiple DS18B20 Temperature Sensors.
- ESP32 Arduino: Getting temperature from DS18B20 sensor.
- ESP32 Arduino DS18B20 Temperature sensor.
- ESP32 and DS18B20 temperature sensor example.
- Герметичный датчик температуры DS18B20.
- DS18B20 1-Wire calibration with Arduino: Finally nailed it!
- Calibrating DS18B20 1-Wire Sensors with Ice & Steam point measurement