Симулятор DS18B20 онлайн: термометр OneWire без датчика
DS18B20 — цифровой термометр с протоколом OneWire: один сигнальный провод, подтяжка 4,7 кОм, до сотни датчиков на одной линии. На бумаге красиво — на практике новички теряются: requestTemperatures() честно ждёт 750 мс (12-битная конверсия), и без setWaitForConversion(false) весь loop замирает; getTempCByIndex(0) возвращает -127 при перепутанной полярности; несколько датчиков на одной шине требуют поиска по ROM-коду. В браузере можно прогнать логику «запросил — подождал — прочитал» без пайки.
DS18B20 в каталоге симулятора — деталь «Термометр DS18B20» с голубым проводом DS18 на любой цифровой пин. Двигаете ползунок температуры на плашке — getTempC() возвращает значение с лёгким шумом ±0,06 °C, requestTemperatures() честно ждёт 750 мс. Ниже — проба, мульти-датчик через ROM, граница «браузер против платы» и грабли.
Что видно на стенде
DS18B20 в каталоге компонентов — деталь «Термометр DS18B20»: один сигнальный провод на цифровой пин (по умолчанию D2), голубой провод с меткой DS18. На плашке устройства — ползунок температуры от -55 до +125 °C. Двигаете ползунок — sensors.getTempCByIndex(0) возвращает значение с лёгким шумом ±0,06 °C, как живой датчик с конверсией 12 бит. requestTemperatures() честно ждёт 750 мс в движке — как на плате при setWaitForConversion(true).
- Один провод OneWire: голубой провод DS18 на любой цифровой пин; подтяжка 4,7 кОм между сигналом и +5V — в браузере виртуальная.
- requestTemperatures() ждёт 750 мс: 12-битная конверсия честно выполняется — ставьте setWaitForConversion(false) и свой таймер.
- getTempCByIndex(0): температура с шумом ±0,06 °C — как живой датчик; для -127 (нет датчика) и 85 (POWER_ON) значения проверяйте в коде.
- Один датчик на шине: getTempCByIndex(0) — самый простой API; для нескольких — поиск по ROM.
- setResolution(12): 9-12 бит; ниже разрешение — быстрее конверсия (94 мс при 9 битах вместо 750 при 12).
Скетч-проба: термометр в монитор
#include <OneWire.h>#include <DallasTemperature.h> OneWire oneWire(2); // сигнальный провод на D2DallasTemperature sensors(&oneWire); void setup() { Serial.begin(9600); sensors.begin(); sensors.setWaitForConversion(false); // не ждать в requestTemperatures} unsigned long last = 0; void loop() { if (millis() - last >= 1000) { last += 1000; sensors.requestTemperatures(); // запускает конверсию // 750 мс конверсии — параллельно делаем что-то ещё } // через 800 мс после запроса — читаем static unsigned long reqAt = 0; if (last > 0 && millis() - last >= 800) { float t = sensors.getTempCByIndex(0); Serial.print("T="); Serial.print(t, 2); Serial.println(" C"); reqAt = 0; last = 0; }}Скетч вставьте в основной симулятор: монитор печатает «T=22.50 C» раз в секунду, и вы видите, как requestTemperatures() ждёт 750 мс — Loop замораживается, если setWaitForConversion(true). Двигайте ползунок температуры — число меняется. Полный разбор пина, подтяжки и обращения с несколькими датчиками — в уроке про подключение DS18B20.
Несколько датчиков на одной шине
#include <OneWire.h>#include <DallasTemperature.h> OneWire oneWire(2);DallasTemperature sensors(&oneWire);DeviceAddress addr; void setup() { Serial.begin(9600); sensors.begin(); Serial.print("Datchikov na shine: "); Serial.println(sensors.getDeviceCount());} void loop() { sensors.requestTemperatures(); for (int i = 0; i < sensors.getDeviceCount(); i++) { sensors.getAddress(addr, i); Serial.print(i); Serial.print(": "); for (int j = 0; j < 8; j++) { Serial.print(addr[j], HEX); Serial.print(" "); } Serial.print("= "); Serial.println(sensors.getTempC(addr), 2); } delay(2000);}Поиск по ROM-адресу: sensors.getAddress(addr, i) заполняет массив 8 байтами — ROM-код датчика. По этому коду getTempC(addr) читает температуру конкретного датчика, а не по индексу. На живой плате удобно для системы «уличный — комнатный — в подвале»: каждый датчик свой ROM, скетч не путает их при добавлении нового. Полный разбор — в уроке про аквариумный термостат с DS18B20.
Честная граница: модель против живого датчика
| Проверка | Симулятор | Только железо |
|---|---|---|
| OneWire + DallasTemperature: begin, request, getTempC | да: API тот же | то же, плюс реальные шины |
| Конверсия 750 мс и setWaitForConversion | да: честно 750 мс | то же, плюс временной окно |
| Несколько датчиков: ROM-поиск | логически один датчик | да — до 100 на шине |
| Подтяжка 4,7 кОм | виртуальная, не настраивается | да — обязательна, без неё шина молчит |
| Длина провода и наводки | нет: модель без физики | да — при 30 м нужен экранированный кабель |
| Значение -127 (нет датчика) и 85 (POWER_ON) | не моделируются | да — диагностика неисправности |
Движок исполняет логику OneWire и DallasTemperature: getTempC, requestTemperatures, setResolution — все вызовы работают как на плате. Подтяжка, длина провода и паразитное питание в браузере не моделируются — это физика. На живой плате термометр на улице с проводом 20 м ловит наводки от ЛЭП — лечится витой парой и подтяжкой 2,2 кОм. Разбор уличного монтажа и герметизации — в уроке про уличный термометр на морозе.
Грабли DS18B20
- Забытый sensors.begin(): в начале setup — иначе getTempCByIndex возвращает -127. Логично, но часто забывают.
- setWaitForConversion(true) по умолчанию: requestTemperatures ждёт 750 мс, loop замораживается. Лечение — setWaitForConversion(false) + свой таймер на 750+ мс.
- Подтяжка 4,7 кОм: без неё датчик молчит или шлёт -127. Между DATA и VCC, не GND.
- Паразитное питание (2 провода): на длине > 1 м работает нестабильно — берите 3-проводное подключение.
- ROM-адреса перепутаны: при добавлении нового датчика индексы могут сместиться — храните адреса в EEPROM. Полный разбор в уроке про два датчика.