Сенсори
Початковий
Десять термометрів на одному дроті: DS18B20 і шина 1-Wire
Водонепроникні датчики DS18B20 підключаються паралельно до одного GPIO. Міряємо температуру котла, бойлера, вулиці й кімнати одночасно та віддаємо все одним JSON.
Чому DS18B20
- Точність ±0.5 °C у діапазоні −10…+85 °C, загалом −55…+125 °C.
- Продається у водонепроникній гільзі з кабелем 1–3 м — можна опускати у воду чи кріпити на трубу.
- Кожен датчик має унікальну 64-бітну адресу, тому десятки датчиків можуть сидіти на одному дроті даних.
Компоненти
- ESP32 DevKit
- 2–10 датчиків DS18B20 (краще у гільзі)
- Резистор 4.7 кОм — один на всю шину
Підключення
Усі датчики підключаються паралельно:
| DS18B20 | ESP32 |
|---|---|
| Червоний (VDD) | 3V3 |
| Чорний (GND) | GND |
| Жовтий (DATA) | GPIO 4 + 4.7 кОм до 3V3 |
Для кабелів довше 10 м зменште резистор до 2.2 кОм і використовуйте виту пару.
Бібліотеки
- OneWire
- DallasTemperature
Код
Опитування неблокуюче: запускаємо вимірювання, а через 800 мс забираємо результат — веб-сервер тим часом відповідає миттєво.
#include <WiFi.h>
#include <WebServer.h>
#include <OneWire.h>
#include <DallasTemperature.h>
const char* WIFI_SSID = "YOUR_SSID";
const char* WIFI_PASS = "YOUR_PASSWORD";
const int ONE_WIRE_PIN = 4;
const int MAX_SENSORS = 10;
OneWire oneWire(ONE_WIRE_PIN);
DallasTemperature sensors(&oneWire);
WebServer server(80);
DeviceAddress addrs[MAX_SENSORS];
float temps[MAX_SENSORS];
int count = 0;
bool converting = false;
unsigned long requestedAt = 0;
unsigned long lastCycle = 0;
String addrToString(const uint8_t *a) {
char buf[17];
for (int i = 0; i < 8; i++) sprintf(buf + i * 2, "%02X", a[i]);
return String(buf);
}
void handleData() {
String json = "[";
for (int i = 0; i < count; i++) {
if (i) json += ",";
json += "{\"id\":\"" + addrToString(addrs[i]) + "\",\"t\":";
json += temps[i] == DEVICE_DISCONNECTED_C ? String("null") : String(temps[i], 2);
json += "}";
}
json += "]";
server.send(200, "application/json", json);
}
void setup() {
Serial.begin(115200);
sensors.begin();
count = sensors.getDeviceCount();
if (count > MAX_SENSORS) count = MAX_SENSORS;
Serial.printf("Found %d sensor(s)\n", count);
for (int i = 0; i < count; i++) {
sensors.getAddress(addrs[i], i);
sensors.setResolution(addrs[i], 12); // 0.0625 °C, ~750 мс на вимір
temps[i] = DEVICE_DISCONNECTED_C;
Serial.println(" " + addrToString(addrs[i]));
}
sensors.setWaitForConversion(false);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) delay(500);
Serial.println(WiFi.localIP());
server.on("/data", handleData);
server.begin();
}
void loop() {
server.handleClient();
if (!converting && millis() - lastCycle > 5000) {
sensors.requestTemperatures(); // усі датчики міряють одночасно
requestedAt = millis();
converting = true;
}
if (converting && millis() - requestedAt > 800) {
for (int i = 0; i < count; i++) {
temps[i] = sensors.getTempC(addrs[i]);
Serial.printf("%s: %.2f °C\n", addrToString(addrs[i]).c_str(), temps[i]);
}
converting = false;
lastCycle = millis();
}
}
Як дізнатися, де який датчик
Порядок, у якому бібліотека знаходить датчики, не збігається з порядком підключення. Тож:
- Підключіть датчики й відкрийте Serial Monitor — там буде список адрес.
- Затисніть один датчик у долоні — його температура зросте.
- Підпишіть адресу (наприклад,
28FF4A1B...→ «котел, подача»).
Надалі в Home Assistant чи іншій системі прив'язуйтеся саме до адрес — вони не змінюються.
Проблеми
- −127 °C — датчик не відповідає: перевірте контакт і резистор 4.7 кОм.
- 85 °C одразу після ввімкнення — це значення за замовчуванням, вимір ще не завершився.
- Знаходить не всі датчики на довгій лінії — зменште резистор, приберіть «зірку» (підключайте ланцюжком).
Ідеї
- Моніторинг опалення: подача/зворотка котла і різниця температур.
- Контроль морозильної камери з Telegram-сповіщенням при > −12 °C.
- Акваріумний термостат з реле обігрівача.