Цифровой датчик температуры ds18b20. Инструкция по применению датчика температуры DS18B20. Подключение цифрового датчика температуры DS18B20 к внешнему источнику питания

В ассортименте нашего магазина появился датчик температуры DALLAS 18B20 во влагозащищенном корпусе с широким диапазоном измеряемых температур от -55 до +125°С. Данные о влагозащищенности и максимальной температуре в +125 градусов сразу натолкнули на мысли об экстремальном тестировании в кипящей воде. Этим мы и займемся.

Компоненты для повторения (купить в Китае):

Данный датчик работает по шине 1-Wire.

Каждое такое устройство содержит уникальный 64-битный "ROM" код, состоящий из 8 битов, определяющих код серии, 48 бит уникального номера и 8 бит помехоустойчивого CRC кода.

Информация об измеренной температуре хранится в оперативной памяти датчика, которая состоит из 9 байт.

1 и 2 байты хранят информацию о температуре.

3 и 4 байты хранят соответственно верхний и нижний пределы температуры.

5 и 6 байты зарезервированы.

7 и 8 байты используются для сверхточного измерения температуры.

9 байт хранит помехоустойчивый CRC код предыдущих 8 байт.

Основные команды, используемые при работе с библиотекой:

search(addressArray)

Выполняет поиск следующего 1-Wire устройства, если устройство найдено, то в 8 байтный массив addressArray записывается его ROM код, иначе возвращает false.

reset_search()

Выполняет новый поиск с первого устройства.

reset()

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

select(addressArray)

Выполняет выбор устройства после сброса, передается ROM Код устройства.

write(byte)

Передает информационный байт на устройство

write(byte, 1)

read()

Считывает информационный байт с устройства

crc8(dataArray, length)

Вычисляет CRC код байтов из массива dataArray, длиной length

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

0x44 - провести измерение температуры и записать данные в оперативную память

0x4E - записать 3 байта в 3й, 4й и 5й байты оперативной памяти

0x48 - скопировать 3й и 4й байты оперативной памяти в EEPROM

0xB8 - скопировать данные из EEPROM В 3й и 4й байты оперативной памяти

Подключение к Arduino

Из датчика выходят три провода:

Красный: "+" питания.

Черный: "-" питания

Белый: Вывод выходного сигнала

Подключение датчика:

Красный: на + 5 Вольт Arduino.

Черный на любой из GND пинов--- Arduino.

Белый на любый цифровой вход Arduino (в примере D10).

Для работы датчика необходимо соединить сигнальный провод с проводом питания резистором номиналом 4.7 кОм.

Для начала рассмотрим самый полезный пример для работы с датчиком - вывод показаний температуры в монитор порта.

Пример программного кода

#include OneWire ds(10); // подключен к 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 < 8; i++) { Serial.write(" "); Serial.print(addr[i], HEX); } if (OneWire::crc8(addr, 7) != addr) { Serial.println("CRC is not valid!"); return; } Serial.println(); // the first ROM byte indicates which chip switch (addr) { case 0x10: Serial.println(" Chip = DS18S20"); // or old 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, 1); // начало коммуникации delay(1000); present = ds.reset(); ds.select(addr); ds.write(0xBE); // читаем значение Serial.print(" Data = "); Serial.print(present, HEX); Serial.print(" "); for (i = 0; i < 9; i++) { // смотрим 9 байтов data[i] = ds.read(); Serial.print(data[i], HEX); Serial.print(" "); } Serial.print(" CRC="); Serial.print(OneWire::crc8(data, 8), HEX); Serial.println(); // Преобразуем получненный данные в температуру // Используем int16_t тип, т.к. он равен 16 битам // даже при компиляции под 32-х битный процессор int16_t raw = (data << 8) | data; if (type_s) { raw = raw << 3; if (data == 0x10) { raw = (raw & 0xFFF0) + 12 - data; } } else { byte cfg = (data & 0x60); if (cfg == 0x00) raw = raw & ~7; else if (cfg == 0x20) raw = raw & ~3; else if (cfg == 0x40) raw = raw & ~1; } 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"); }

Dallas18B20 экстремальное тестирование

Как уже говорилось, мы решили устроить датчику экстремальное тестирование, но просто опускать датчик в кипяток это не интересно. Поместим датчик в стакан и прокипятим. Для наглядности в монитор порта будут выводиться значения температуры. На прикрепленном ниже видео видно плавное нарастание температуры. Хочется отметить что температура воды при нормальном атмосферном давлении не может быть выше 100 °С. При тестировании датчика в кипящей воде, максимально зафиксированная нами температура составила 99.87°С. Тест можно считать успешным.

В схему было добавлено реле, для автоматического отключения кипятильника при температуре 99.5°С. Чтобы не резать провода на кипятильнике подключим через розетку, внутри которой находится вышеупомянутое реле.

Важно

Датчик температуры находится в металлическом корпусе, переход от металла на кабель заизолирован термоусадочной трубкой. На металле трубка прилегает очень плотно, на кабеле слабее, через это место может, хоть вероятность и мала, просочиться вода. С целью избежания данной ситуации мы советуем не погружать датчик в воду целиком. Если у вас все таки есть такая необходимость, мы рекомендуем заизолировать данный участок более тщательно.

Код примера

#include OneWire ds(10); // подключен к 10 пину (резистор на 4.7к обязателен) void setup(void) { Serial.begin(9600); pinMode(3, OUTPUT); // Включаем кипятильник digitalWrite(3, LOW); } 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 < 8; i++) { Serial.write(" "); Serial.print(addr[i], HEX); } if (OneWire::crc8(addr, 7) != addr) { Serial.println("CRC is not valid!"); return; } Serial.println(); // the first ROM byte indicates which chip switch (addr) { case 0x10: Serial.println(" Chip = DS18S20"); // or old 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, 1); // начало коммуникации delay(1000); present = ds.reset(); ds.select(addr); ds.write(0xBE); // читаем значение Serial.print(" Data = "); Serial.print(present, HEX); Serial.print(" "); for (i = 0; i < 9; i++) { // смотрим 9 байтов data[i] = ds.read(); Serial.print(data[i], HEX); Serial.print(" "); } Serial.print(" CRC="); Serial.print(OneWire::crc8(data, 8), HEX); Serial.println(); // Преобразуем получненный данные в температуру // Используем int16_t тип, т.к. он равен 16 битам // даже при компиляции под 32-х битный процессор int16_t raw = (data << 8) | data; if (type_s) { raw = raw << 3; if (data == 0x10) { raw = (raw & 0xFFF0) + 12 - data; } } else { byte cfg = (data & 0x60); if (cfg == 0x00) raw = raw & ~7; else if (cfg == 0x20) raw = raw & ~3; else if (cfg == 0x40) raw = raw & ~1; } 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"); // Если температура достигает температуры кипения (с погрешностью), отключаем кипятильник if (celsius > 99.5) { digitalWrite(3, HIGH); } }

#include

OneWire ds(10); // Подключаем датчик к 10 цифровому пину

void setup(void) {
Serial.begin(9600);
pinMode(3, OUTPUT);
// Включаем кипятильник
digitalWrite(3, LOW);
}

void loop(void) {
byte i;
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;
}

// Проверяем не было ли помех при передаче
if (OneWire::crc8(addr, 7) != addr) {
Serial.println("CRC is not valid!");
return;
}
Serial.println();

// Определяем серию датчика
switch (addr) {
case 0x10:
Serial.println(" Chip = DS18S20");
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(0xBE); // Считываем оперативную память датчика

for (i = 0; i < 9; i++) {
data[i] = ds.read(); // Заполняем массив считанными данными
}

// Данные о температуре содержатся в первых двух байтах, переведем их в одно значение и преобразуем в шестнадцатиразрядное число
int16_t raw = (data << 8) | data;
if (type_s) {
raw = raw << 3;
if (data == 0x10) {
raw = (raw & 0xFFF0) + 12 - data;
}
}
else {
byte cfg = (data & 0x60);
if (cfg == 0x00) raw = raw & ~7;
else if (cfg == 0x20) raw = raw & ~3;
else if (cfg == 0x40) raw = raw & ~1;
}
celsius = (float)raw / 16.0;
fahrenheit = celsius * 1.8 + 32.0;
Serial.print("Temp = ");
Serial.print(celsius);
Serial.print(" C, ");
Serial.print(fahrenheit);
Serial.println(" F");

// Если температура достигает температуры кипения (с погрешностью), отключаем кипятильник
if (celsius > 99.5)
{
digitalWrite(3, HIGH);
}
}

Купить в России

В двух предыдущих статьях мы рассмотрели и . В этой статье мы рассмотрим схему подключения одного или нескольких датчиков к микроконтроллеру и программирование работы МК с датчиком (датчиками) по шине 1-Wire с внешним питанием

Типовая схема подключения датчиков DS18B20 к микроконтроллеру:


Как видно из схемы, датчик DS18B20 (или датчики) подключаются к микроконтроллеру, если они имеют общее питание, тремя проводниками:
— вывод №1 — общий провод (масса, земля)
— вывод №2 — он же DQ , по которому происходит общение между МК и DS18B20, подключается к любому выводу любого порта МК. Вывод DQ обязательно должен быть «подтянут» через резистор к плюсу питания
— вывод №3 — питание датчика — +5 вольт
Если в устройстве используется несколько датчиков температуры, то их можно подключить к разным выводам порта МК, но тогда увеличится объем программы. Датчики лучше подключать как показано на схеме — параллельно, к одному выводу порта МК.
Напомню о величине подтягивающего резистора:
«Сопротивление резистора надо выбирать из компромисса между сопротивлением используемого кабеля и внешними помехами. Сопротивление резистора может быть от 5,1 до 1 кОм. Для кабелей с высоким сопротивлением жил надо использовать более высокое сопротивление. А там где присутствуют промышленные помехи – выбирать более низкое сопротивление и использовать кабель с более большим сечением провода. Для телефонной лапши (4 жилы) для 100 метров необходим резистор 3,3 кОм. Если вы применяете «витую пару» даже 2 категории длина может быть увеличена да 300 метров»

Программирование работы микроконтроллера с датчиком DS18B20

Как происходит общение датчика DS18B20 с микроконтроллером мы рассмотрим используя даташит датчика и программу Algorithm Builder.

Последовательность операций общения
ОЧЕНЬ ВАЖНО следовать установленной последовательности (которая состоит из трех пунктов) каждый раз при обращении к DS18B20:
1. Инициализация
2. Команда ROM
3. Функциональная команда DS18B20
Только две команды выполняется в два шага: Поиск ROM и Поиск Аварии .

Инициализация DS18B20

Последовательность выполнения инициализации состоит из двух частей:
— импульс сброса — который формирует микроконтроллер
— импульс присутствия — который формирует DS18B20
Исходное состояние шины DQ, по которой происходит общение МК и датчика, — логическая 1, так как шина DQ «подтянута» через резистор к питанию.
По состоянию шины DQ можно определить подключен ли датчик к микроконтроллеру:
— если на шине логическая 1 — значит датчик подключен
— если не логическая 1 — значит датчик не подключен (или забыли подключить, или обрыв линии DQ)
Поэтому, последовательность выполнения инициализации можно дополнить еще одним пунктом — проверка подключения датчика. Но учтите, что эту проверку можно провести только при одном датчике.

Проверяем подключение датчика DS18B20:

Где:
— INI_DS18B20 — подпрограмма инициализации
— DQ_Pin — имя, которое я присвоил, разряду порта к которому подключен датчик (если смотреть по схеме, то это вывод PB0 порта В)
— DQ_Pin=1 — проверка подключения датчика — если на выводе DQ_Pin логическая единица то переходим по стрелке, если нет, то:
— 1—> Term_Error , где Term_Error — переменная в которую записывается код ошибки, в данном случае «1»
— Show_Term_Error — переход к подпрограмме вывода ошибки на дисплей
К примеру, при использовании трехразрядного семисегментного дисплея, можно вывести такую строчку:
— Er1 , что означает — возникла ошибка, код ошибки-1 (датчик не подключен)

Теперь заглянем в даташит датчика и посмотрим временной график процедуры инициализации:


Переводим график в слова:
1. Исходный уровень шины DQ — логическая единица (за счет подтягивающего резистора)
2. Микроконтроллер формирует импульс сброса:
— МК переводит шину DQ в состоянии логического нуля на время не менее 480 микросекунд
— МК отпускает шину (переводим вывод в режим приема), при этом шина DQ опять переходит в состоянии логической единицы
3. DS18B20 обнаружив перепад уровня на шине (с логического нуля на логическую единицу) через 15-60 микросекунд передает импульс присутствия — переводит шину DQ в состояние логического нуля на длительность 60-240 микросекунд
4. По завершению импульса присутствия DS18B20 возвращает шину DQ в уровень логической единицы (судя по графику — через 480 микросекунд, от окончания импульса сброса, шина должна стопроцентно вернуться в уровень логической единицы)

Теперь переведем это все на язык программы. Но при этом следует учесть, что в процессе инициализации могут возникнуть еще две ошибки:
— DS18B20 не выдал импульс присутствия
— после импульса присутствия от DS18B20 шина DQ не вернулась в состоянии логической единицы


На графике указаны минимальные временные характеристики, поэтому в программе они несколько завышены или взяты максимальные (из минимальных) значения:
— импульс сброса от МК — не 480 а 500 микросекунд
— пауза от окончания импульса сброса до импульса присутствия — 60 микросекунд
— возврат шины в состояние логической единицы после импульса присутствия через 420 микросекунд
Я надеюсь с первым вопросом — ИНИЦИАЛИЗАЦИЯ, мы разобрались
Переходим к следующему шагу обязательной последовательности — «Команда ROM»

Команда ROM

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

Каждая команда ROM имеет шестнадцатиразрядный код (также как и функциональные команды), поэтому для удобства в программе очень можно определить константы, которые имеют понятные названия команд, к примеру:


В этой таблице заданы константы нужных мне для работы с датчиками команд.
После первого шага — ИНИЦИАЛИЗАЦИЯ, и передачи датчику DS18B20 команды ROM, датчик готов выполнить функциональную команду.
В предыдущей статье я подробно рассказал и о командах ROM, и о функциональных командах, повторяться не буду (я про функциональные команды).

Два примера алгоритма работы с DS18B20:
1. При использовании одного датчика:
— выполняем инициализацию

— подаем датчику функциональную команду — «Конвертировать температуру» (измерить температуру)
В процессе конвертирования контролируем работу датчика — если на шине ноль, то конвертирование не закончилось, если на шине логическая единица — конвертирование закончено.
Теперь можно считать температуру с датчика:
— выполняем инициализацию
— подаем датчику команду ROM — «Пропуск ROM»
— подаем датчику функциональную команду — «Чтение памяти»
По команде «чтение памяти» датчик начинает передачу данных из своей памяти — все девять байт. Но нам нужны только первые два байта — в них записана текущая измеренная датчиком температура. Поэтому считываем только два первых байта и выходим из подпрограммы.

Вам необходимо измерить температуру в неблагоприятной для микросхем среде?

Датчик DS18B20 поможет вам измерить температуру воды в аквариуме или в чайнике. Можно использовать его для измерения температуры на улице и при этом не бояться, что датчик зальёт дождём. Дачники оценят возможность измерять температуру почвы в теплице и на участке.

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

Разрешение показаний настраивается и может составлять от 9 до 12 бит. Меньше разрешение - выше скорость преобразования.

Подключение

Герметичный датчик на основе микросхемы DS18B20 можно подключить двумя способами:

По трём проводам: питание (красный), земля (чёрный) и сигнал (белый).

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

Независимо от способа подключения, сигнальный провод необходимо соединить с питанием через резистор 4,7 кОм. При подключении только одного датчика, подойдёт и резистор на 10 кОм.

Для подключения датчика к Arduino или к макетной плате удобно будет использовать нажимной клеммник.

Для подключения 1-Wire устройств к Arduino существует готовая библиотека, а для работы именно с DS18B20 существует библиотека-надстройка от Майлса Бёртона.

Характеристики:
  • Напряжение питания: 3.0..5.5 В
  • Диапазон температур: -55°C..+125°C
  • Точность показаний температуры: 0.5 °С
  • Шаг показаний: 0.0625 °С
  • Интерфейс: 1-Wire
  • Длинна провода: 1 метр
  • Потребляемый ток: 1мА