Вывод с DS18B20 на LCD дисплей
Содержание
Задача
- Вывести показания с датчика температуры DS18B20 на LCD дисплей 1602
- Усложнить задачу, вывести изменение температуры с момента перезагрузки
- Вывести температуру с двух датчиков и разницу между ними
Базовые уроки
Подключение
- Дисплей подключается к питанию и шине I2C
- Датчик подключается на любой цифровой пин
- Можно подключить несколько датчиков на один пин
Библиотеки
- LiquidCrystal_I2C для дисплея
- microDS18B20 для термометра
Программа 1
Для начала просто выведем температуру с датчика на дисплей.
#include <LiquidCrystal_I2C.h> // подключаем библиотеку дисплея LiquidCrystal_I2C lcd(0x27, 16, 2); // адрес, столбцов, строк #include <microDS18B20.h> MicroDS18B20<2> sensor; // указываем пин void setup() { lcd.init(); // инициализация lcd.backlight(); // включить подсветку } void loop() { sensor.requestTemp(); // запросить температуру delay(1000); // ждём ответа lcd.home(); // курсор в 0,0 lcd.print(sensor.getTemp()); // выводим температуру lcd.write(223); // символ градуса lcd.print("C "); // С и пара пробелов для очистки }
Программа 2
Теперь будем выводить такую строку: “температура с момента запуска программы” -> “текущая температура”. Может быть полезным для исследования изменения температуры. Нам нужно завести переменную для хранения первого значения, назовём её prevT
. При запуске программы запросим температуру с датчика, подождём, запишем результат в переменную и будем выводить на дисплей как в предыдущем примере:
#include <LiquidCrystal_I2C.h> // подключаем библу LiquidCrystal_I2C lcd(0x27, 16, 2); // адрес, столбцов, строк #include <microDS18B20.h> MicroDS18B20<2> sensor; float prevT; // переменная для хранения температуры void setup() { lcd.init(); // инициализация lcd.backlight(); // включить подсветку sensor.requestTemp(); // запрос температуры delay(1000); // ждём prevT = sensor.getTemp(); // запомнили } void loop() { sensor.requestTemp(); // запрос температуры delay(1000); // ждём lcd.home(); // курсор в 0,0 lcd.print(prevT, 1); // вывод prevT с точностью 1 знак lcd.write(223); // градус lcd.print(' '); // пробел lcd.write(126); // стрелочка lcd.print(' '); // пробел lcd.print(sensor.getTemp(), 1); // текущая температура lcd.write(223); // градус }
Также можно вывести время, прошедшее с момента запуска программы, например в формате часы:секунды.
- У нас есть функция
millis()
, которая возвращает время работы программы в миллисекундах. millis() / 1000
даст нам секунды, запишем в переменнуюsec
.- Чтобы получить количество секунд в пределах одной минуты, разделим секунды на 60:
sec / 60
- Чтобы получить количество минут из общего количества секунд – нужно выполнить операцию остаток от деления, опять же на 60:
sec % 60
- Чтобы выводить значения с ведущим нулём (например 03 вместо 3), сделаем простое условие:
if (минуты < 10) lcd.print(0);
- Обернём вывод времени в функцию для лучшей читаемости кода
#include <LiquidCrystal_I2C.h> // подключаем библу LiquidCrystal_I2C lcd(0x27, 16, 2); // адрес, столбцов, строк #include <microDS18B20.h> MicroDS18B20<2> sensor; float prevT; // переменная для хранения температуры void setup() { lcd.init(); // инициализация lcd.backlight(); // включить подсветку sensor.requestTemp(); // запрос температуры delay(1000); // ждём prevT = sensor.getTemp(); // запомнили } void loop() { sensor.requestTemp(); // запрос температуры delay(1000); // ждём lcd.home(); // курсор в 0,0 lcd.print(prevT, 1); // вывод prevT с точностью 1 знак lcd.write(223); // градус lcd.print(' '); // пробел lcd.write(126); // стрелочка lcd.print(' '); // пробел lcd.print(sensor.getTemp(), 1); // текущая температура lcd.write(223); // градус printTime(); // выводим время } // функция вывода времени void printTime() { lcd.setCursor(0, 1); // курсор на вторую строку int sec = millis() / 1000; // общее количество секунд byte thisM = sec / 60; // количество минут if (thisM < 10) lcd.print(0); // ведущий 0 lcd.print(thisM); // минуты lcd.print(':'); // двоеточие byte thisS = sec % 60; // количество секунд if (thisS < 10) lcd.print(0); // ведущий 0 lcd.print(thisS); // секунды }
Программа 3
Следующая задача – опросить два термометра и вывести их текущие показания и разность.
- Для начала прошьём пример address_read из библиотеки microDS18B20
- Поочерёдно подключим два датчика, увидим их адреса и скопируем в блокнот
Далее аналогично примеру one_pin_many_sensors записываем полученные адреса в массивы и создаём два датчика. Дальнейшая работа ведётся с двумя датчиками:
#include <LiquidCrystal_I2C.h> // подключаем библу LiquidCrystal_I2C lcd(0x27, 16, 2); // адрес, столбцов, строк // полученные адреса uint8_t s1_addr[] = {0x28, 0xE1, 0x57, 0xCF, 0x4E, 0x20, 0x1, 0x3D}; uint8_t s2_addr[] = {0x28, 0xFF, 0x36, 0x94, 0x65, 0x15, 0x2, 0x80}; #include <microDS18B20.h> MicroDS18B20<2, s1_addr> sensor1; // Создаем термометр с адресацией MicroDS18B20<2, s2_addr> sensor2; // Создаем термометр с адресацией void setup() { lcd.init(); // инициализация lcd.backlight(); // включить подсветку } void loop() { // запрашиваем температуру sensor1.requestTemp(); sensor2.requestTemp(); // ждём delay(1000); // получаем и записываем в переменные float t1 = sensor1.getTemp(); float t2 = sensor2.getTemp(); lcd.home(); lcd.print(t1, 1); // температура 1 lcd.write(223); // градус lcd.print('-'); // "минус" lcd.print(t2, 1); // температура 2 lcd.write(223); // градус lcd.print('='); // "равно" lcd.print(t1 - t2, 1); // ищем разность и выводим lcd.write(223); // градус }
Домашнее задание
- Избавиться от
delay()
, использовать асинхронную конструкцию сmillis()
- Выводить на дисплей сообщение, если температура выше заданного “порога”
- Подключить два датчика без адресации (на разные пины)
20 Комментариев
Простой проект. Более того, мой первый. Чуть не наложил себе в руки из-за того что сделал всё чётко по инструкции, но на экране ничего не отображалось. Не буду описывать свои ухищрения, дело оказалось в настроечной крутилке позади экрана. Подкрутил и всё высветилось.
Именно поэтому в самом начале статьи дана ссылка на базовый урок по дисплею
Да мне ж быстрее-быстрее начать хотелось)
б….. Ты мой герой. Чуть не прослезился. Спасибо родной.
Мужики, значиться так. С Библиотекой microDS18B20 не хочет работать. Показывает температуру 0 градусов. С onewire (примеры) все хорошо. Причем месяц назад собирал, все работало. Подскажите, где косячу. Единственное что поменялось из условий – ядро и другой пк. Поставил gyvercor. Гугл говорит ставь резистор если 0, понятное дело ставил. Мультиметром тыкался все ок, напруга наваливает, все проходит и все контачит. Библа не отрабатывает.
попробуй на стандартном ядре, вдруг гуверкор слишком быстрый. Микродс18б20 актуальной версии работает отлично, даже на есп8266
microDS18B20 не работает на GyverCore!
починили, нужно обновить ядро и библу
плохой контакт с подтягивающим резистором (у меня тоже такое было)
на уно не работает пробовал перезагружать
поэтому паять надо
Алекс, почему в 1 примере 2 значения?
потому что первое запрос температуры а второе получение
Спасибо за подробный урок! Все сработало вместе с деталями из GyverKit PRO. Единственное, было бы классно для совсем новичков поизучать основы электрических законов. Что такое эти подтягивающие резисторы, почему они располагаются в схеме. Может быть добавлять в уроки принципиальную схему? Или ссылку на какой-то пакет с симуляцией электро деталей?
базовые уроки по электронике будут. А резисторы – требование из документации к датчику =)
Класс
HELP.
Не понимаю в чём проблема. Упираюсь в это..
Скетч использует 5978 байт (19%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 272 байт (13%) динамической памяти, оставляя 1776 байт для локальных переменных. Максимум: 2048 байт.
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0xad
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0xad
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0xad
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0xad
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0xad
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0xad
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0xad
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0xad
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0xad
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0xad
Problem uploading to board. See https://support.arduino.cc/hc/en-us/sections/360003198300 for suggestions.
Неверная библиотека найдена в D:\Arduino\libraries\firmware: нет заголовочных файлов (.h), найденных в D:\Arduino\libraries\firmware
Неверная библиотека найдена в D:\Arduino\libraries\libraries: нет заголовочных файлов (.h), найденных в D:\Arduino\libraries\libraries
Неверная библиотека найдена в D:\Arduino\libraries\schemes: нет заголовочных файлов (.h), найденных в D:\Arduino\libraries\schemes
Неверная библиотека найдена в C:\Users\holod\OneDrive\Документы\Arduino\libraries\firmware: нет заголовочных файлов (.h), найденных в C:\Users\holod\OneDrive\Документы\Arduino\libraries\firmware
Неверная библиотека найдена в C:\Users\holod\OneDrive\Документы\Arduino\libraries\libraries: нет заголовочных файлов (.h), найденных в C:\Users\holod\OneDrive\Документы\Arduino\libraries\libraries
Неверная библиотека найдена в C:\Users\holod\OneDrive\Документы\Arduino\libraries\schemes: нет заголовочных файлов (.h), найденных в C:\Users\holod\OneDrive\Документы\Arduino\libraries\schemes
библиотеку переустанови и проверь точка запятые поставлены везде
Alex помоги прикрутить датчик без i2c. СПАСИБО.