Почему DS18B20 — лучший термометр для Arduino
DS18B20 — цифровой датчик температуры: в отличие от аналоговых (термисторов, LM35) он сам измеряет и отдаёт готовое число по шине 1-Wire. Точность ±0.5 °C в диапазоне −10…+85 °C, разрешение до 0.0625 °C (12 бит), диапазон −55…+125 °C. Есть в металлическом герметичном корпусе — можно мерить воду и почву.
Главная фича — 1-Wire: несколько датчиков на одном проводе, каждый с уникальным 64-битным адресом. Десяток термометров по дому — и один пин Arduino.
Подключение
Три вывода: VCC (3–5.5 В), GND, DQ (данные). Обязательна подтяжка DQ к VCC резистором 4.7 кОм — без неё шина не работает:
Arduino 5V ── VCC ──┬──[4.7 кОм]──┬── DQ ── Arduino D2
│ │
GND DQ других датчиков на том же проводе
Датчики цепляются параллельно — один резистор на всю шину, не на каждый.
Библиотеки и первый код
Ставим OneWire (Jim Studt/Paul Stoffregen) и DallasTemperature (Miles Burton):
#include <OneWire.h>
#include <DallasTemperature.h>
OneWire oneWire(2); // шина на пине 2
DallasTemperature sensors(&oneWire);
void setup() {
Serial.begin(9600);
sensors.begin();
Serial.print("найдено датчиков: ");
Serial.println(sensors.getDeviceCount());
}
void loop() {
sensors.requestTemperatures(); // команда всей шине
float t = sensors.getTempCByIndex(0); // по индексу — первый найденный
if (t != DEVICE_DISCONNECTED_C) {
Serial.print("T: "); Serial.println(t);
}
delay(1000);
}
requestTemperatures запускает измерение у всех датчиков на шине сразу — они измеряют параллельно ~750 мс на 12 бит.
Несколько датчиков по адресам
Каждый DS18B20 имеет прошитый адрес — обращение по индексу работает, но порядок не гарантирован после перезагрузки. Правильно — по адресу:
DeviceAddress addr1 = {0x28, 0xFF, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC};
float t = sensors.getTempC(addr1); // конкретный датчик
Адреса узнают скетчем-сканером из примеров OneWire или:
DeviceAddress addr;
for (int i = 0; i < sensors.getDeviceCount(); ++i) {
sensors.getAddress(addr, i);
// распечатать addr в hex и записать для скетча
}
Разрешение и точность
По умолчанию 12 бит (0.0625 °C). Можно снизить ради скорости:
sensors.setResolution(9); // 9 бит = 0.5 °C, измерение ~94 мс
// 10 бит — 0.25 °C / ~188 мс
// 11 бит — 0.125 °C / ~375 мс
// 12 бит — 0.0625 °C / ~750 мс
При опросе важно: requestTemperatures стартует измерение, а getTempC читает готовое. Между ними должно пройти время на измерение — иначе старое значение или DEVICE_DISCONNECTED.
Паразитное питание и режимы
DS18B20 умеет работать по двум проводам — паразитное питание от линии данных (VCC на GND). Не рекомендую: меньше ток на измерение, нестабильность при длинных линиях. Подключайте тремя проводами — надёжнее.
setWaitForConversion(false) позволяет не блокировать loop на время измерения:
sensors.setWaitForConversion(false);
sensors.requestTemperatures();
// через 800 мс (по millis) читаем
if (millis() - convStart >= 800) {
float t = sensors.getTempCByIndex(0);
}
Практический проект: мультизонный термометр
OneWire oneWire(2);
DallasTemperature sensors(&oneWire);
DeviceAddress inside = {0x28, 0xAA, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
DeviceAddress outside = {0x28, 0xBB, 0x77, 0x88, 0x99, 0x00, 0x11, 0x22};
void loop() {
sensors.requestTemperatures();
delay(800);
Serial.print("дома: "); Serial.println(sensors.getTempC(inside));
Serial.print("улица: "); Serial.println(sensors.getTempC(outside));
delay(5000);
}
Типичные проблемы
getDeviceCount() = 0: нет резистора 4.7 кОм или он не туда; DQ на другом пине; датчик мёртвый/перепутаны выводы (смотрите маркировку — у waterproof-версий цвета проводов).- 85 °C всегда: датчик в режиме "сброса" — возвращает стартовое значение; не хватило времени на конверсию.
- −127 °C: DEVICE_DISCONNECTED — потерян контакт или нет подтяжки.
- Пляшут значения на длинной линии: провод >10 м — уменьшите резистор до 2.2 кОм, экранируйте, добавьте конденсатор.
- Перепутаны адреса: распечатайте адреса сканером и задайте явно.
Итог
DS18B20 — готовый точный термометр на одном проводе: резистор 4.7 кОм, OneWire + DallasTemperature, опрос по адресу для нескольких датчиков. Три грабли: подтяжка обязательна, дайте 750 мс на измерение, −127 значит «нет связи». Дальше — теплица, аквариум, котёл, метеостанция.
Полный пример: несколько датчиков
#include <OneWire.h>
#include <DallasTemperature.h>
OneWire oneWire(4);
DallasTemperature sensors(&oneWire);
void setup() {
Serial.begin(9600);
sensors.begin();
Serial.printf("найдено датчиков: %d\n", sensors.getDeviceCount());
}
void loop() {
sensors.requestTemperatures(); // опросить все
for (int i = 0; i < sensors.getDeviceCount(); ++i) {
float t = sensors.getTempCByIndex(i);
Serial.printf("датчик %d: %.2f°C\n", i, t);
}
delay(1000);
}
Одна шина — много датчиков: библиотека сама различает их по уникальным 64-битным адресам.
По адресу: надёжнее, чем по индексу
getTempCByIndex возвращает датчики в порядке обнаружения — при замене порядок может измениться. Стабильнее запрашивать по конкретному ROM-адресу:
DeviceAddress addr1 = {0x28, 0xFF, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC};
float t = sensors.getTempC(addr1);
Адреса узнаёте сканером — библиотека печатает их при старте.
Водонепроницаемый корпус
DS18B20 в герметичном гильзе — стандарт для улицы, аквариума, котла. Три провода: красный VCC, чёрный GND, жёлтый DATA. Подтяжка 4.7 кОм между DATA и VCC.
Паразитное питание
DS18B20 умеет работать от двух проводов — DATA и GND, «воруя» питание с линии данных. Для этого VCC датчика сажается на GND. Экономит провод, но медленнее и менее надёжно — для обычных задач используйте трёхпроводную схему.
Диапазон и точность
- −55…+125°C, точность ±0.5°C в диапазоне −10…+85.
- Разрешение настраивается 9–12 бит (0.5–0.0625°C шаг) — больше бит = медленнее конверсия (750 мс на 12 бит).
setResolution(12)для максимальной точности,setWaitForConversion(false)для неблокирующего чтения.
Частые проблемы
getTempCвозвращает -127: датчик не отвечает — проверьте провода, подтяжку, адрес.- Показания скачут: плохой контакт, длинный провод без витой пары.
- Несколько датчиков мешают: суммарная подтяжка важна — один резистор на всю шину.
- Медленный опрос:
requestTemperaturesждёт конверсии 750 мс на 12 бит —setWaitForConversion(false)и опрос по таймеру.
Проекты
- Уличный термометр в гильзе.
- Контроль температуры котла/бойлера.
- Земляной термометр в теплице.
- Металлическая гильза для точного измерения жидкостей.