DS18B20 это датчик температуры от американской компании Dallas Semiconductor
Это точный цифровой датчик для измерения температуры в диапазоне от -55 до +125°C, при этом, в диапазоне от -10 до +85°C достигается наивысшая точность с ошибкой до ±0.5°C. Принцип работы: отправляем команду на выполнение температурного преобразования, ждем 750мс (при максимальном разрешении 12 бит) и в результате получаем температуру в двоичном(десятичном) виде. Наиболее распространенный вариант исполнения датчика: зонд в виде стальной (сталь 304) гильзы длиной 50mm, диаметром 6mm и длиной провода 2 метра (между проводом и зондом находится термоусадка, которая занимает 15mm длины гильзы).
Использование датчика
- системы умного дома (Home Assistant / Sonoff eWelink)
- контроллеры (Arduino / ESP32 / STM32 / Raspberry Pi / Wiren Board)
- системы вентиляции и кондиционирования
- инкубаторы, теплицы
- бани, сауны
- датчик для ректификационной колонны(самогоноварение)
- датчик для терморегулятора
Исполнение датчика
- герметичное в стальной гильзе
- зонд с креплением под винт
- зонд в виде винта
- корпус TO-92
- корпус SO8 (SOIC-8)
Адрес датчика
- каждый датчик имеет 64 битный код(адрес)
- пример адреса: 28-62-8D-62-A3-21-01-4A
- маска адреса: 28-xx-xx-xx-xx-00-00-crc (оригинала)
- первые 8 бит - код семейства: 28h
- следующие 48 бит - уникальный серийный номер
- следующие 8 бит - контрольная сумма CRC
- код(адрес) хранится в ПЗУ(ROM), записывается в момент производства и его нельзя изменить
Преимущество перед термистором (ntc 10k)
- уникальный адрес у каждого датчика - на один порт можно подключить более 100 датчиков
- не требуется АЦП, только два цифровых входа
- высокая точность - датчик откалиброван и рассчитан на ошибку 0.5°C, термистор же необходимо откалибровать с помощью эталонного термометра и при подключении использовать прецизионный точный резистор
- длина провода для подключения датчика может достигать нескольких десятков метров
Таблица 1: список характеристик, источник: DataSheet или DataSheet на русском языке
Характеристика | Значение |
---|---|
модель | DS18B20 |
назначение | датчик температуры |
температурный диапазон | -55...+125°C |
максимальная ошибка (отклонение или погрешность) |
диапазон [-55...-9°C] = ±2°C диапазон [-10...+85°C] = ±0.5°C диапазон [+86...+125°C] = ±2°C |
разрешение | 9/10/11/12 бит (выбирается пользователем) |
9 бит (0.48°C) | < 93.75 ms (время температурного преобразования) |
10 бит (0.25°C) | < 187.5 ms (время температурного преобразования) |
11 бит (0.125°C) | < 375 ms (время температурного преобразования) |
12 бит (0.0625°C) | < 750 ms (время температурного преобразования) |
калибровка | датчики откалиброваны в момент производства |
напряжение питания | min 3.0V DC max 5.5V DC |
потребляемый ток (в состоянии покоя) | < 5 uA |
потребляемый ток (запрос данных) | < 1.5 mA |
интерфейс | 1-Wire |
адресация | каждый датчик имеет уникальный 64-битный код, что позволяет подключить несколько датчиков к одной шине |
схемы подключения | №1: внешнее питание (основная) №2: паразитное питание |
3-pin подключение | Vdd (Vcc) = +5V DC DQ = data GND = -5V DC |
резистор | рекомендуется использовать 4.7кОм резистор разместить ближе к микроконтроллеру |
максимальная длина провода | для неэкранированных кабелей(например витая пара) до 20 метров, для экранированных до 100 метров, свыше 100 метров через повторители 1-Wire |
Карта памяти SCRATCHPAD
- карта памяти хранит в оперативной памяти 8 байт информации
- Byte0 и Byte1 хранит значение температуры, при подаче питания и до команды requestTemperatures() хранит значение 85°С (Byte0 = 0x50 / Byte1 = 0x05). Если при работе с датчиком периодически появляется неверное значение температуры равное 85°С - это значит что есть проблемы с питанием и датчик перезапускается
- Byte2(нижний предел ALARM) и Byte3(верхний предел ALARM) хранит информацию о диапазоне температур для аварийного оповещения, использовать эту функцию разумно только тогда когда у вашего микроконтроллера не хватает памяти для реализации контроля температуры и вы хотите чтобы эту функцию выполнял DS18B20
- Byte4 хранит "регистр конфигурации" - разрешающую способность (9/10/11/12 бит), которая влияет на точность измерения температуры и время температурного преобразования и соответственно чем вы выше точность, тем выше длительность температурного преобразования.
- Byte5 = 0xFF, Byte6 = 0x0C, Byte7 = 0x10 это зарезервированные байты, значения которых не должны меняться. При этом значение байта 6 = 0x0C в datasheet не указано.
- Byte8 - контрольная сумма CRC
- Byte2, Byte3, Byte4 - значение этих байтов хранится в энергонезависимой памяти EEPROM
- тестирование датчика на соответствие характеристикам оригинала в том числе выполняется с попыткой перезаписать информацию в этих байтах
Информация по копиях (подделках) датчика DS18B20
- информация о подделках датчика появилась в 2018-2019 годах
- факт №1: сайт drive2.ru
- факт №2: сайт github.com
- факт №3: сайт habr.com
- факт №4: сайт kernelchip.ru
- далее ниже по тексту будем называть "подделки" - копиями
- копии существуют разного качества, некоторые копии пригодны для использования
- понятие "оригинала" выходит за рамки соответствия датчика характеристикам оригинала и связано, в том числе, с покупкой у официальных дилеров компании Maxim Integrated
- шанс купить оригинальный датчик очень низкий, максимум можно купить копию которая будет соответствовать некоторым(или всем) признакам оригинального датчика
Список отличий копии от оригинала
- 1. группа отличий, которые можно проверить экспериментальным методом
- 1.1 некорректная работа по схеме паразитного питания
- 1.2 "зависает" - перестает отвечать на запросы спустя некоторое время
- 1.3 "неуверенный отклик" - отвечает на запросы через раз
- 1.3 ошибка(погрешность) выше заявленной, то есть выше чем ±0.5°C (при температуре -10..+85°C)
- 1.4 высокое потребление тока в момент температурного преобразования, между температурными преобразованиями
- 1.5 при температуре выше 95°C - зависание, перезапуск
- 2. группа отличий, которые можно проверить программным способом
- 2.1 есть два способа проверки - скетч discover_fake_DS18B20.ino или скетч classify_fake_DS18B20.ino - оба для arduino совместимых плат. Первый выполняет некоторые безопасные тесты, второй использует недокументированные функции датчика и во время проверки может его повредить. Результат проверки второго скетча - отнесение датчика к семейству копий - является более интересным.
- 2.2 для проверки понадобится - устройства: плата Arduino UNO R3 или ESP32 или подобная, резистор 4.7 kОм
- 2.3 для проверки понадобится - программное обеспечение: Arduino IDE 1.8 или Arduino 2.0, драйвер: CH340 или CP2102 (зависит от того - какую плату используете), Arduino IDE 1.8 - ввести дополнительные ссылки для менеджера плат(если используете ESP32), Arduino IDE 1.8 - установить библиотеку OneWire.h
- 2.4 в скетче в строке "#define pin_onewire 25" по необходимости, указать иной PIN подключения контакта DQ датчика DS18B20
- 2.5 схема подключения: можно использовать эту схему (внешнее питание, резистор между Vdd и DQ, порт для подключения ESP32 - G25)
- 2.6 когда все подключено - необходимо загрузить скетч в плату и запустить монитор порта на скорости 115200 бод. Результат тестирования будет выведен в монитор порта, по необходимости, нажмите кнопку RESET на плате для повторного тестирования. Для скетча classify_fake_DS18B20.ino после вывода первых сообщений в монитор порта - необходимо нажать кнопку ENTER
- 3. проверка скетчем(программой) discover_fake_DS18B20.ino для arduino (esp32)
- 3.1 первый скетч из основной темы про копии на сайте github.com
- 3.2 скетч выполняет несколько безопасных тестов и показывает отклонение от оригинального датчика DS18B20 (работает только по схеме подключения датчика с внешним питанием)
- 3.3 результат проверки: после запуска скетча в монитор порта(115200 бод) выводится адрес датчика(ROM), ScratchPad, результат каждой проверки (ok или Error) и в итоге общий результат с количеством ошибок.
Таблица 2: алгоритм проверки датчика из скетча discover_fake_DS18B20.ino
Проверяемое значение Условие Результат ScratchPad: Byte8 попытка перезаписать контрольную сумму CRC при удачной перезаписи: ошибка 64 битный адрес датчика проверка на соответствие маске:
28-xx-xx-xx-xx-00-00-crc
Byte0=28 Byte5=00 Byte6=00
не соответствует: ошибка ScratchPad: Byte8 проверяем контрольную сумму CRC не совпадает: проверьте соединение датчика ScratchPad: Byte2, Byte3, Byte4 сравнение со значениями по умолчанию:
Byte2 = 0x4b
Byte3 = 0x46
Byte4 = 0x7f
в случае расхождений: это не является ошибкой, так как в этих байтах хранятся настройки, которые могут быть изменены пользователем ScratchPad: Byte5 Byte5 = 0xFF не совпадает: ошибка, так как это зарезервированный байт, значение которого указано в datasheet ScratchPad: Byte6 сложное условие не совпадает: ошибка ScratchPad: Byte7 Byte7 = 0x10 не совпадает: ошибка, так как это зарезервированный байт, значение которого указано в datasheet ScratchPad: Byte2, Byte3 попытка изменить верхнюю и нижнюю границы ALARM не удается изменить: ошибка ScratchPad: Byte4 попытка изменить разрешение(регистр конфигурации) на 10 бит не удается изменить: ошибка ScratchPad: Byte5, Byte6, Byte7 сравниваем значения зарезервированных байтов до изменения разрешения и после не совпадает: ошибка, так как зарезервированные байты не должны изменятся ScratchPad: Byte4 попытка изменить разрешение(регистр конфигурации) на 12 бит не удается изменить: ошибка ScratchPad: Byte5, Byte6, Byte7 сравниваем значения зарезервированных байтов до изменения разрешения и после не совпадает: ошибка, так как зарезервированные байты не должны изменятся - 4. проверка скетчем(программой) classify_fake_DS18B20.ino для arduino (esp32)
- 4.1 второй скетч из основной темы про копии на сайте github.com
- 4.2 скетч классифицирует датчик и относит к одному из семейств копий (при тестировании используются недокументированные функции, которые могут повредить датчик и он перестанет работать, соответственно используйте на свой страх и риск)
- 4.3 результат проверки: после запуска скетча в монитор порта(115200 бод) нажать кнопку ENTER и в результате - напротив адреса датчика будет написано семейство копий, например Family B1 (Clone) или Family A1 (Genuie Maxim то есть оригинал)
- 4.4 какой вариант выбрать ?
- Кроме оригинального семейства А1, семейство B1 имеет схожие характеристики - работает по схеме паразитного питания, несколько худшая точность чем А1, разброс показаний между датчиками семейства B1 совпадает с разбросом показаний семейства A1.
- Не рекомендовано к покупке: А2 из-за большой погрешности, D1 / D2 / D3 из-за большой погрешности, нестабильной работы по схеме паразитного питания и множества других проблем, C из-за малого количества циклов перезаписи EEPROM
- Итого: покупаем А1 (это оригинал, или копия соответствующая всем признакам оригинала), покупаем B1(лучшая из копий, не сильно уступающая оригиналу)
Таблица 3: семейства копий датчика DS18B20
Family | Расшифровка |
---|---|
A1 | оригинальный датчик (Genuie Maxim) время температурного преобразования(12бит): 580-615 ms |
A2 | копия значительное количество датчиков со смещением(погрешностью) ±0.5°С при 0°С время температурного преобразования(12бит): 325-505 ms |
B1 | копия некоторые байты ПЗУ (ROM) могут быть изменены программно время температурного преобразования(12бит): 585-730 ms |
B2 | копия значительное количество датчиков со смещением(погрешностью) ±0.5°С при 0°С время температурного преобразования(12бит): 585-730 ms |
D1 | копия не работает в паразитном режиме или нестабильно работает в паразитном режиме показания температуры сразу после включения составляют 25°C, а не 85 °C датчик не выполняет преобразование температуры с низким разрешением быстрее зарезервированные Byte5 и Byte7 отличаются от datasheet некоторые байты ПЗУ (ROM) могут быть изменены программно значительное количество датчиков со смещением(погрешностью) ±0.5°С при 0°С время температурного преобразования(12бит): 11 ms |
D2 | копия не работает в паразитном режиме или нестабильно работает в паразитном режиме показания температуры сразу после включения составляют 25°C, а не 85 °C датчик не выполняет преобразование температуры с низким разрешением быстрее зарезервированные Byte5 и Byte7 отличаются от datasheet значительное количество датчиков со смещением(погрешностью) ±0.5°С при 0°С время температурного преобразования(12бит): 460-525 ms |
C | копия EEPROM: количество циклов перезаписи очень мало <10 раз разрешение 12 бит невозможно изменить время температурного преобразования(12бит): 28-30 ms |
Потребление тока копией - семейство B1 - в момент температурного преобразования составляет около 4мА
Схема подключения №1: внешнее питание
Основная схема подключения Vdd питание 3V DC+, DQ данные, GND земля 3V DC-. При подключении необходимо использовать резистор 4.7 kОм. На один порт(pin) можно подключить несколько датчиков.
Схема подключения №2: паразитное питание
Датчик подключается двумя проводами: питание(DC+) на датчик приходит по линии связи (DQ), контакт GND(DC-) необходимо соединить с контактом Vdd. При подключении необходимо использовать резистор 4.7 kОм. На один порт(pin) можно подключить несколько датчиков. В режиме преобразования температуры или работы с EEPROM датчик может потреблять ток 1.5 mA и при паразитном питании необходимо обеспечить достаточный ток для корректной работы. При температурах свыше +100°С из-за более высокого тока утечки использовать паразитное питание не рекомендуется из-за невозможности обеспечить достаточный уровень тока.
Подключение DS18B20 к ESP32 (ESP32_DS18B20.ino)
cписок устройств: отладочная плата ESP32, датчик DS18B20, резистор 4.7 kОм.
cхема подключения: с внешним питанием
программное обеспечение: Arduino IDE 1.8 или Arduino 2.0, драйвер CP2102, дополнительные ссылки для менеджера плат ESP32, библиотека OneWire.h, библиотека DallasTemperature.h
скетч ESP32_DS18B20.ino (pin для подключения одного или нескольких датчиков ds18b20: G25, OutputType = 1 вывод данных в порт текстом, Output = 2 вывод графика в плоттер, SetSensorResolution = 0 не изменять разрешение датчика, SetSensorResolution = 12 изменить разрешение на заданное значение, temp_check_period = 100 миллисекунд интервал между запросами на температурное преобразования)
#include <OneWire.h>
#include <DallasTemperature.h>
#define PIN_DQ 25 //G25 - ESP32
OneWire oneWire(PIN_DQ);
DallasTemperature sensors(&oneWire);
unsigned long temp_check_lasttime;//last time check temperature
uint8_t sensors_addresses[256][8]; //save all sensors addresses
uint8_t sensors_count=0;
int request_number=0;
//Settings
uint8_t OutputType = 2;// 1 - serial text, 2 - serial plotter (graph)
uint8_t SetSensorResolution = 0; //0 - no change, 9 - 9 bit, 10 - 10 bit, 11 - 11 bit, 12 - 12 bit
const unsigned long temp_check_period = 100; //time between check temperature (1000 = 1 seсond)
void setup()
{
Serial.begin(115200);
if (OutputType == 1) Serial.println("");
if (OutputType == 1) Serial.println("-------------");
if (OutputType == 1) Serial.println("1. ESP32 start");
if (OutputType == 1) Serial.println("2. Search all sensors");
uint8_t sensor_address[8];
uint8_t scratchpad[9];
uint8_t sensor_resolution = 0;
bool check_scratchpad;
while(oneWire.search(sensor_address)){
sensors_count++;
Serial.print("2.");
Serial.print(sensors_count);
if (OutputType == 2) Serial.print(", ");
if (OutputType == 1) Serial.print(" adress: ");
for (uint8_t i = 0; i < 8; i++)
{
sensors_addresses[sensors_count][i] = sensor_address[i];
if (OutputType == 1) Serial.print("0x");
if (sensor_address[i] < 0x10) {if (OutputType == 1) Serial.print("0");}
if (OutputType == 1) Serial.print(sensor_address[i], HEX);
if (i < 7) {if (OutputType == 1) Serial.print(", ");}
}
if (OutputType == 1) Serial.print(" SCRATCHPAD: ");
sensors.readScratchPad(sensor_address,scratchpad);
check_scratchpad = true;
for (uint8_t i = 0; i < 9; i++)
{
if (OutputType == 1) Serial.print("0x");
if (scratchpad[i] < 0x10) {if (OutputType == 1) Serial.print("0");}
if (OutputType == 1) Serial.print(scratchpad[i], HEX);
if (i == 5 && scratchpad[i] != 0xFF) check_scratchpad = false;
if (i == 6 && scratchpad[i] != 0x0C) check_scratchpad = false;
if (i == 7 && scratchpad[i] != 0x10) check_scratchpad = false;
if (i < 8) {if (OutputType == 1) Serial.print(", ");}
}
sensor_resolution = sensors.getResolution(sensor_address);
if (OutputType == 1) Serial.print(" res: ");
if (OutputType == 1) Serial.print(sensor_resolution);
if (OutputType == 1) Serial.print(" bit");
if (SetSensorResolution == 0) {
}
else if (SetSensorResolution !=sensor_resolution) {
sensors.setResolution(sensor_address,SetSensorResolution);
if (OutputType == 1) Serial.print("-->");
if (OutputType == 1) Serial.print(SetSensorResolution);
if (OutputType == 1) Serial.print(" bit");
}
if (OutputType == 1) Serial.print("\n");
}
if (OutputType == 2) Serial.println();
if (sensors_count==0)
{
if (OutputType == 1) Serial.print("Sensors not found. Check ESP32: PIN" + String(PIN_DQ));
}
else
{
if (OutputType == 1) Serial.print("3. Checking temperature... [1 time in " + String(temp_check_period/1000) + " sec] or [1 time in " + String(temp_check_period) + "ms]");
sensors.begin();
}
}
void loop()
{
unsigned long request_time;
unsigned long all_request_time;
float t;
if (millis() - temp_check_lasttime > temp_check_period)
{
request_number++;
if (OutputType == 1) Serial.println();
all_request_time = millis();
sensors.requestTemperatures();
for (uint8_t i = 1; i <= sensors_count; i++)
{
request_time = millis();
if (true) //(sensors.requestTemperaturesByAddress(sensors_addresses[i]))
{
t = sensors.getTempC(sensors_addresses[i]);
request_time = (millis() - request_time);
if (OutputType == 1) {
Serial.print("\nSensor 2." + String(i) + " temperature: " + String(t) + " (Celsius)");// RequestTime: " + String(request_time) + " ms");
}
else {
Serial.print(t);
}
}
else
{
if (OutputType == 1) Serial.print("\nSensor 2." + String(i) + " temperature: n/a");
else Serial.print(-60);
}
if ((OutputType == 2) && (i!=sensors_count)) Serial.print(" ");
if ((OutputType == 2) && (i==sensors_count)) Serial.println();
}
all_request_time = (millis() - all_request_time);
if (OutputType == 1) Serial.print("\nRequest №" + String(request_number) + " time: " + String(all_request_time) + " ms");
temp_check_lasttime = millis();
}
}
Режим работы: 1 (OutputType = 1) вывод данных в последовательный порт
Режим работы: 2 (OutputType = 2) вывод данных в плоттер для построения графика
Скачать
- ESP32_DS18B20.ino
- discover_fake_DS18B20.ino (источник: сайт github.com)
- classify_fake_DS18B20.ino (источник: сайт github.com)