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