Среди поистине множества устройств, подключаемых к микроконтроллерам, по праву одно из первых мест занимают датчики температуры. Применение такого сенсора оправдано в широком диапазоне вещей и действий, для которых требуется автоматизация. Здесь примером может стать обычная бытовая климатическая техника, а вернее терморегулятор. При изменении нагрева воздуха выше какого-либо уровня включается охлаждение, при понижении — обогрев. Вот как раз для целей определения текущего значения и служит сенсор температуры, а уж в зависимости от его показаний микроконтроллер «принимает решение» о последующих действиях.
Среди самодельных и не только устройств наибольшее распространение получил логический блок Arduino. В своей основе он высокоинтеллектуальный контроллер, по возможностям более всего напоминающий обычный компьютер. Причем форм-фактор производства устройства допускает легкое его расширение новыми функциями. Специально для работы совместно с ним было разработано большое количество сенсоров, в числе которых и определяющие нагрев среды. А среди последних популярностью пользуется цифровой датчик температуры DS18B20, о котором и будет рассказано далее.
В сущности, требование микроконтроллера к любому сенсору заключается в формате получения ответа. Здесь слабо подходит классический аналоговый вид сигнала, по причине слишком низкой точности. Последняя непосредственно зависит от согласованности и качества элементарной базы на обеих частях устройства — определяющей показания и принимающей результат. Решением служит цифровая передача. То есть, сенсор отправляет на контроллер бинарную импульсную последовательность одного уровня, в которой зашифрованы текущие значения показаний температуры. Кроме того, есть еще один нюанс. В основном он действует в отношении слабых компьютеров, к которым и принадлежат микроконтроллеры, такие как Arduino.
Это наличие большого количества портов ввода вывода. В управляющих логических устройствах оно сильно ограничено, а передача цифровой информации занимает минимум 8 бит или такой же объем проводников при параллельном «общении» детектирующего устройства и приемника показаний. Выходом становиться последовательная передача данных с использованием различных протоколов. Термометр DS18B20, для этого, к слову, применяет трансляцию информации по одному проводу в цифровых последовательностях, используемых форматом передачи 1-Wire, что сильно экономит количество занятых контактов платы контроллера. Кроме того, можно в его рамках на единую линию вешать несколько детекторов аналогичного типа и получать результат от каждого из них.
Еще один плюс подключения ds18b20 к Ардуино — его независимость от среды измерения. То есть, датчик может определять температуру и газа, и жидкости, достаточно оснастить его водонепроницаемым корпусом для последнего случая.
Что «умеет» DS18B20
Выглядит DS18B20 Arduino достаточно просто, — небольшая микросхема с тремя или восемью ножками, из которых одна используется с целью передачи цифровых сигналов, а две для питания. Тем не менее, функций и возможностей и у нее очень много:
- Есть встроенная 64 битная постоянная память, содержащая среди прочего уникальный код каждого корпуса, используемый при адресации устройства;
- Для подключения к контроллеру нет необходимости в дополнительных компонентах, достаточно присоединить сенсор напрямую к любому из цифровых входов на Ардуино;
- Есть возможность подачи так называемого «тревожного сигнала» на логические цепи, если характеристики температуры отличаются от заложенных во внутреннюю память;
- Допустимо подключение нескольких датчиков на одной линии связи с бесконфликтной их работой;
- Диапазон определяемых температур от −55 °С до +125 °С;
- Точность 0.5 °С;
- Доступно изменение разрешающей способности от 9 до 12 бит;
- Передача данных осуществляется на одном канале по протоколу 1-Wire, причем для обмена достаточно единичной линии или двух проводников;
- Время получения показаний 750 мс;
- Температура измеряется в Цельсии;
- Для питания устройства достаточно чуть более 3 вольт.
Назначение выводов
Как уже говорилось, есть два варианта поставки термодатчика — микросхема с 8 ножками (8-PIN SOIC) или 3 (ТО-92). Из рисунка ниже видно, какие контакты для чего предназначены, включая их полную распиновку.
Линия связи при подключении должна быть задействована через подтягивающий резистор 4.7 кОм. Требование обуславливается работой самого протокола 1-Wire. Питание корпуса, хоть это и не рекомендуется для температур свыше 100 °С, можно организовать от линии данных шины:
Работа вышеописанной схемы обеспечивается внутренним конденсатором Cpp, накапливающим заряд от линии. Ее минус — в моменты трансляции измеренных данных в цифровой вид, из-за повышенного потребления, мощности может просто не хватить на само устройство. Поэтому и рекомендуется использовать схемы с раздельным питанием.
Схема подключения с использованием внешнего источника будет выглядеть по-другому:
Или же, следуя советам профессионалов, выполнить подключение можно также таким образом:
В представленном варианте, схема будет работать от сохраненного через диод заряда в конденсаторе. К сожалению, необходимость в двух проводах никуда не делась.
Если возникает необходимость в определении именно вида поступающего питания на сенсор, то можно произвести опрос самого термодатчика DS18B20, отправив сначала ему команду CС[hex] следом B4[hex]. На выходе будет 0, если применяется паразитное питание или 1 при раздельном.
Внутренняя структура микросхемы и памяти, шина 1-Wire
Для понимания принципа работы, вначале стоит ознакомиться с блок-схемой корпуса:
Любая работа с микросхемой производится всегда, начиная с трех процедур: инициализации, команды ROM и отправки функционального кода. После, при необходимости, идет обмен данными между датчиком и контроллером. В случае не соблюдения последовательности, — логическая часть DS18B20 станет в своеобразный «ступор», не реагируя до сброса. Единственным исключением здесь будут команды F0[hex] и EC[hex], первая из которых «Поиск ПЗУ», вторая «Определение тревоги датчика».
Понятие инициализации подразумевает подачу микроконтроллером краткосрочного импульса на шину 1-Wire длительностью 480 мс и ожидание им ответа от датчика в течении 60 мс. Сам сенсор, при своей готовности к работе, отправляет сигнал высокого уровня с длительностью до 240 мс.
Обмен данными в рамках шины 1-Wire производится по 1 биту, когда они передаются в определенные временные интервалы, начиная с младшего. Каждый фиксированный промежуток в 60 мс предназначен для хранения одного состояния, нуля или единицы.
В сущности, процесс работы в рамках 1-Wire всегда одинаков. Выполнив сброс, описанный ранее, и получив ответ о присутствии устройства на линии микроконтроллер должен выбрать, к какому именно датчику на шине обратиться. Для этого используются ROM команды. Полный их список шины 1-Wire:
Команда [hex] | Действие | |
---|---|---|
F0 | Поиск ROM | Определение устройств на линии. В текущем виде ответом будет номер каждого из датчиков |
33 | Чтение ROM | Применяется, если на 1-Wire находится только одно устройство, оно будет выбрано по умолчанию |
CC | Пропуск ROM | Отправка последующей команды всем устройствам шины |
55 | Совпадение ROM | Выбор конкретного датчика для ответа. После отсылки этой ROM команды следом должен быть отправлен 64 битный ИД подключенной точки, от которой будут ожидаться последующие ответы. |
EC | Поиск тревожного сигнала | Эта ROM команда вызовет отклик только тех DS18B20, на которых есть состояние тревоги |
После отправки ROM команды, идет обмен с конкретным датчиком и посылка функциональных кодов для него. В высоко уровневой части, все эти операции выполняются подключением готовых библиотек в Arduino IDE с кодом, который и будет производить необходимые временные задержки и подачу напряжения на выходах контроллера для шины 1-Wire.
Немного про ИД устройства. Он содержит в себе не только сам уникальный номер корпуса, но и информацию о семействе сенсора и его контрольную сумму.
С передачей данных разобрались. Теперь нужно рассмотреть структуру памяти EEPROM самой микросхемы. Это требуется знать по причине того, что сенсор всегда в ответ на функциональную команду BE[hex] отправляет все ее содержимое.
На запись доступны только байты 2–4, которые используются при работе функциональных команд. Значение температур измерителя читается из 0–1, а 5–7 зарезервированы и всегда возвращают 1. В 8 хранится код CRC позволяющий проверить правильность прочтенных байт памяти.
С регистром конфигурации все немного сложнее. Из представляющего его байта используется только 5 и 6 бит, устанавливающий разрядность датчика. При запуске они равны 11, что означает 12 битное представление числа измеренной температуры. Чем оно выше, тем дольше логический сенсор будет преобразовывать его. В следующей таблице представлены значения битов R0(6) и R1(5), соответственно шестого и пятого по очереди в байте конфигурации, а также зависимость разрядности от них:
Регистры Th и Tl используются только с целью задания промежутка значений температуры порога тревоги. Их содержимое, как и конфигурацию можно сохранять в энергонезависимой памяти устройства.
Функциональные команды
Все это хорошо, но теперь нужно разобраться с самими функциональными командами сенсора.
Функциональная команда [hex] | Название | Действие |
---|---|---|
BE | Читать память датчика | После получения команды, сенсор выгружает на шину передачи данных 9 байт состояния своей памяти |
4E | Записать параметры и регистры | Контролер, отправивший эту команду следом должен отослать 3 байта – Th, Tl и значение регистра конфигурации |
48 | Копирование в EEPROM | Th, Tl и конфигурация помещаются из оперативной памяти в энергонезависимую, откуда они будут восстановлены после перезагрузки |
B8 | Сброс | |
B4 | Опрос питания |
Функциональная команда [hex]НазваниеДействиеBEЧитать память датчикаПосле получения команды, сенсор выгружает на шину передачи данных 9 байт состояния своей памяти4EЗаписать параметры и регистрыКонтролер, отправивший эту команду следом должен отослать 3 байта – Th, Tl и значение регистра конфигурации48Копирование в EEPROMTh, Tl и конфигурация помещаются из оперативной памяти в энергонезависимую, откуда они будут восстановлены после перезагрузкиB8Сброс
B4Опрос питания
Пример работы
Итак, с теоретической основой закончили, можно приступать к соединению датчика температуры и Arduino. Схема подключения:
Естественно, речь идет об использовании сенсора в воздушной среде. В том случае, если требуется измерять нагрев жидкости, то нужен герметичный датчик температуры DS18B20.
Алгоритм обработки
Сама последовательность действий достаточно проста. Только для упрощения, в приведенном примере, она рассчитана на наличие единственного сенсора на линии 1-Wire.
- Определить ИД датчика термостата
- Отправить команду по ИД на измерение температуры
- Ждать 750 мс, пока устройство отработает и поместит данные в оперативную память
- Дать функциональную команду на чтение памяти датчика температуры ds18b20
Сам скетч для Arduino
Здесь требуется примечание. Существует множество библиотек работы с 1-Wire выполняющих подключение датчика температуры DS18B20 к Arduino. В представленном скетче, будет использоваться вариант «OneWire», которую можно скачать с официальной страницы разработчиков ПО Arduino (https://playground.arduino.cc/Learning/OneWire). Там же, есть информация для ознакомления со списком функций в библиотеке.
#include <OneWire.h>
OneWire DataSerial(8); // объект коммуникации
/* установка скорости порта */
void setup(){
Serial.begin(9600);
}
/* действия производимые при каждом цикле работы с датчиком */
void INIT_WIRE(){
DataSerial.reset(); // Сброс
DataSerial.write(0xCC); // Используется один датчик, поэтому поиск других не нужен
}
/* процедура обработки и получения данных */
void loop(){
byte BANK[2]; // Два байта температуры
INIT_WIRE();
DataSerial.write(0x44); // Функциональная команда определить нагрев среды
delay(750); // Пауза на работу устройства
INIT_WIRE();
DataSerial.write(0xBE); // Запрос памяти датчика
// Выгружаем байты из шины. Их 9 штук, но нужны только первые два – температура
BANK[0] = DataSerial.read();
BANK[1] = DataSerial.read();
// приводим в божеский вид, исходя из разрядности полученных значений в 12 бит (0.0625 в тексте скетча)
float TEMP = ((BANK[1] << 8) | BANK[0]) * 0.0625;
// Отправляем результат в порт
Serial.println(TEMP);
}
Есть нюанс в приведенном скетче, он относится к физической схеме подключения питания датчика и соответствующим взаимодействием процедур библиотеки. Если используется паразитное, то DataSerial.Write(0х44), о запросе температуры, нужно заменить на DataSerial.Write(0x44, 1).
Что касается конечных пользователей, то пользуясь этой инструкцией, им будет несложно выполнить подключение инфракрасного датчика ds18b20 температуры для Ардуино. Все достаточно прозрачно, скетч элементарен, а простота схемы достойна уважения.