Термометр на ардуино своими руками
Я писал недавно статью, где подключал к arduino 4-разрядный 7-сегментный индикатор hs420561k-32, тогда упоминал, что хочу сделать градусник с выводом температуры на этот индикатор, только проблема была в отсутствии датчиков. И вот наконец-то приехала посылка с недостающими запчастями и можно продолжить проект. Температурных датчиков у меня три штуки – dht11, LM35 и DS18B20. Но использовать буду только LM35 и DS18B20, поскольку dht11 очень неточный, в даташите написано, что отклонения от реальной температуры составляют плюс-минус два градуса, а так же он работает только с положительной температурой.
Температурный датчик LM35. Подключение к arduino
Первый датчик, который будем использовать – это LM35, использовать его очень просто, тут даже дополнительные библиотеки не требуются, достаточно подключить к нему питание и считать данные на выходе с помощью аналогового пина arduino. LM35 работает с температурами от -55 до 150 градусов Цельсия и если верить даташиту, то погрешность составляет всего плюс-минус 0,25 градуса. Хоть датчик и обрабатывает до +150 градусов, но считать ардуиной сможем только до +110, хотя и это более чем достаточно для домашнего градусника. Поскольку этот датчик имеет высокую точность, но находится в корпусе TO92, без какой-либо дополнительной защиты, использовать его будем для измерения температуры в помещении.
Официальный мануал arduino рекомендует использовать для снятия показаний этого датчика опорное напряжение 1,1 В. Чтобы настроить arduino подобным образом достаточно использовать команду analogReference(INTERNAL) в функции setup. Далее достаточно просто, с нужным интервалом, считывать напряжение с выходной ножки(OUT) датчика. LM35 формирует напряжение 10 милливольт на один градус, таким образом имея опорное напряжение в 1,1 В легко обработать, довольно точно, данные.
Ниже на картинке показано, какая нога датчика LM35 за что отвечает.
Температурный датчик DS18B20. Подключение к arduino
Второй датчик, который будет использован – это цифровой DS18B20. Точность в этом случае не на много ниже — плюс-минус 0,5 градуса, а диапазон измерения температуры практически такой же: от -55 до +125 градусов Цельсия. Большим преимуществом является то, что датчик находится внутри влагозащитного корпуса, а так же имеется кабель длиной 1 метр, что позволяет вынести его на улицу, когда само устройство будет находиться в помещении. Еще из плюсов сюда можно добавить возможность подключение одновременно до 127 датчиков на один пин ардуино, только я даже предположить не могу, где это может пригодиться :).
Считывать данные с DS18B20 немного сложнее, чем с LM35, для удобства можно воспользоваться библиотекой OneWire. В комплекте с библиотекой идет уже готовый пример считывания данных с датчика. Информация о температуре передаются в байтах, которые необходимо сначала запросить, получить и перевести к человеческому виду. В коде примера это подробно прокомментировано, а так же в полном скетче проекта я добавил комментарии.
На картинке ниже показано, как подключать датчик DS18B20. Основным моментом является то, что необходимо использовать резистор сопротивлением 4.7 кОм для соединения провода, передающего данные и плюсовым.
Проблема вывода температуры на индикаторе hs420561k-32
Пока я разбирался с каждым датчиком по отдельности, а также когда подключал к arduino 4-х разрядный 7-сегментнтый индикатор, проблем ни каких не было, все прекрасно работало. Но стоило мне собрать все в кучу, на одну макетную плату и собрать код воедино, как сразу появилась серьезная проблема. Я писал в прошлой статье, что для одновременного вывода данных сразу на 4-х разрядах hs420561k-32 необходимо очень быстро по очереди выводить по одному разряду, тогда создается впечатление одновременного вывода четырех цифр, глаз не успевает уловить смену разрядов. В связи с таким способом вывода возникла сложность с одновременной работой датчика DS18B20, для его опроса требуется чуть больше секунды времени – в двух участках кода используется delay, который заставляет микроконтроллер ждать, 250 и 1000 миллисекунд. Сначала я сделал запрос к датчику раз в 30 секунд, но это не решило проблему – два раза в минуту датчик по секунде показывал непонятно что. Поэтому пришлось отказаться от delay и добавить другую аналогичную конструкцию в код, которая будет выполнять определенные куски кода с задержкой, а остальной код будет выполняться без задержек. Многопоточности в arduino, как оказалось, нет, но есть псевдомногопоточность, добиться ее можно используя не хитрую конструкцию с таймером, который отмеряет время в миллисекундах от старта работы микроконтроллера. Пример такого кода я приведу ниже:
Что использовалось в проекте:
- Arduino (я использовал arduino nano, но можно любую другую). Покупал тут: arduino nano
- Температурный датчик LM35. Покупал тут: Температурный датчик LM35 5 шт
- Температурный датчик DS18B20. Покупал тут: Температурный датчик DS18B20
- Дисплей hs420561k-32. Покупал тут: аналог дисплея hs420561k-32
- 1 резистор сопротивлением 4.7 кОм. Покупал тут:набор резисторов 700 шт. От 10 Ом до 1 МОм
- 8 резисторов сопротивлением 300 Ом. Покупал тут:набор резисторов 700 шт. От 10 Ом до 1 МОм
- 1 Сдвиговый регистр 74HC595. Покупал тут: сдвиговые регистры 10 штук
- Макетная плата. Я использовал с 830 отверстиями. Покупал тут: макетная плата
- Несколько соединительных проводов. Покупал тут: соединительные провода
Скетч уличного и комнатного термометра на arduino
Все сложные моменты, с которыми возникали сложности, в процессе создания термометра я описал, теперь остается только написать скетч, его код приведен ниже, а также доступен для скачивания тут: скачать.
Послесловие
Термометр работает, показывает температуры дома и на улице, только вся конструкция собрана на макетной плате, и использовать прибор в таком виде довольно неудобно. Поэтому в планах на будущее будет разработка удобного в эксплуатации устройства – напечатаю на 3D принтере корпус, а все провода нужно будет перенести на печатную плату, так же хочется убрать arduino и использовать atmega8. Это что касается планов на будущее, а пока в завершение статьи приложу видео работы термометра:
Как ни странно, обычный ЖК-монитор можно превратить в термометр. Это легко сделать с помощью вы можете легко сделать термометр самостоятельно с помощью электронного конструктора Arduino и, разумеется, ЖК-дисплея. В итоге последний будет работать как небольшая метеостанция. Как это работает, показано в заметке.
Электронный конструктор Arduino весьма популярен среди талантливых подростков и любознательных взрослых. Сегодня мы разберем, как с его помощью превратить обычный ЖК-дисплей в метеостанцию.
Как настроить ЖК-дисплей
Если вы хотите управлять ЖК-дисплеем с помощью Arduino, вам будут нужны, помимо самого конструктора и монитора, соединительный кабель, потенциометр и макетная плата Breadboard. Однако в интернете вы найдете множество практичных и доступных наборов Arduino, в которых все эти компоненты уже есть.
После карантина захотелось потренироваться в разводке плат в Easy EDA и их изготовлению методом ЛУТ, да и особого желания делать сразу что-то сложное не было. Поэтому на роль "подопытного кролика" выступил проект цифрового термометра. К тому же это был отличный шанс попрактиковаться в написании программ для МК на C++.
Немного теории
Основой термометра будет терморезистор. Терморезистор - это резистор, у которого его сопротивление меняется от температуры. Терморезисторы разделяют на 2 большие группы: с положительным коэффициентом сопротивления (Сопротивление растёт от температуры) и с отрицательным (Сопротивление понижается от температуры). От типа терморезистора зависят и необходимые расчёты.
Теоретический практикум
Для проекта был подобран следующий терморезистор (рис. 1). Данный артефакт ещё советских времён ( штекер "СШ-5"), но несмотря на свой возраст, работает отлично.
Рисунок 1 - терморезистор
Как показала быстрая проверка датчика - данный терморезистор с положительным коэффициентом сопротивления (Сопротивление растёт от температуры), что немного необычно (Большинство современных терморезисторов обладает отрицательным коэффициентом сопротивления).
После первичного осмотра необходимо снять зависимость сопротивления от температуры. Для этого нам понадобится образцовый термометр и мультиметр (рис. 2).
Рисунок 2 - необходимые инструменты
План замеров таков:
- Замеряем температуру и сопротивление датчика при комнатной температуре.
- Записываем результаты замеров.
- Замеряем температуру и сопротивление датчика при различной температуре (В горячей, холодной, тёплой воде и тд).
- Записываем результаты замеров.
- Повторяем пункты 3 - 4 до тех пор, пока значений будет не менее 3-х.
После снятия первичных значений необходимо их обработать.
Для этого необходимо:
- Определить ТКС (Температурный Коэффициент Сопротивления). Если ТКС 0, то зависимость на некотором участке диапазона близка к линейной. В моём случае ТКС > 0, а зависимость линейная (Значит терморезистор изготовлен из какого-то металла).
- Для положительного ТКС: вбиваем показания в Excel и строим график. Далее добавляем линию тренда и выводим полученное уравнение (рис. 3).
Рисунок 3 - получение прогноза температуры от сопротивления
T = 17.173R - 130.82,
где T - температура в градусах Цельсия, а R - сопротивление в килоомах. Данная функция понадобится позже, а именно при написании скетча.
P.s. Данный практикум больше служит для выяснения типа датчика, нежели для получения итоговой функции (Т.к. проще составить прямую зависимость значения АЦП от температуры).
Схема электрическая принципиальная
Рисунок 4 - схема электрическая принципиальная
Да, опять я не пользуюсь сдвиговыми регистрами или драйверами семисегментников. С другой стороны, проект простенький и поэтому особого смысла в экономии выводов ATMEGA328 я не видел. Датчик подключается в разъём H1, который вместе с резистором R1 образуют делитель напряжения. Напряжение с делителя напрямую поступает на аналоговый вывод МК. Данный узел необходим для измерения сопротивления терморезистора.
Печатная плата и 3D модель устройства
Так как изначальной идеей проекта была тренировка в разводке ПП в Easy EDA, то и делать плату мы будем в этой программе (рис. 5). Итоговый размер платы 90x63 мм.
Рисунок 5 - рисунок ПП в Easy EDA
Также для статьи была подготовлена 3D модель устройства (рис. 6).
Рисунок 6 - 3D модель устройства
Помимо большого количества дорожек и малой ширины промежутков между ними, плата ещё и двусторонняя, что доставит ещё дополнительных проблем при её изготовлении, но это нам и нужно (Изначальная цель проекта - изготовление сложной ПП в Easy EDA).
Перед печатью необходимо экспортировать плату в .pdf из программы (Верхний и нижний слои) в чёрно-белом варианте без шелкографии (Это легко настраивается в окне экспортирования (рис. 7)). Нижний слой экспортируется без изменений, а верхний зеркально!
Рисунок 7 - настройки экспортирования для верхнего слоя
Далее печатаем на лазерном принтере или несём PDFки в ближайший копицентр, где просим печать на лазерном принтере на глянцевой бумаге (Единственное, что надо учесть: Easy EDA экспортирует одну картинку на целый лист. Мне в копицентре из одиночной картинки на лист сделали лист с 4 копиями обеих сторон, но это могут делать не везде).
Изготовление печатной платы
После печати трафаретов их необходимо перенести на текстолит методом ЛУТ (Не принципиально, просто я им пользуюсь, да и многие тоже).
- Необходимо вырезать трафареты с запасом (по 5 мм с каждой стороны).
- Потом их необходимо совместить на просвет так, чтобы все отверстия совпали.
- Когда отверстия совпадут, скрепляем шаблоны по краям степлером (Аккуратно и не спеша). Лучше скреплять стороны по очереди, следя за отверстиями.
- После соединения шаблонов подготавливаем кусок текстолита по размерам платы и собираем "бутерброд".
- После выравнивания текстолита и шаблонов фиксируем "бутерброд" степлером.
Далее "бутерброд" необходимо разгладить с обеих сторон - тут нужен опыт, у меня так и не получается всё сделать идеально. После хорошо отмываем, так чтобы не осталось белого налёта на медном слое (Тут главное не перегреть плату при переносе рисунка утюгом, иначе налёт будет очень трудно снять), и получаем результат (рис. 8.1 и рис. 8.2).
Рисунок 8.1 - нижняя сторона ПП
Рисунок 8.2 - верхняя сторона ПП
Результат неидеален, но приемлем. Полученную "плату" кидаем в ваш любимый раствор для травления (Я пользуюсь медным купоросом) и вытравливаем плату. Потом отмываем, сверлим отверстия, паяем. Итоговый результат сборки представлен на рисунке 9.1 и рисунке 9.2.
Рисунок 9.1 - верх
Рисунок 9.2 - низ
Вспоминая о соотнесении отверстий на просвет степлером, считаю необходимым показать результат совмещения (рис. 10).
Рисунок 10 - результат совмещения слоёв
Также скажу пару слов о сборке: перед программированием МК необходимо убедится в качестве пайки и травления, иначе можно получить самые разные неприятные сюрпризы.
Практика
Когда дело доходит до практики, то начинаются проблемы с теорией. Основной причиной проблем стала плохая пайка аналогового входа МК, поэтому пришлось перелопатить весь делитель (рис. 11), чтобы понять где была проблема (Совет: Всегда проверяйте пайку мультиметром - это поможет избежать различных проблем). Поэтому все прошлые расчёты можно смело забыть (Но закон Ома забывать не советую) ;).
Рисунок 11 - окончательная схема
Изменения в схеме в основном коснулись делителя, а также был отвязан вывод AREF от +5 В. Теперь R1 притягивает пин PC0 к земле, и номинал резистора был изменён с 10 кОм до 8.1 кОм
Теперь что касается формул. Так как конфигурация делителя изменилась, а на момент отладки уже работал вывод целых чисел на дисплей, то гораздо проще и лучше стало построить график зависимости температуры от значения АЦП и спрогнозировать его (рис. 12).
Рисунок 12 - прогноз температуры от значения АЦП
Итоговой формулой для моего датчика (Напомню, он обладает положительным ТКС и имеет линейную характеристику) стало следующее выражение:
T = -0.7309*X + 378.49,
где T - температура в градусах Цельсия, а X - значение АЦП. Данная формула оказалась вполне рабочей и показания контрольного и самодельного термометров совпадают +- погрешность округления (обрезки дробной части =) ) (рис. 13).
Рисунок 13 - первое включение и тесты (Затемнение на фото вызвано высокой яркостью индикатора)
Помимо всего прочего, схему необходимо обеспечить питанием от стабильного источника напряжение, иначе показания будут "плавать".
Скетч
Помимо проблем с пайкой были ещё и проблемы с самой ATMEGA328PU: экземпляр, который я купил в радиомагазине тактируется исключительно от 1 МГц (брак какой-то), поэтому всеми любимый ардуино код пришлось переделать в гибридный вариант. Изменения в основном коснулись динамической индикации, так как при тактовой частоте 1 МГц ардуино код вызывал сильное мерцание сегментов. Поэтому пришлось писать динамическую индикацию на прямом обращении к регистрам портов (рис. 14).
Рисунок 14 - порты ATMEGA328P
У ATMEGA328P всего 3 порта: PORTB, PORTC, PORTD, из которых PORTC - аналоговый (Содержит АЦП). Как видно из рисунка 15 выводы кварца и даже "Reset" являются частью портов и могут быть сконфигурированы для работы с помощью фьюзов,как и обычные пины ("Reset" трогать не советую ;) ).
Для конфигурации порта необходимо использовать регистр DDR + "Имя порта" (B,C или D и тд.). Пример:
Нумерация битов идёт справа налево - это нужно помнить!"1" соответствует режиму выхода, "0" - входу.
Теперь краткий экскурс по правильному управлению большим количеством пинов. Пример:
Данный метод выводит значение, записанное по цифрам в массив data[]. В отличии от варианта на ардуино коде эта реализация более компактная и оптимизированная, но гораздо сложнее для понимания и отладки (Я потратил на отладку 2 дня).
И так. в массиве chisla[][] записаны коды чисел для семисегментного индикатора с общим анодом. Цикл for перебирает цифры в массиве data[] и подставляет их в один из индексов массива chisla[][], тем самым получая код нужной цифры. Далее массив из 0 и 1 необходимо преобразовать в двоичное число для регистра. На первый взгляд задача сложная, но на самом деле всё гораздо проще.
Для перевода кода цифры необходимо воспользоваться школьными познаниями в информатике: вспомнить перевод числа из десятичной системы счисления в двоичную. Умножая 0 и 1 на 2 в нужной степени мы получим необходимый двоичный код. Пример: для того чтобы "потушить" сегмент "А" необходимо на сегмент "А" подать 5В. Для этого согласно схеме необходимо подать "1" на вывод PC5, т.е. сформировать вот такое двоичное число: "B100000" или умножить 1 на 25 или на 32 (В двоичном виде 32 представляет собой как раз "B100000") =). Код на С++:
PORTC = 32 * chisla[data[i]][0];
В данном случае "0" или "1" берутся из массива chisla[][]. По такому же принципу работают и другие сегменты.
Теперь поговорим о переключении разрядов. Тут всё элементарно - побитовый сдвиг. Т.к. индикатор с общим анодом, то двигаем мы "1". Код на С++:
PORTC |= 1 14.07.2020 0 0
Вознаградить Я собрал 0 1
Полтора года назад* коллега по инженерству Димон попросил сделать термометр для рабочих нужд. Оказалось, что измерять околокомнатную температуру важных деталей нам просто нечем! Я взял на пробу несколько микросхем DS18B20, и после сборки макета точно понял — такому термометру работа найдётся и дома.
*Откопал черновик из июня 2019-го — не выбрасывать же?
Дисплей — первый попавшийся LCD 1602 с I2C-адаптером. Отображает показания каждого датчика и третью величину: среднее значение или разницу между ними.
Вспомогательное — резистор 4,7 кОм (R1).
Печатную плату делал по размеру дисплея и его I2C-адаптера, но регулировочное отверстие под потенциометр всё равно немного не совпало.
Включился и работает. Это ещё старая прошивка, которая показывала минус 127 градусов при отключённых датчиках. О текущей версии расскажу ниже.
О работе прибора
Ещё термометр отправляет в COM-порт температуру по каждому датчику, среднюю и разницу. Причём его можно подключить не только к компьютеру, но и к телефону — через OTG-кабель.
Сфера применения устройства довольно широка:
Дополнение от 31.10.20
С её помощью задаётся период опроса датчиков и вывода температуры на экран и в UART. Когда строка закомментирована, то период определяется библиотечным минимумом 750 мс. Если вам не хочется, чтобы цифры часто мельтешили, ставьте 2000 или 5000 мс.
В архиве к тому же лежат уже скомпилированные файлы .hex, которые можно скормить ISP-программатору.
Скетч и прошивки в .hex
Печатная плата в формате .lay6
Читайте также: