В данной статье мы рассмотрим подключение цифрового датчика температуры DS18B20 к плате Arduino Uno. Приведены схема и программа (скетч) для проекта.
Также на нашем сайте вы можете посмотреть проекты измерения температуры с помощью платы Arduino и датчиков lm35 и DHT11.
Необходимые компоненты
- Плата Arduino Uno (купить на AliExpress).
- Maxim Integrated DS18B20 Programmable Resolution (цифровой датчик температуры DS18B20) (купить на AliExpress).
- Резистор 4,7 кОм (купить на AliExpress).
- Макетная плата.
- Соединительные провода.
Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158
Общие принципы работы датчика температуры 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 вы можете посмотреть в следующей статье на нашем сайте.
Схема проекта
Схема подключения датчика температуры DS18B20 к плате Arduino Uno представлена на следующем рисунке.
Схема подключения датчика к плате Arduino достаточно проста: контакт 1 – к контакту GND Arduino, контакт 2 – к любому ее цифровому контакту (в нашем случае к контакту 2), контакт 3 – к ее контакту +5V или +3.3V. Также необходимо подключить подтягивающий (pull-up) резистор.
Исходный код программы (скетча)
Перед тем как загружать программу в плату Arduino необходимо скачать и извлечь из архива следующие библиотеки, необходимые для работы проекта:
- 1-Wire bus;
- Dallas Temperature (необходима для считывания и расчета температуры с датчика).
В скетче программы необходимо подключить заголовочные файлы этих библиотек.
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) 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); } |
На следующем рисунке показано тестирование работы проекта.
8 493 просмотров
Ну а в примере, который был с выводом информации о новом значении температуры в окно монитора последовательной связи, не было таких странных скачков с температурами? Примеры меню, которые вы привели, они для ЖК дисплея 16х2. Такие примеры есть и у меня на сайте и с таким меню я бы еще худо бедно мог бы вам помочь, но на ваш индикатор я даже не знаю как правильно информацию выводить. Как в этом случае я могу сделать вам меню?
То, что у вас температуры при нажатии кнопок прыгают, это совсем не из-за того, что у вас меню нет, здесь нужно искать другую причину. И запись в энергонезависимую память тоже никак от наличия меню не зависит, для этого можно просто выделить отдельную кнопку, при нажатии на которую информация будет записываться в память.
К сожалению, с меню на вашем индикаторе я не смогу помочь, могу попробовать помочь отладить программу в текущем варианте, без меню, чтобы температуры не прыгали
Ладно, Вы и так много сделали, за что Вам большое спасибо!!!
Проект замораживается.
Жаль, что вы его не доделали, как говорится, "на одном дыхании". Но будем надеяться что вы его в ближайшем будущем все же доделаете и напишите статью об нем на нашем сайте ))
Удачи.
По представленному скрину я вижу что у вас нажатия кнопки обрабатываются так, как я это запрограммировал. Значит, все нормально. Писать код для второй кнопки?
И после нажатия кнопки, я думаю, целесообразно сделать так, чтобы новое значение температуры загоралось на индикаторе на пару секунд для визуального контроля. Сможете сами в программу дописать код для вывода нового значения температуры на индикатор? Я могу объяснить куда в код программы это нужно вставить. Просто вы с этим индикатором уже разобрались больше чем я - у вас то он под рукой
Обрабатывается после исправления - https://disk.yandex.ru/d/u2_q2fWodyjmoA, вторую кнопку по аналогии сделал. Вряд ли смогу дописать код, т.к. нужен пример. Да, объясните, куда в код программы вставить это.
Ну в те блоки программы, где обрабатываются нажатия кнопок и происходит вывод нового значения температуры в окно монитора последовательной связи, туда добавьте высвечивание температуры на индикаторе (скопируйте его из того места программы, где выводите информацию на индикатор в основном цикле программы) и задержку на 2-3 секунды
Происходит такое: при нажатии кнопки, подключенной к D2, показания действующей температуры меняются на показания temp_min, затем снова показания действующей температуры, потом показания temp_min-0.1, так до показания temp_min=26.3, после чего последнее temp_min=25.3.
https://disk.yandex.ru/d/UnqPr1xr8gFABQ
Всё-таки устанавливаемые кнопками temp_min и temp_max лучше сделать в меню.
Не представляю чем кардинально меню может помочь в этой ситуации. Ситуацию, которую вы описали, мне не понятна - не должно так происходить если в программе все правильно. Может быть вы во время экспериментов какую-нибудь опечатку в код программы внесли? И где вы эту ситуацию наблюдали - в мониторе последовательного порта или на индикаторе?
И в коде программы, который вы прислали, что делает операция digitalRead(2) в блоке обработки нажатия кнопки? Это опечатка?
Ситуацию наблюдал на индикаторе. digitalRead(2) - ненужная строка в последнем скетче. В нем добавлено отображение на индикаторе temp_min при нажатой кнопке. Что получилось написал. Добавлю ещё то, что если отпустить кнопку во время отображения значения temp_min, а потом снова нажать, то отображается значение 25.3 на каком бы значении в процессе отсчета temp_min не отпускалась кнопка; дальнейшие нажатия на кнопку никакого значения temp_min не отображают. Это меня не устраивает. Нужно стандартное меню, в котором устанавливаются значения temp_min, temp_max, temp_upper_limit с занесением в EEPROM на случай отключения электроэнергии, которые могут быть просмотрены и изменены в любое время.
Примерно такое меню - allduino.forum2x2.ru/t12-topic или arduino.proweblab.xyz/arduino-pereklyuchenie-menyu-knopkoy, но только для индикатора ТМ1637 и с записью в EEPROM.
Давайте сделаем для начала две кнопки - одна будет повышать какой-нибудь предел температуры, а другая - понижать. А потом будем пытаться дальше усложнять. На сколько это у меня получится при таком формате удаленной работы, настолько помогу. Подойдет вам такой вариант?
Подойдет.
Скетч - https://disk.yandex.ru/d/EDmcan-1r-Ppqg
температура с десятыми, библиотека ТМ1637 с этого сайта - proto-constructor.ru/displei/17-displei-na-baze-drajvera-tm1637-izuchaem-vozmozhnosti.html
Хорошо, подскажите к каким контактам Ардуино будут подключены эти две кнопки и какой предел температуры в программе менять при их нажатии
К контактам D2 и D3 или аналоговым А6 и А7. Предел от 25.0 до 29.0 (с десятыми).
https://disk.yandex.ru/d/aqi4PdTLrhmUcw
Сегодня сил только на одну кнопку хватило, подключена к D2, срабатывает при подаче на D2 логического нуля. При нажатии происходит увеличение temp_max на 0.1 до тех пор пока temp_max не достигнет 29 градусов. Новое значение temp_max выводится в монитор последовательного порта. Если заработает, тогда дальше пойдем
Один контакт кнопки на общий, а другой к D2 с резистором на +5V или без резистора?
https://disk.yandex.ru/d/S_vYx4j56R8fCQ
немного исправил - https://disk.yandex.ru/d/u2_q2fWodyjmoA
При подключении MCP41010 и MAX7219 по SPI на MAX7219 ничего не будет отображаться, т.к. нужно разделить CS по разным контактам Arduino для MCP41010 и MAX7219.
learningaboutelectronics.com/Articles/Multiple-SPI-devices-to-an-arduino-microcontroller.php - вот один из примеров, но как это приспособить для нашего случая?
Вы какой то индикатор выбрали что с ним замучаешься разбираться как на нем что отображать. К сожалению, я не могу потратить кучу времени на то, чтобы разобраться с этим индикатором. Мне жутко не хватает времени для работы над сайтом
Хорошо, вернемся к ТМ1637. Вот два скетча https://disk.yandex.ru/d/sSro9K8Ma1pJ8A
wDS18B20-7 - изменение ступеней;
wDS18B20-7.1 - отображение температуры с десятичной точкой, но без десятых.
Как соединить их вместе для отображения на одном ТМ1637 изменений ступеней, на другом ТМ1637 - температуры (желательно с десятыми)?
Удалось соединить скетчи в один - https://disk.yandex.ru/d/fFT4PlaISwWAXw,
но с выводом десятых не получается.
Ещё остались кнопки для установки заданной температуры в целых значениях.
Фото пришлите плз как выглядит результат работы данного скетча на индикаторе
https://disk.yandex.ru/d/5MgGG2854bS_0w
Кнопки предполагаю так: кнопка "-", кнопка "меню", кнопка "+". При нажатии на кнопку "меню" отображается temp_min, кнопками "-" и "+" выставляется значение, следующее нажатие на "меню" - отображается заданное значение температуры, кнопками "-" и "+" выставляется значение, следующее нажатие на "меню" - отображается temp_max, кнопками "-" и "+" выставляется значение, следующее нажатие на "меню" - выход из меню. Установленные значения запоминаются в EEPROM.
А что у вас с десятыми не получается? Вроде по фото видно что они выводятся у вас на индикатор.
Что то с кнопками вы серьезный больно функционал хотите замутить. Я думал с их помощью нужно будет пределы температуры изменять. А меню, которое вы хотите, я даже не знаю как реализовать. Слишком долго в это вникать нужно
Десятые на фото не выводятся (большой индикатор), только черточка в третьем разряде, в четвертом знак градуса. С этим я сам разберусь.
Сделайте с кнопками по-своему.
Удалил потому, что вместо температуры отображались непонятные знаки. Как отобразить ступени в двух первых разрядах индикатора я не знаю.
Ну там символ градуса или фаренгейта отображается, а мои цифры почему то не хотят отображаться. Я не знаю как это исправить дистанционно.
Внес Ваши изменения в скетч и температура появилась! Теперь нужно добавить отображение ступеней (два левых разряда индикатора) и кнопки установки температуры.
Вот для меня это сложный проект - газовый котел всё-таки, где многое нужно учесть. Ваши удаленные правки всегда с моими экспериментами и обратной связью.
На всякий случай: https://www.youtube.com/watch?v=A9oOtKbNfck - убрал лишнее, хотя может быть и не всё - https://disk.yandex.ru/d/I7XxiMFKj-ItXw. Температуру показывает.
Ну вы картинку пришлите как у вас сейчас температура отображается, а то мне сложно пока представить куда нужно ступени отображать
https://disk.yandex.ru/i/DH11XHznnuqGSQ
ступени там, где обведено красной линией
Попробуйте эту программу
https://disk.yandex.ru/d/ofJjHf5AtIQ96g
Пришлите мне фото что высвечивается при этом на индикаторе
https://disk.yandex.ru/d/2GnOWM8X77c0mw -
фото с внесенными исправлениями в скетч (нарисовал в графическом редакторе градус и С слева на индикаторе, т.к. фото получается очень размытыми).
А зачем вы мои строки из программы удалили:
DispString[0] = 3;
DispString[1] = 4;
DispString[2] = 5;
DispString[3] = 6;
У меня просто есть сомнения относительно того как вам ступени в первых двух разрядах индикатора отображать. Или вы сами уже знаете как в этих двух разрядах числа отображать?
Датчика BMP180 нет в наличии.
Значит что-то в Вашем скетче не так - нет вывода температуры на индикатор.
Хорошо, попробуйте эту программу
https://disk.yandex.ru/d/wVfL9VO2_3Avxw
Это скетч с proto-constructor.ru, из которого удалена вся работа с датчиком BMP180. Он должен все время выводить на индикатор температуру 25 градусов
Выводит на индикатор температуру 25 градусов, если убрать строки
/*Создаём объект BMP180_Sensor класса SFE_BMP180*/
SFE_BMP180 BMP180_Sensor;
/*Инициализация датчика BMP180*/
BMP180_Sensor.begin();
В предыдущей программе те же самые строки для вывода информации на индикатор скопированы, а он не работает. Я не знаю почему так.
https://disk.yandex.ru/d/1_Jt7_36XsCFMA
в мониторе порта температура отображается, а на индикаторе нет - только 0 градус С горит. Не найду в чем проблема.
Измените функцию int GetTemperature() следующим образом:
{
/*Переменная для хранения замеренного значения температуры*/
double T;
//Работаем с датчиком DS18B20
temp.requestTemperatures();
T=temp.getTempCByIndex(0);
Serial.print(T);
return int(T);
}
А то у вас в ней переменная T объявляется, а ей ничего не присваивается. Естественно, что в этом случае на выход функции ничего не передавалось
Отсюда https://www.youtube.com/watch?v=A9oOtKbNfck все четко показывает.
Больше примеров подключения DS18B20 и MAX7219 не нашёл.
Да не в этом проблема, просто изначально ваш проект предполагался достаточно простым, а теперь вы в него добавляете все более сложные устройства, для которых и объем кода значительно возрастает. И в этом случае мне уже становится тяжело удаленно вам что то править
вот скетч https://disk.yandex.ru/d/n4bJSSwzcJlAcw отсюда https://www.youtube.com/watch?v=A9oOtKbNfck
Для упрощения можете удалить всё, что связано со вторым индикатором.
Слишком сложная программа, не имея доступа к железу этого проекта мне трудно в ней разобраться до уровня, чтобы для вас ее подправить. Может два предыдущих индикатора использовать? На один температуру выводить, а на другой - номер ступени?
Вот ещё нашёл по-проще - proto-constructor.ru/primery-primeneniya/15-chasy-na-arduino-variant-1/8-shag-5-vyvodim-temperaturu-na-displej.html,
нужно только заменить BMP180 на DS18B20 и добавить дробную часть.
Попробуйте эту программу
https://disk.yandex.ru/d/1y6sPwx5Cn9aYQ
Пока без дробной части
На индикаторе вообще ничего не светится. В мониторе порта показания отображаются.
Ну а сам пример с proto-constructor.ru у вас работает? Я же все оттуда взял
thesolaruniverse.wordpress.com/2018/08/08/four-digit-7-segment-led-display-for-arduino-based-on-the-tm1637-driver/?like_comment=1190&_wpnonce=960f2ed19e
Все равно не вижу. Можете на яндекс диск загрузить пример подобного скетча, который у вас заработал?
https://disk.yandex.ru/d/W5_HtEoaGgEmwg
Сделайте плз еще скрин работы этого скетча как он температуру на индикаторе отображает, а то пока не очень понятно
Температуру на индикаторе отображает так, как на Рис.3:Схема подключения в статье - 26 градус С.
Предлагаю всё-таки использовать индикатор на MAX7219 отсюда:
https://www.youtube.com/watch?v=A9oOtKbNfck
Убрать букву П на верхнем индикаторе, сделать два левых разряда для индикации ступеней регулирования 0 - 19. Уличная температура пусть остается. Соединить всё в один скетч.
Ну как хотите. Тогда попробуйте какой-нибудь скетч в сети для работы с индикатором на MAX7219, который у вас заработает. Ссылку мне тогда на статью с этим скетчем напишите, а я его в нашу программу интегрирую.
Температуру пока оставим без изменений.
Да, интегрировать скетч с сайта thesolaruniverse.wordpress.com, другого не нашел. Номера контактов на Ваше усмотрение. Как изменить задержку, чтобы не было мерцания?
Кстати, с 8-ми разрядным индикатором на MAX7219 (фото посылал) работали? Думаю проще будет сделать на одном индикаторе и температуру и показания уровня. Вот нашел
https://www.youtube.com/watch?v=A9oOtKbNfck
Нет, не работал. Попробуйте эту программу
https://disk.yandex.ru/d/6sMCZbs9txiVhg
Добавил в нее вывод ступени на индикатор, может, и не будет в ней никакого мерцания. Контакты 9 и 8 как и в примере на thesolaruniverse.wordpress.com
Ступени на индикаторе отображаются без мерцания. Как теперь отобразить температуру и ступени попеременно, к примеру по 10 секунд?
А температуру нужно отображать с десятыми долями градуса? Индикатор позволяет отображать десятичную точку?
Нужно отображать с десятыми. Да, точки отображает. В скетче с сайта thesolaruniverse.wordpress.com убрать знак С, градус оставить и сместить на место С, а вместо градуса сделать десятые.
А где там этот скетч? Что то я его не нашел
Да, нужно чтобы от нуля, чтобы состояние "Выключено" было обязательно, иначе котел не отключится.
Ясно, что несоответствие связано с функцией map.
А что с подключением индикатора?
Попробуйте тогда эту программу
https://disk.yandex.ru/d/nna9czgHn0DwAQ
Ну у вас получилось какой-нибудь пример с индикатором запустить из тех, ссылки на которые вы мне писали
https://disk.yandex.ru/d/irMV6B38L3CJ6A - при уменьшении и увеличении температуры.
С индикатором пока ничего не пробовал.
Ну работает как я и программировал. До 19 ступени показания не могут подняться потому что у нас шаг 2. Или вам еще что-нибудь нужно подправить?
thesolaruniverse.wordpress.com/2018/08/08/four-digit-7-segment-led-display-for-arduino-based-on-the-tm1637-driver/?like_comment=1190&_wpnonce=960f2ed19e
с этого сайта использовал скетч для индикатора и DS18B20 - все работает, только периодически мигание индикатора заметно. С чем это может быть связано?
Этого я не знаю, я же никогда с таким индикатором не работал. Можете еще с какого-нибудь сайта пример работы с таким индикатором попробовать, может в нем не будет мигания. Все равно работу с температурой пока не до конца отладили
Что ещё нужно отладить с температурой?
Этого я не знаю, это вы должны мне сказать. Ну если работа с температурой вас устраивает, то оставим ее пока без изменений и займемся другими задачами
Кнопки ещё нужно добавить для того, чтобы задавать температуру. Также сделать, чтобы на индикатор выводились показания уровня от 0 до 19.
Ну вам тогда в программу скетч с сайта thesolaruniverse.wordpress.com интегрировать? Не будете другой искать? К каким номерам контактов Ардуино тогда подключить ваш индикатор в программе.
Возможно, мерцание в скетче наблюдается из-за задержки всего в 250 мс, но это не точно
https://disk.yandex.ru/d/cuwbpiNmgvd_KQ
Должно быть stupen=0 (выкл) и только тогда level=0; при stupen=1 , level=13.
Почему не соблюдается соотношение 13 к 1 (к примеру,level=70 - stupen=6, а должно быть 78)?
То есть ступени можно опускаться до 0? Я могу тогда диапазон трансформации ступени задать от 0 до 19. Сейчас стоит от 1 до 19. Может быть это вам поможет.
Ну вы же сами когда делили одно на другое у вас получалось отношение 13 с чем то. Не преувеличивайте возможности функции map - она просто линейно трансформирует один диапазон в другой.
256/19=13,47
256/20=12,8 (это если я диапазон в программе изменю чтобы он с нуля начинался)