Взаимодействие ds18b20, однопроводного (1-wire) цифрового датчика температуры, с arduino

Способ 2: чтение датчика DS18B20 по адресу

Мы знаем, что каждому DS18B20 назначен уникальный 64-битный адрес, чтобы отличать их друг от друга. В этом методе мы найдем этот адрес для соответствующей маркировки каждого датчика. Затем этот адрес можно использовать для считывания каждого датчика в отдельности.

Поиск адресов датчиков DS18B20s на шине

Следующий скетч обнаруживает все DS18B20, присутствующие на шине, и печатает их адреса на 1-Wire в монитор последовательного порта.

Вы можете подключать только один датчик за раз, чтобы определить его адрес (или последовательно добавлять по одному новому датчику, чтобы вы могли идентифицировать каждый из них по его адресу). Затем вы можете пометить каждый датчик.

Теперь откройте монитор последовательного порта. Вы должны получить что-то подобное:

Рисунок 6 – Нахождение адресов 1-Wire всех датчиков DS18B20 на шине

Скопируйте все адреса, так как они нам понадобятся в следующем скетче.

Чтение показаний датчиков DS18B20 по адресу

Следующий скетч считывает температуру датчиков DS18B20 по их адресам. Прежде чем приступить к загрузке скетча, вам нужно изменить адреса датчиков DS18B20 на те, которые вы определили в предыдущем скетче.

Вывод вышеприведенного эскиза выглядит так

Рисунок 7 – Вывод показаний нескольких датчиков DS18B20 методом адреса

Объяснение кода

Как обычно, скетч начинается с включения библиотек, объявления вывода, к которому подключена шина датчиков, и создания объекта библиотеки .

Далее мы вводим адреса, которые были найдены ранее для каждого датчика температуры. В нашем случае имеем следующее.

Во фрагменте настройки мы инициализируем библиотеку путем вызова функции и инициализируем последовательную связь с ПК.

В цикле мы просто посылаем команду всем датчикам для преобразования температуры, используя функцию .

Затем, чтобы напечатать температуру датчика, мы вызываем пользовательскую функцию , для которой передается в качестве параметра.

Вышеприведенная функция просто вызывает библиотечные функции для отображения температуры в градусах Цельсия и для отображения температуры в градусах Фаренгейта.

Подключение LMT01 к PIC10F204

Рис. 16. Макет устройства (LMT01 + PIC10F204)

На рисунке 16 представлен макет подключения LMT01 к микроконтроллеру PIC10F204 в корпусе DIP-8. Так как данный микроконтроллер имеет в своем составе компаратор, внешний ключ на транзисторе не нужен. Схема подключения представлена на рисунке 17. На рисунке 18 представлены осциллограммы сигналов для разных измеряемых температур.

В связи с крайне ограниченными ресурсами PIC10F204 код программы был написан на ассемблере и занял большую часть объема Flash-памяти. Результаты измерения выводятся через программный UART на скорости 9600 бит/с. Счет импульсов идет программным способом на пределе скорости для тактовой частоты 4 МГц. В программе реализован прямой пересчет для получения результата с максимальным разрешением 0,0625°C без использования программного умножения и деления. Для отображения результата используется подпрограмма b24dec для перевода 24-битного результата в ASCII-код. Исходный код проекта LMT01_MSP430 с дополнительными материалами можно найти в архиве «Примеры кода для LMT01».

Рис. 17. Схема подключения LMT01 к микроконтроллеру PIC10F204

Рис. 18. Изменение количества импульсов LMT01 в зависимости от температуры

Исходный код программы (скетча)

Перед тем как загружать программу в плату Arduino необходимо скачать и извлечь из архива следующие библиотеки, необходимые для работы проекта:

  • 1-Wire bus;
  • Dallas Temperature (необходима для считывания и расчета температуры с датчика).

В скетче программы необходимо подключить заголовочные файлы этих библиотек.

Arduino

/********************************************************************/
// сначала необходимо подключить следующие библиотеки в проект
#include <OneWire.h>
#include <DallasTemperature.h>
/********************************************************************/
// контакт данных датчика подключен к контакту 2 платы Arduino
#define ONE_WIRE_BUS 2
/********************************************************************/
//создаем объект класса oneWire для работы с датчиком и его взаимодействия
//с другими OneWire устройствами (не только температурными датчиками Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
/********************************************************************/
// связываем наш объект oneWire с библиотекой Dallas Temperature.
DallasTemperature sensors(&oneWire);
/********************************************************************/
void setup(void)
{
// инициализируем последовательную связь со скоростью 9600 бод
Serial.begin(9600);
Serial.println(«Dallas Temperature IC Control Library Demo»);
// инициализируем датчик
sensors.begin();
}
void loop(void)
{
// вызываем функцию sensors.requestTemperatures() для запроса значения
// температуры со всех устройств, подключенных к шине
/********************************************************************/
Serial.print(» Requesting temperatures…»);
sensors.requestTemperatures(); // передаем команду на запрос температуры
Serial.println(«DONE»);
/********************************************************************/
Serial.print(«Temperature is: «);
Serial.print(sensors.getTempCByIndex(0)); // почему вводится индекс «byIndex»?
// потому что к одной и той же шине может быть подключено несколько датчиков DS18B20.
// 0 относится к первому датчику (микросхеме) на шине (проводе)
delay(1000);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

/********************************************************************/
// сначала необходимо подключить следующие библиотеки в проект
#include <OneWire.h>
#include <DallasTemperature.h>
/********************************************************************/
// контакт данных датчика подключен к контакту 2 платы Arduino
#define ONE_WIRE_BUS 2
/********************************************************************/
//создаем объект класса oneWire для работы с датчиком и его взаимодействия
//с другими OneWire устройствами (не только температурными датчиками Maxim/Dallas temperature ICs)

OneWireoneWire(ONE_WIRE_BUS);

/********************************************************************/
// связываем наш объект oneWire с библиотекой Dallas Temperature.

DallasTemperaturesensors(&oneWire);

/********************************************************************/

voidsetup(void)

{

// инициализируем последовательную связь со скоростью 9600 бод

Serial.begin(9600);

Serial.println(«Dallas Temperature IC Control Library Demo»);

// инициализируем датчик

sensors.begin();

}

voidloop(void)

{

// вызываем функцию sensors.requestTemperatures() для запроса значения

// температуры со всех устройств, подключенных к шине

/********************************************************************/

Serial.print(» Requesting temperatures…»);

sensors.requestTemperatures();// передаем команду на запрос температуры

Serial.println(«DONE»);

/********************************************************************/

Serial.print(«Temperature is: «);

Serial.print(sensors.getTempCByIndex());// почему вводится индекс «byIndex»?  

// потому что к одной и той же шине может быть подключено несколько датчиков DS18B20.  

// 0 относится к первому датчику (микросхеме) на шине (проводе)

delay(1000);

}

На следующем рисунке показано тестирование работы проекта.

Описание датчика DS18B20 для Arduino

DS18B20 – это цифровой температурный датчик, обладающий множеством полезных функций. По сути, DS18B20 – это целый микроконтроллер, который может хранить значение измерений, сигнализировать о выходе температуры за установленные границы (сами границы мы можем устанавливать и менять), менять точность измерений, способ взаимодействия с контроллером и многое другое. Все это в очень небольшом корпусе, который, к тому же, доступен в водонепроницаемом исполнении.

Микросхема имеет три выхода, из которых для данных используется только один, два остальных – это земля и питание. Число проводов можно сократить до двух, если использовать схему с паразитным питанием и соединить Vdd с землей. К одному проводу с данными можно подключить сразу несколько датчиков DS18B20 и в плате Ардуино будет задействован всего один пин.

Где купить датчик

Влагозащищенный датчик температуры DS18B20 с длиной провода 1 м от надежного магазина Комплект из 10 микросхем DS18B20 TO92 Модуль DS18B20 для удобного подключения к Ардуино от Keyestudio
Беспроводной модуль DS18B20 на ESP8266 ESP-01 ESP-01S для проектов умного дома Шилд датчика DS18B20 для платы D1 MINI – беспроводная передача данных Датчик DS18B20 с модулем для подключения к Ардуино

Особенности цифрового датчика DS18B20

Погрешность измерения не больше 0,5 С (для температур от -10С до +85С), что позволяет точно определить значение температуры. Не требуется дополнительная калибровка.
Температурный диапазон измерений лежит в пределах от -55 С до +125 С.
Датчик питается напряжением от 3,3В до 5В.
Можно программно задать максимальную разрешающую способность до 0,0625С, наибольшее разрешение 12 бит.
Присутствует функция тревожного сигнала.
Каждое устройство обладает своим уникальным серийным кодом.
Не требуются дополнительные внешние элементы.
Можно подключить сразу до 127 датчиков к одной линии связи.
Информация передается по протоколу 1-Wire.
Для присоединения к микроконтроллеру нужны только 3 провода.
Существует так называемый режим паразитного питания – в нем происходит питание напрямую от линии связи. Для подключения в этом случае нужны только 2 провода

Важно, что в этом режиме не гарантируется корректная работа при температурах выше 100С. Режим паразитного питания удобно обычно применяется для приложений с удаленным температурным датчиком.

Память датчика состоит из двух видов: оперативной и энергонезависимой – SRAM и EEPROM. В последнюю записываются регистры конфигурации и регистры TH, TL, которые могут использоваться как регистры общего назначения, если не используются для указания диапазона допустимых значений температуры.

Основной задачей DS18B20 является определение температуры и преобразование полученного результата в цифровой вид. Мы можем самостоятельно задать необходимое разрешение, установив количество бит точности – 9, 10, 11 и 12. В этих случаях разрешающие способности будут соответственно равны 0,5С, 0,25С, 0,125С и 0,0625С.

Во время включения питания датчик находится в состоянии покоя. Для начала измерения контроллер Ардуино выполняет команду «преобразование температуры». Полученный результат сохранится в 2 байтах регистра температуры, после чего датчик вернется в первоначальное состояние покоя. Если схема подключена в режиме внешнего питания, микроконтроллер регулирует состояние конвертации. Во время выполнения команды линия находится в низком состоянии, после окончания программы линия переходит в высокое состояние. Такой метод не допустим при питании от паразитной емкости, так как на шине постоянно должен сохраняться высокий уровень сигнала.

Полученные температурные измерения сохраняются в SRAM датчика. 1 и 2 байты сохраняют полученное значение температуры, 3 и 4 сохраняют пределы измерения, 5 и 6 зарезервированы, 7 и 8 используются для высокоточного определения температуры, последний 9 байт хранит устойчивый к помехам CRC код.

Пример работы

Итак, с теоретической основой закончили, можно приступать к соединению датчика температуры и Arduino. Схема подключения:

Естественно, речь идет об использовании сенсора в воздушной среде. В том случае, если требуется измерять нагрев жидкости, то нужен герметичный датчик температуры DS18B20.

Алгоритм обработки

Сама последовательность действий достаточно проста. Только для упрощения, в приведенном примере, она рассчитана на наличие единственного сенсора на линии 1-Wire.

  1. Определить ИД датчика термостата
  2. Отправить команду по ИД на измерение температуры
  3. Ждать 750 мс, пока устройство отработает и поместит данные в оперативную память
  4. Дать функциональную команду на чтение памяти датчика температуры ds18b20

Сам скетч для Arduino

Здесь требуется примечание. Существует множество библиотек работы с 1-Wire выполняющих подключение датчика температуры DS18B20 к Arduino. В представленном скетче, будет использоваться вариант «OneWire», которую можно скачать с официальной страницы разработчиков ПО Arduino (https://playground.arduino.cc/Learning/OneWire). Там же, есть информация для ознакомления со списком функций в библиотеке.

Есть нюанс в приведенном скетче, он относится к физической схеме подключения питания датчика и соответствующим взаимодействием процедур библиотеки. Если используется паразитное, то DataSerial.Write(0х44), о запросе температуры, нужно заменить на DataSerial.Write(0x44, 1).

Что касается конечных пользователей, то пользуясь этой инструкцией, им будет несложно выполнить подключение инфракрасного датчика ds18b20 температуры для Ардуино. Все достаточно прозрачно, скетч элементарен, а простота схемы достойна уважения.

Основные функциональные способности датчика DS18B20

Термодатчик DS18B20 имеет в своем функционале сразу несколько важнейших команд:

  1. Навык преобразования температур. (Данная способность может поместить температуру в двух-байтный блок оперативной памяти, после чего датчик переходит в состояние низкого потребления. В этом состоянии DS18B20 считывает код данных и определяет режим состояния процесса);
  2. Команда записи памяти. (Она дает возможность сохранить три байта данных в оперативной памяти DS18B20. При это, следует уточнить, что ведущий прибор перебрасывает информацию с наименьшего бита);
  3. Способность чтения памяти. (Применяется для прочтения оперативной памяти памяти прибора. Сброс данных осуществляется с самых наименьших битов или байтов, при этом, в случае необходимости, эта команда способна прекратить сброс данных);
  4. Команда копирования памяти. (Она помогает скопировать все данные внутренней памяти устройства в блок EEPROM, что приводит к осуществлению в дальнейшем питательной способности системы);
  5. Способность перезагрузки EEPROM. (Дает возможность регистрам передохнуть, перезагружая все значения на блоках. Кроме того, только после перезагрузки DS18B20 происходит процесс прочтения оперативной памяти памяти прибора и сообщается о ее состоянии).

Другие полезные функции в библиотеке DallasTemperature.h

Есть еще несколько полезных функций, которые вы можете использовать с объектом . Несколько из них перечислены ниже:

  • Функция устанавливает разрешение внутреннего аналого-цифрового преобразователя DS18B20 на значение 9, 10, 11 или 12 бит, что соответствует шагу температуры 0,5°C, 0,25°C, 0,125°C и 0,0625°C соответственно ,
  • Функция возвращает значение флага . Это может быть полезно, когда вы хотите проверить, завершено ли преобразование температуры.
  • Функции и устанавливают внутренние пороги тревоги высокой и низкой температуры для устройства в градусах Цельсия. Допустимый диапазон от -55°C до +125°C
  • Функция возвращает , если устройство имеет состояние тревоги, когда температура выходит за пределы диапазона между верхним и нижним уровнями тревоги.

На что они похожи?

На Рисунке 1 приведен пример подлинного датчика DS18B20 производства Maxim в корпусе TO-92.

Рисунок 1. Пример маркировки оригинальных датчиков DS18B20 на корпусе TO-92.

На момент написания статьи (2019) маркировка оригинальных  микросхем Maxim наносилась лазером, а не печаталась.

  • Первые две строки, DALLAS 18B20, указывают, что это датчик DS18B20 (Dallas Semiconductor является первоначальным производителем), датчики только с паразитным питанием маркируются DALLAS 18B20P.
  • Знак «+» в четвертой строке означает, что компонент соответствует требованиям RoHS.
  • 3-я строка указывает год выпуска и номер недели в году (в данном случае это 32 неделя 2019 года).
  • Последние два символа в строке 3 указывают ревизию кристалла (на данный момент С4).
  • В строке 4 трехзначное число, за которым следуют два символа, является формой кода партии, которая позволяет Maxim отследить историю производства.
  • В микросхемах, выпущенных в 2016 году или позже, встречалась только комбинация символов AB и AC .

Маркировка внутри отступа на задней части:

  • Маркировка P (Филиппины?). На всех последних микросхемах (2016 и моложе) и на большинстве микросхем, выпуск которых уходит, как минимум, в 2009 год.
  • Маркировка THAI <буква> (Таиланд?), где <буква> — это одна из I, J, K, L, M, N, O, S, T, U, V, W, X, и, возможно, других, по крайней мере, на некоторых микросхемах произведенных в 2011 году . Шрифт <буквы>  отличается от шрифта символов, составляющих слово THAI.

Из того, что было автором замечено на корпусе TO-92, только для микросхем с маркировкой P в отступе на задней части один код партии соответствует коду даты производства. Это не относится к микросхемам с маркировкой THAI в отступе.

Активация однопроводного (One-Wire) интерфейса в Raspberry Pi

Поскольку датчик DS18B20 передает данные по однопроводному интерфейсу (One-Wire) нам необходимо включить использование данного интерфейса в настройках платы Raspberry Pi. Для этого выполните следующую последовательность шагов.

Шаг 1. Откройте в редакторе файл config.txt.

Shell

sudo nano /boot/config.txt

1 sudo nanobootconfig.txt

Шаг 2. Внутрь данного файла добавьте строку “dtoverlay=w1-gpio” как показано на следующем рисунке и сохраните изменения в файле.

Шаг 3. Используйте Ctrl+X чтобы выйти из файла и “Y”, и затем Enter чтобы сохранить изменения в файле. После этого перезагрузите плату Raspberry Pi.

Shell

sudo reboot

1 sudo reboot

Шаг 4. После перезагрузки платы снова откройте терминал и выполните следующую последовательность команд:

Shell

sudo modprobe w1–gpio
sudo modprobe w1-therm.
cd /sys/bus/w1/devices
ls

1
2
3
4

sudo modprobe w1–gpio

sudo modprobe w1-therm.

cdsysbusw1devices

ls

После этого в окне терминала у вас должна появиться примерно следующая картина:

Шаг 5. В конце шага 4 вы вводите команду ls, в результате ее выполнения ваша плата покажет вам уникальный номер, этот номер будет уникальный для каждого датчика, но он всегда будет начинаться с 28-. В нашем случае мы получили адрес датчика 28-03172337caff.

Шаг 6. Теперь проверим корректно ли работает датчик с помощью следующих команд:

Shell

cd 28-XXXXXXXXXXXX [use the name of your directory or use Tab key for auto complete)
cat w1_slave

1
2

cd28-XXXXXXXXXXXXusethe name of your directory oruseTab key forauto complete)

catw1_slave

Эти две команды считают данные с датчика и отобразят их в терминале как показано на следующем рисунке. На этом рисунке значение температуры обведено красной линией – оно равно 37*C.

Примеры работы для Arduino

Один датчик

Рассмотрим простой пример — подключения одного датчика.

Сенсор подключается к управляющей плате через один сигнальный пин.
При подключении к Arduino в компактном формфакторе, например Arduino Micro или Iskra Nano Pro, воспользуйтесь макетной платой и парочкой нажимных клеммников.

Между сигнальным проводом и питанием установите сопротивление 4,7 кОм.

При коммуникации сенсора со стандартными платами Arduino формата Rev3, Arduino Uno или Iskra Neo, используйте Troyka Slot Shield совместно с модулем подтяжки.

Код программы

Выведем температуру сенсора в Serial-порт.

simple.ino
// библиотека для работы с протоколом 1-Wire
#include <OneWire.h>
// библиотека для работы с датчиком DS18B20
#include <DallasTemperature.h>
 
// сигнальный провод датчика
#define ONE_WIRE_BUS 5
 
// создаём объект для работы с библиотекой OneWire
OneWire oneWire(ONE_WIRE_BUS);
 
// создадим объект для работы с библиотекой DallasTemperature
DallasTemperature sensor(&oneWire);
 
void setup(){
  // инициализируем работу Serial-порта
  Serial.begin(9600);
  // начинаем работу с датчиком
  sensor.begin();
  // устанавливаем разрешение датчика от 9 до 12 бит
  sensor.setResolution(12);
}
 
void loop(){
  // переменная для хранения температуры
  float temperature;
  // отправляем запрос на измерение температуры
  sensor.requestTemperatures();
  // считываем данные из регистра датчика
  temperature = sensor.getTempCByIndex();
  // выводим температуру в Serial-порт
  Serial.print("Temp C: ");
  Serial.println(temperature);
  // ждём одну секунду
  delay(1000);
}

Серия датчиков

Каждый сенсор DS18B20 хранит в своей памяти уникальный номер, такое решение позволяет подключить несколько датчиков к одному пину.

Добавим к предыдущем схемам подключения ещё по паре датчиков в параллель.

Код программы

Просканируем все устройства на шине и выведем температуру каждого сенсора отдельно в Serial-порт.

multipleSensors.ino
// библиотека для работы с протоколом 1-Wire
#include <OneWire.h>
// библиотека для работы с датчиком DS18B20
#include <DallasTemperature.h>
 
// сигнальный провод датчика
#define ONE_WIRE_BUS 5
 
// создаём объект для работы с библиотекой OneWire
OneWire oneWire(ONE_WIRE_BUS);
// создадим объект для работы с библиотекой DallasTemperature
DallasTemperature sensors(&oneWire);
// создаём указатель массив для хранения адресов датчиков
DeviceAddress *sensorsUnique;
// количество датчиков на шине
int countSensors;
 
// функция вывода адреса датчика
void printAddress(DeviceAddress deviceAddress){
  for (uint8_t i = ; i < 8; i++){
    if (deviceAddressi < 16) Serial.print("0");
    Serial.print(deviceAddressi, HEX);
  }
}
 
void setup(){
  // инициализируем работу Serial-порта
  Serial.begin(9600);
  // ожидаем открытия Serial-порта
  while(!Serial);
  // начинаем работу с датчиком
  sensors.begin();
  // выполняем поиск устройств на шине
  countSensors = sensors.getDeviceCount();
  Serial.print("Found sensors: ");
  Serial.println(countSensors);
  // выделяем память в динамическом массиве под количество обнаруженных сенсоров
  sensorsUnique = new DeviceAddresscountSensors;
 
  // определяем в каком режиме питания подключены сенсоры
  if (sensors.isParasitePowerMode()) {
    Serial.println("Mode power is Parasite");
  } else {
    Serial.println("Mode power is Normal");
  }
 
  // делаем запрос на получение адресов датчиков
  for (int i = ; i < countSensors; i++) {
    sensors.getAddress(sensorsUniquei, i);
  }
  // выводим полученные адреса
  for (int i = ; i < countSensors; i++) {
    Serial.print("Device ");
    Serial.print(i);
    Serial.print(" Address: ");
    printAddress(sensorsUniquei);
    Serial.println();
  }
  Serial.println();
  // устанавливаем разрешение всех датчиков в 12 бит
  for (int i = ; i < countSensors; i++) {
    sensors.setResolution(sensorsUniquei, 12);
  }
}
 
void loop(){
  // переменная для хранения температуры
  float temperature10;
  // отправляем запрос на измерение температуры всех сенсоров
  sensors.requestTemperatures();
  // считываем данные из регистра каждого датчика по очереди
  for (int i = ; i < countSensors; i++) {
    temperaturei = sensors.getTempCByIndex(i);
  }
  // выводим температуру в Serial-порт по каждому датчику
  for (int i = ; i < countSensors; i++) {
    Serial.print("Device ");
    Serial.print(i);
    Serial.print(" Temp C: ");
    Serial.print(temperaturei);
    Serial.println();
  }
  Serial.println();
  // ждём одну секунду
  delay(1000);
}

Термометр через последовательный монитор

Чтобы отобразить данные на последовательном мониторе, подключите датчик DS18B20 к Arduino, используя перемычки и макет, и не забудьте подключить или припаять резистор 4.7k между контактом 2 и 3 датчика.

Затем скачайте, откройте и загрузите файл .ino, который называется — DS18B20_Serial, ниже.

Если все в порядке, вы должны увидеть измеренную температуру на серийном мониторе Arduino IDE.

#include <OneWire.h>
#include <DallasTemperature.h>
 
// Провод данных подключен к контакту 2 на Arduino
#define ONE_WIRE_BUS 2
 
// Настройка oneWire для связи с любыми устройствами OneWire 
// (не только Maxim/Dallas температурные IC)
OneWire oneWire(ONE_WIRE_BUS);
 
DallasTemperature sensors(&oneWire);
 
void setup(void)
{
  // Старт серийного порта
  Serial.begin(9600);
  Serial.println("Dallas Temperature IC демо");

  // Запуск библиотеки
  sensors.begin();
} 
 
void loop(void)
{
  // запрашиваем sensor.requestTemperatures() для получения глобальной температуры
  // запрос всех устройств на шине
  Serial.print(" Запрашиваем температуру...");
  sensors.requestTemperatures(); // Отправляем команды для получения температуры
  Serial.println("DONE");

  Serial.print("Температура: ");
  Serial.print(sensors.getTempCByIndex(0)); // Почему "byIndex"? 
    // У вас может быть несколько IC на одной шине. 
    // 0 относится к первой IC
    delay(1000);
}

Общие принципы работы датчика температуры DS18B20

DS18B20 представляет собой однопроводный цифровой датчик температуры от компании Maxim IC. Выдает значение температуры в градусах Цельсия, способен измерять температуру с 9-12 битной точностью в диапазоне от -55 до 125 градусов Цельсия с точностью +/-0.5 градуса. Каждый датчик DS18B20 имеет 64-битный уникальный номер (Serial number), вытравленный на корпусе датчика, что позволяет подключать огромное число подобных датчиков к одной шине данных. С помощью данного датчика можно измерять температуру воздуха, жидкостей и земли. В некоторых магазинах датчик продается в комплекте с резистором сопротивлением 4,7 кОм.

Особенности датчика DS18B20:

  • однопроводный интерфейс (1-Wire interface), что позволяет использовать для подключения датчика только один контакт микроконтроллера (в нашем случае платы Arduino Uno);
  • каждый датчик имеет 64-битный уникальный последовательный код (номер), хранящийся в ПЗУ (ROM) датчика;
  • способность подключения к одной шине множества датчиков позволяет создавать на его основе приложения для распределенного (в пространстве) измерения температуры;
  • не требует никаких внешних компонентов;
  • может быть запитан от линии данных;
  • поддерживает напряжение питания от 3.0V до 5.5V;
  • способен измерять температуру в диапазоне от –55°C до +125°C (–67°F до +257°F) с точностью ±0.5°C (в диапазоне от –10°C до +85°C);
  • можно выбрать разрешающую способность (разрешение) датчика: от 9 до 12 бит;
  • преобразует значение температуры в 12-битное цифровое слово длительностью 750 мс (max.);
  • можно настраивать энергонезависимую (nonvolatile, NV) сигнализацию (сигнал тревоги);
  • опции сигнала тревоги позволяют идентифицировать и определить адрес датчика, чья температура не соответствует запрограммированным границам;
  • может применяться в устройствах термоконтроля, промышленных системах, потребительских продуктах, термометрах и в любых других системах, где требуется измерение температуры.

Более подробную информацию о принципах работы датчика DS18B20 вы можете посмотреть в следующей статье на нашем сайте.

Сенсоры, определяющие температуру

Датчик температуры подключаемый к Arduino, как и в случае любого другого микроконтроллера, существует в двух видах: цифровой и аналоговый. Разница между настоящими термометрами в виде передаваемой на управляющую плату информации. Для первых характерна выдача уже готовых цифровых последовательностей, с которыми контроллер может работать непосредственно. Вторые только изменяют физическую характеристику идущего через них тока в зависимости от внешнего воздействия. То есть, Arduino, еще должен и преобразовать получаемый результат к цифровому виду, «зная» тип самого устройства и таблицу соответствия приходящего сигнала реальным значениям.

В последнем случае падает конечная точность измерений, так как сам микроконтроллер, о котором идет речь, может определять лишь изменения с градацией в 1024 уровня. Кроме того, для каждого чувствительного аналогового устройства требуется свой отдельный входящий канал. Единственное, что нивелирует минусы аналоговых сенсоров — их низкая цена и простота конструкции, которая обеспечивает достаточную длительность бесперебойной работы. Наибольшее распространение среди таких детекторов тепла получили модели на основе чипсета LM35 — TMP35, TMP37, LM335. Существует и широкий спектр аналогичных решений от иных производителей.

Другое дело — цифровые датчики. Никаких сторонних вычислений микроконтроллеру проводить для такого термометра не нужно. Достаточно получить итоговую цифровую последовательность с контакта всех сенсоров, расположенных на единой линии. Каждый из которых подключается к ней параллельно. Их максимальное количество ограничено лишь физическими возможностями дальности хода сигнала между микроконтроллером и чувствительным элементом.

Шина передачи в названом случае называется 1-Wire.  В ней, для определения конечного отправителя показаний, используется уникальный идентификационный код «зашитый» в сам конечный датчик, что помогает избежать путаницы с изначальным адресантом. Хорошим примером цифровых детекторов такого типа служит DS18B20 Arduino и его варианты разных производителей — DS18S20, DS1820, DS1822, MAX31820. Все они основаны на логике DS18.

Есть у цифровых датчиков и недостаток. Они сильно подвержены влиянию импульсных электрических помех от стороннего оборудования или самой линии питания. Чувствительна аппаратура и к сильным магнитным полям. В достаточно простых и не критичных системах, фактором можно пренебречь, но в важных контролирующих комплексах он требует обращения на себя особого внимания.

Вне зависимости от разновидности датчиков Ардуино, они поставляются в открытом, более удобном к монтажу исполнении, или закрытом, защищенном корпусе, препятствующем попаданию влаги. Последний фактор позволяет использовать термометры на основе DS1820 или LM35 в весьма агрессивной для электроники среде — насыщенном водой пространстве. Речь идет не только о допустимости прямого погружения их в жидкость, но и об функционировании в воздухе, насыщенном ее парами.

Скетч для Arduino и сенсора DS18B20

Установливаем библиотеку OneWire Library

После того как вы скачали архив с библиотекой, ее надо импортировать. Для этого в Arduino IDE выберите пункт “Sketch” — “Import Library” — “Add Library” и выберите архив, который вы скачали. Если у вас возникли проблемы, с установкой библиотеки, ознакомьтесь с инструкцией по установке библиотек в Arduino.

Загружаем скетч на Arduino

Скетч, который представлен ниже, есть в библиотеке OneWire, в категории examples. Перейдите в “File” — “Examples” — “OneWire” и выберите пример “DS18x20_Temperature”. Код программы представлен ниже.

Данный пример использует библиотеку OneWire Library, для того, чтобы собрать данные со всех подключенных датчиков температуры DS28B20 (как подключить несколько сенсоров описано в конце статьи) и отобразить их в окне серийного монитора Arduino IDE.

В окне серийного монитора вы увидите примерно следующее:

ROM = 28 88 84 82 5 0 0 6A

Chip = DS18B20

Data = 1 56 1 4B 46 7F FF A 10 D1 CRC=D1

Temperature = 21.37 Celsius, 70.47 Fahrenheit

No more addresses.

ROM = 28 88 84 82 5 0 0 6A

Chip = DS18B20

Data = 1 56 1 4B 46 7F FF A 10 D1 CRC=D1

Temperature = 21.37 Celsius, 70.47 Fahrenheit

No more addresses.

ROM = 28 88 84 82 5 0 0 6A

Chip = DS18B20

Data = 1 56 1 4B 46 7F FF A 10 D1 CRC=D1

Temperature = 21.37 Celsius, 70.47 Fahrenheit

No more addresses.

Обычное или паразитное питание?

DS18B20 может работать в обычном или в так называемом «паразитном» режиме. В обычном режиме для подключения используется 3 коннектора, в «паразитном» режиме — в его лишь 2.

Вам надо настроить правильный режим в скетче, чтобы снять достоверные показания с датчика:

  • Для «паразитного» режима в строке 65 надо указать: ds.write(0x44, 1);
  • Для обычного режима в строке 65 указывается: ds.write(0x44);

Убедитесь, что вы указали корректные пины!

В строке 10, где указано “OneWire ds(2);” устанавливается пин, к которому подключен контакт data с сенсора.

В этом примере использован пин 2, но значения пина по умолчанию в примере OneWire стоит на 10. Можно использовать и его.

#include &ltOneWire.h&gt

// пример использования библиотеки OneWire DS18S20, DS18B20, DS1822

OneWire ds(2); // на пине 10 (нужен резистор 4.7 КОм)

void setup(void) {

Serial.begin(9600);

}

void loop(void) {

byte i;

byte present = 0;

byte type_s;

byte data;

byte addr;

float celsius, fahrenheit;

if ( !ds.search(addr)) {

Serial.println(«No more addresses.»);

Serial.println();

ds.reset_search();

delay(250);

return;

}

Serial.print(«ROM =»);

for( i = 0; i

Serial.write(‘ ‘);

Serial.print(addr, HEX);

}

if (OneWire::crc8(addr, 7) != addr) {

Serial.println(«CRC is not valid!»);

return;

}

Serial.println();

// первый байт определяет чип

switch (addr) {

case 0x10:

Serial.println(» Chip = DS18S20″); // или более старый DS1820

type_s = 1;

break;

case 0x28:

Serial.println(» Chip = DS18B20″);

type_s = 0;

break;

case 0x22:

Serial.println(» Chip = DS1822″);

type_s = 0;

break;

default:

Serial.println(«Device is not a DS18x20 family device.»);

return;

}

ds.reset();

ds.select(addr);

ds.write(0x44); // начинаем преобразование, используя ds.write(0x44,1) с «паразитным» питанием

delay(1000); // 750 может быть достаточно, а может быть и не хватит

// мы могли бы использовать тут ds.depower(), но reset позаботится об этом

present = ds.reset();

ds.select(addr);

ds.write(0xBE);

Serial.print(» Data = «);

Serial.print(present, HEX);

Serial.print(» «);

for ( i = 0; i

data = ds.read();

Serial.print(data, HEX);

Serial.print(» «);

}

Serial.print(» CRC=»);

Serial.print(OneWire::crc8(data, 8), HEX);

Serial.println();

// конвертируем данный в фактическую температуру

// так как результат является 16 битным целым, его надо хранить в

// переменной с типом данных «int16_t», которая всегда равна 16 битам,

// даже если мы проводим компиляцию на 32-х битном процессоре

int16_t raw = (data

if (type_s) {

raw = raw

if (data == 0x10) {

raw = (raw & 0xFFF0) + 12 — data;

}

} else {

byte cfg = (data & 0x60);

// при маленьких значениях, малые биты не определены, давайте их обнулим

if (cfg == 0x00) raw = raw & ~7; // разрешение 9 бит, 93.75 мс

else if (cfg == 0x20) raw = raw & ~3; // разрешение 10 бит, 187.5 мс

else if (cfg == 0x40) raw = raw & ~1; // разрешение 11 бит, 375 мс

//// разрешение по умолчанию равно 12 бит, время преобразования — 750 мс

}

celsius = (float)raw / 16.0;

fahrenheit = celsius * 1.8 + 32.0;

Serial.print(» Temperature = «);

Serial.print(celsius);

Serial.print(» Celsius, «);

Serial.print(fahrenheit);

Serial.println(» Fahrenheit»);

}