Выносной дисплей для счетчика воды своими руками
Подключаем счетчик воды к умному дому
Когда-то системы домашней автоматизации, или как их часто называют “умный дом”, были жутко дорогими и их могли позволить себе лишь богачи. Сегодня на рынке можно найти достаточно бюджетные комплекты с датчиками, кнопками/выключателями и исполнительными устройствами для управлением освещением, розетками, вентиляцией, водоснабжением и другими потребителями. И даже самый криворукий DIY-шник может приобщиться к прекрасному и за недорого собирать устройства для умного дома.
Как правило предлагаемые устройства это либо датчики, либо исполнительные механизмы. Они позволяют легко реализовать сценарии вроде “при срабатывании датчика движения включить свет” или “выключатель возле выхода тушит свет во всей квартире”. Но вот с телеметрией как-то не сложилось. В лучшем случае это график температуры и влажности, или мгновенная мощность в конкретной розетке.
Недавно я себе поставил счетчики воды с импульсным выходом. Через каждый литр пробежавший через счетчик срабатывает геркон и замыкает контакт. Осталось дело за малым — прицепиться к проводам и попробовать из этого получить пользу. Например, анализировать потребление воды по часам и дням недели. Ну а если стояков для воды в квартире несколько, то удобнее видеть все текущие показатели на одном экране, чем лазить по труднодоступным нишам с фонариком.
Под катом мой вариант устройства на базе ESP8266, которое считает импульсы со счетчиков воды и по MQTT отправляет показания на сервер умного дома. Программировать будем на micropython с использованием библиотеки uasyncio. При создании прошивки я наткнулся на несколько интересных сложностей, о которых также расскажу в этой статье. Поехали!
Схема
Сердцем всей схемы является модуль на микроконтроллере ESP8266. Изначально планировался ESP-12, но мой оказался бракованный. Пришлось довольствоваться модулем ESP-07, который был в наличии. Благо они одинаковые и по выводам, и по функционалу, разница только в антенне — у ESP-12 она встроенная, а у ESP-07 — внешняя. Впрочем, даже без антенны WiFi сигнал в моей ванной ловится нормально.
Обвязка модуля стандартная:
- кнопка ресет с подтяжкой и конденсатором (хотя и то и другое уже есть внутри модуля)
- Сигнал enable (CH_PD) подтянут к питанию
- GPIO15 подтянут к земле. Это нужно только на старте, но мне все равно нечего на эту ногу цеплять больше не нужно
Состояние линии GPIO2 проверяется только вначале работы — при подаче питания или сразу после ресета. Так модуль либо загружается как обычно, либо переходит в режим прошивки. После загрузки этот вывод можно использовать как обычный GPIO. Ну а раз там уже есть кнопка, то можно повесить на нее какую нибудь полезную функцию.
Для программирования и отладки я буду использовать UART, который вывел на гребенку. Когда нужно — я просто подключаю туда USB-UART переходник. Нужно только не забывать, что питается модуль от 3.3В. Если забыть переключить переходник на это напряжение и подать 5В, то модуль скорее всего сгорит.
С электричеством в ванной у меня проблем нет — розетка расположена примерно в метре от счетчиков, так что запитывать буду от 220В. В качестве источника питания у меня будет трудится небольшой блочок HLK-PM03 от Tenstar Robot. Лично у меня туго с аналоговой и силовой электроникой, а тут готовый блок питания в маленьком корпусе.
Для сигнализации режимов работы я предусмотрел светодиод, подключенный к GPIO2. Впрочем распаивать я его не стал, т.к. в модуле ESP-07 уже есть светодиод, причем подключенный к тому же GPIO2. Но на плате пускай будет — вдруг я захочу вывести этот светодиод на корпус.
Переходим к самому интересному. У счетчиков воды нет никакой логики, у них нельзя спросить текущие показания. Единственное что нам доступно это импульсы — замыкание контактов геркона каждый литр. Выводы герконов у меня заведены в GPIO12/GPIO13. Подтягивающий резистор я буду включать программно внутри модуля.
Пора подумать что делать если пропадет электричество. Первый вариант — на старте запрашивать у сервера начальные значения счетчиков. Но это потребовало бы существенного усложнения протокола обмена. Более того, работоспособность устройства в таком случае зависит от состояния сервера. Если бы после отключения света сервер не завелся (или завелся позже), то счетчик воды не смог бы запросить начальные значения и работал бы неверно.
Поэтому я решил реализовать сохранение значений счетчиков в микросхеме памяти, подключенной по I2C. Особых требований по размеру флеш памяти у меня нет — нужно сохранять всего 2 числа (количество литров по счетчикам горячей и холодной воды). Даже самый маленький модуль подойдет. А вот на количество циклов записи нужно обратить внимание. У большинства модулей это 100 тыс циклов, у некоторых до миллиона.
Казалось бы миллион это много. Но я за 4 года проживания в своей квартире потребил чуть более 500 кубов воды, это 500 тыс литров! И 500 тыс записей во флеш. И это только холодная вода. Можно, конечно, перепаивать микросхему каждые пару лет, но оказалось есть микросхемы FRAM. С точки зрения программирования это тот же самый I2C EEPROM, только с ооооочень большим количеством циклов перезаписи (сотни миллионов). Вот только пока все никак не доеду до магазина с такими микросхемами, поэтому пока постоит обычная 24LC512.
Печатная плата
Изначально я планировал делать плату в домашних условиях. Потому плата проектировалась как односторонняя. Но продолбавшись битый час с c лазерным утюгом и паяльной маской (без нее как-то не comme il faut), я все же решил заказать платы у китайцев.
Уже практически перед заказом платы я сообразил, что помимо микросхемы флеш памяти на шину I2C можно подцепить что нибудь еще полезное, например дисплей. Что именно на него выводить — пока еще вопрос, но развести на плате нужно. Ну а раз я собрался платы заказывать на фабрике, то ограничивать себя односторонней платой уже не было смысла, поэтому линии на I2C — единственные на задней стороне платы.
С односторонней разводкой также связан был один большой косяк. Т.к. плата рисовалась односторонняя, то дорожки и SMD компоненты планировалось размещать с одной стороны, а выводные компоненты, разъемы и блок питания с другой. Когда через месяц я получил платы, то забыл про изначальный план и распаял все компоненты на лицевой стороне. И только когда дело дошло до припаивания блока питания выяснилось, что плюс и минус разведены наоборот. Пришлось колхозить перемычками. На картинке выше я уже поменял разводку, но земля перекидывается из одной части платы в другую через выводы кнопки Boot (хотя можно было бы и на втором слое дорожку провести).
Получилось вот так
Корпус
Следущий шаг — корпус. При наличии 3D принтера это не проблема. Особо не заморачивался — просто нарисовал коробку нужного размера и сделал вырезы в нужных местах. Крышка крепится к корпусу на маленьких саморезах.
Я уже упоминал, что кнопка Boot может быть использована как кнопка общего назначения — вот ее и выведем на переднюю панель. Для этого я нарисовал специальный “колодец” где живет кнопка.
Внутри корпуса также располагаются пеньки, на которые устанавливается плата и фиксируется единственным винтом М3 (на плате больше места не оказалось)
Дисплей подбирал уже когда напечатал первый примерочный вариант корпуса. Стандартный двухстрочник в этот корпус не влазил, зато в сусеках обнаружился OLED дисплей SSD1306 128x32. Маловат, но мне на него не каждый день глазеть — покатит.
Прикидывая и так и эдак как от него будут проложены провода решил прилепить дисплей посреди корпуса. Эргономика, конечно, ниже плинтуса — кнопка сверху, дисплей снизу. Но я уже говорил, что идея прикрутить дисплей пришла слишком поздно и лень было переразводить плату, чтобы переместить кнопку.
Устройство в сборе. Дисплейный модуль приклеен на сопли термоклей
Конечный результат можно увидеть на КДПВ
Прошивка
Перейдем к программной части. Для вот таких небольших поделок мне очень нравится использовать язык Python (micropython)- код получается очень компактный и понятный. Благо тут нет необходимости спускаться на уровень регистров с целью выжимать микросекунды — все можно сделать из питона.
Вроде бы все просто, да не очень — в устройстве намечается несколько независимых функций:
- Пользователь тыкает в кнопку и смотрит на дисплей
- Литры тикают и обновляют значения во флеш памяти
- Модуль следит за сигналом WiFi и переконнекчивается если нужно
- Ну а без моргающей лампочки вообще нельзя
В проекте посерьезнее я использовал классическую вытесняющую многозадачность и FreeRTOS, но в данном случае гораздо более подходящей оказалась модель сопрограмм (coroutines) и библиотеки uasync . Причем питоновская реализация корутин просто бомбовая — для программиста все сделано просто и удобно. Просто пиши себе логику, только скажи в каких местах между потоками переключаться можно.
Различия между вытесняющей и конкурентной многозадачностью предлагаю изучить факультативно. А сейчас давайте, наконец, перейдем к коду.
Каждый счетчик обрабатывается экземпляром класса Counter. Первым делом из EEPROM (value_storage) вычитывается начальное значение счетчика — так реализуется восстановление после пропадания питания.
Пин инициализируется со встроенной подтяжкой к питания: если геркон замкнут — на линии ноль, если разомкнут линия подтягивается к питанию и контроллер читает единицу.
Также тут запускается отдельная задача, которая будет производить опрос пина. Каждый счетчик будет запускать свою задачу. Вот ее код
Задержка в 25мс нужна для фильтрации дребезга контактов, а заодно она регулирует как часто просыпается задача (пока эта задача спит — работают другие задачи). Каждые 25мс функция просыпается, проверяет пин и если контакты геркона замкнулись, то значит через счетчик прошел очередной литр и это нужно обработать.
Обработка очередного литра тривиальна — просто увеличивается счетчик. Ну и новое значение неплохо было бы на флешку записать.
Для удобства использования предусмотрены “доступаторы”
Ну а теперь воспользуемся прелестями питона и библиотеки uasync и сделаем объект счетчика waitable (как это на русский перевести-то? Тот, которой можно ожидать?)
Это такая удобная функция, которая ждет пока значение счетчика не обновится — функция время от времени просыпается и проверяет флажок _value_changed. Прикол этой функции в том, что вызывающий код может уснуть на вызове этой функции и спать до получения нового значения.
Да, в этом месте вы меня можете потроллить, мол сам же сказал про прерывания, а на деле устроил тупой опрос пина. На самом деле прерывания это первое, что я попробовал. В ESP8266 можно организовать прерывание по фронту, и даже написать обработчик этого прерывания на питоне. В этом прерывании можно обновлять значение переменной. Наверное, этого бы хватило будь счетчик ведомым устройством — таким, которое ждет, пока у него не спросят это значение.
А еще время от времени вылетает RuntimeError: schedule stack full и кто его знает почему?
С явным опросом и uasync оно в данном случае как-то красивее и надежнее получается
Работу с EEPROM я вынес в небольшой класс
В питоне напрямую с байтами работать сложновато, а ведь именно байты записываются в память. Пришлось городить конвертацию между целым числом и байтами с использованием библиотеки ustruct.
Чтобы каждый раз не передавать объект I2C и адрес ячейки памяти я все это завернул в маленький и удобный классик
Сам объект I2C создается с такими параметрами
Подходим к самому интересному — реализации общения с сервером по MQTT. Ну сам протокол реализовывать не нужно — на просторах интернета нашлась готовая асинхронная реализация. Вот ее и будем использовать.
Все самое интересное собрано в классе CounterMQTTClient, который базируется на библиотечном MQTTClient. Начнем с периферии
Тут создаются и настраиваются пины лампочки и кнопки, а также объекты счетчиков холодной и горячей воды.
С инициализацией не все так тривиально
Для задания параметров работы библиотеки mqtt_as используется большой словарь разных настроек — config. Большая часть настроек по умолчанию нам подходит, но много настроек нужно задать явно. Чтобы не прописывать настройки прямо в коде я их храню в текстовом файле config.txt. Это позволяет менять код независимо от настроек, а также наклепать несколько одинаковых устройств с разными параметрами.
Последний блок кода запускает несколько корутин для обслуживания различных функций системы. Вот например корутина, которая обслуживает счетчики
Базовый класс MQTTClient сам себя обслуживает, сам инициирует соединение по WiFi и переподключается когда соединение пропадает. При изменениях в состоянии соединения WiFi библиотека нас информирует вызовом wifi_connection_handler
Функция честно слизана из примеров. В данном случае она считает количество отключений (internet_outages) и их длительность. При восстановлении соединения на сервер отправляется время простоя.
Кстати говоря, последний sleep нужен только для того, чтобы функция стала асинхронной — в библиотеке она вызывается через await, а так могут вызываться только функции в теле которых есть другой await.
Помимо связи с WiFi нужно еще установить соединение с MQTT брокером (сервером). Этим тоже занимается библиотека, а нам выпадает возможность сделать что нибудь полезное, когда соединение установлено
Парочка вспомогательных функций
Так много текста, а мы еще не моргали светодиодом. Вот
Я предусмотрел 2 режима моргания. Если пропало соединение (или оно только устанавливается), то устройство будет моргать быстро. Если соединение установлено — устройство моргает раз в 5 секунд. При необходимости тут можно реализовать и другие режимы моргания.
Но светодиод это так, баловство. Мы же еще на дисплей замахнулись.
Вот это то, о чем я говорил — как просто и удобно с корутинами. Эта маленькая функция описывает ВСЁ взаимодействие с пользователем. Корутина просто ждет нажатия кнопки и включает дисплей на 3 секунды. На дисплее отображаются текущие показания счетчиков.
Осталась еще пара мелочей. Вот функция которая это все хозяйство (пере)запускает. Основной цикл занимается всего лишь отсылкой разной отладочной информации раз в минуту. В общем, привожу как есть — особо комментировать, я думаю, не нужно
Ну еще парочка настроек и констант для полноты описания
Запускается это все так
Что-то с памятью моей стало
Итак, весь код есть. Файлики я заливал с помощью утилиты ampy — она позволяет заливать их на внутреннюю (ту, которая в самом ESP-07) флешку и потом доступаться из программы как к обычным файлам. Туда же я залил используемые мною библиотеки mqtt_as, uasyncio, ssd1306 и collections (используется внутри mqtt_as).
Запускаем и… Получаем MemoryError. Причем чем больше я пытался понять где именно утекает память, чем больше я расставлял дебаг принтов, тем раньше возникала эта ошибка. Короткий гуглеж привел меня к пониманию, что в микроконтроллере в принципе всего 30кб памяти в которые 65 кб кода (вместе с библиотеками) ну никак не помещаются.
Но выход есть. Оказывается micropython не исполняет код напрямую из .py файла — этот файл сначала компилируется. Причем компилируется он прямо на микроконтроллере, превращается в байткод, который потом хранится в памяти. Ну и для работы компилятора тоже нужен определенный объем оперативки.
Трюк заключается в том, чтобы избавить микроконтроллер от ресурсоемкой компиляции. Можно скомпилировать файлы на большом компьютере, а в микроконтроллер залить уже готовый байткод. Для этого нужно скачать прошивку micropython и собрать утилиту mpy-cross.
Я не стал писать Makefile, а вручную прошелся и скомпилировал все нужные файлики (включая библиотеки) примерно так
Осталось только залить файлики с расширением .mpy, не забыв предварительно удалить соответствующие .py с файловой системы устройства.
Все разработку я вел в программе (IDE?) ESPlorer. Она позволяет заливать скрипты в микроконтроллер и тут же их выполнять. В моем случае вся логика и создание всех объектов находятся находится в файле water_counter.py (.mpy). Но чтобы все это запускалось автоматически на старте должен быть еще файл с именем main.py. Причем это должен быть именно .py, а не пред-компилированный .mpy. Вот его тривиальное содержимое
Запускаем — все работает. Но свободной памяти угрожающе мало — порядка 1кб. У меня еще есть планы по расширению функциональности устройства, и этого килобайта мне явно будет маловато. Но оказалось и на этот случай есть выход.
Дело вот в чем. Даже при том, что файлы скомпилированы в байткод и находятся на внутренней файловой системе, на деле они все равно загружаются в оперативную память и выполняются оттуда. Но оказывается micropython умеет выполнять байткод прямо из флеш памяти, но для этого нужно встроить его непосредственно в прошивку. Это не сложно, хотя на моем нетбуке это заняло прилично времени (только там у меня оказался линукс).
И что с этим теперь делать?
Эти значения теперь можно связать с объектами системы, их можно использовать в сценариях автоматизации и подвергать различному анализу — все это out of scope этой статьи. Кому интересна система majordomo могу порекомендовать канал Электроника В Объективе — товарищ тоже строит умный дом и доходчиво рассказывает про настройку системы.
Покажу лишь пару графиков. Это простой график значений за сутки
Видно, что ночью водой почти никто не пользовался. Пару раз кто-то сходил в туалет, и, похоже фильтр обратного осмоса пару литров за ночь посасывает. Утром потребление существенно возрастает. Обычно я пользуюсь водой из бойлера, но тут я захотел принять ванную и временно переключил на городскую горячую воду — это также хорошо заметно на нижнем графике.
Из этого графика я узнал, что сходить в туалет это 6-7л воды, принять душ — 20-30л, помыть посуду около 20л, а чтобы принять ванную нужно 160л. За день моя семья потребляет где-то около 500-600л.
Для особо любознательных можно заглянуть в записи по каждому отдельному значению
Отсюда я узнал что при открытом кране вода течет со скоростью примерно 1л за 5с.
Но в таком виде статистику, наверное, не очень удобно смотреть. В majordomo есть еще возможности смотреть графики потребления по дням, неделям и месяцам. Вот, например, график потребления в столбиках
Пока у меня данных только за неделю. Через месяц этот график будет более показательным — каждому дню будет соответствовать отдельный столбик. Немного картину портят корректировки значений, которые я ввожу вручную (самый большой столбик). И пока не ясно, то ли я неправильно задал самые первые значения почти на куб меньше, то ли это баг в прошивке и не все литры пошли в зачет. Нужно больше времени.
Над самими графиками еще поколдовать нужно, побелить, покрасить. Возможно я также буду в отладочных целях строить график потребления памяти — вдруг там что-то утекает. Возможно буду как-то отображать периоды, когда отсутствовал интернет. Пока все это крутится на уровне идеи.
Заключение
Сегодня моя квартира стала чуточку умнее. С таким небольшим устройством мне будет удобнее следить за потреблением воды в доме. Если раньше я возмущался “опять много воды за месяц потребили”, то теперь я смогу найти источник этого потребления.
Кому-то покажется странным смотреть показания на экране, если он в метре от самого счетчика. Но в не очень отдаленном будущем я планирую переселиться в другую квартиру, где будет несколько стояков воды, а сами счетчики, скорее всего, будут расположены на лестничной площадке. Так что устройство удаленного снятия показаний будет весьма кстати.
Функциональность устройства я тоже планирую расширять. Я уже присматриваюсь к моторизованным вентилям. Сейчас для переключения бойлер-городская вода мне нужно поворачивать 3 крана в труднодоступной нише. Было бы гораздо удобнее делать это одной кнопкой с соответствующей индикацией. Ну и, само собой, защиту от протечек реализовать стОит.
В статье я рассказал свой вариант устройства на базе ESP8266. На мой взгляд у меня получился весьма интересный вариант прошивки на micropython с использованием корутин — просто и симпатично. Я постарался описать множество нюансов и косяков, с которыми столкнулся походу. Возможно я слишком детально все описывал, лично мне как читателю проще промотать лишнее, чем потом додумывать то, что было недосказано.
Подключаем Arduino к счетчикам воды
Уже достаточно давно я не писал на тему Arduino – как-то со временем не складывалось. Месяц назад знакомый решил установить водосчетчики, но, ввиду очень неудобно расположенных вводов труб в квартиру, считывать их показания приходилось чуть ли не с фонарем и в крайне неудобной позе. Возник вопрос – а можно ли как-то вывести показания с них на более удобное место или, в дальнейшем, автоматизировать сбор и отправку данных? Дело осложнялось тем, что нужен был бюджетный вариант (не более 1000 рублей) и в крайне короткие сроки. Я решил помочь, и вот что из этого получилось.
Что мы хотим получить:
1. Читать показания со счетчика горячей и холодной воды их состояние и выводить их на экран;
2. Хранить состояние счетчиков в энергонезависимой памяти микроконтроллера на случай пропадания питания;
3. Предусмотреть возможность корректировки показаний;
4. Предусмотреть возможность масштабирования (например, если в будущем мы захотим передавать данные по радиоканалу).
Что нам понадобится:
1. Arduino Nano - 1 шт.
2. Беспаечная макетная плата размера Half+ (хотя, подойдет и большая) – 1 шт.
3. ЖК-дисплей 2004 или 1602 с I2C-модулем. Если у Вас уже есть такой дисплей без I2С, то можно купить отдельно модуль и подключить его к дисплею. Да и, в принципе, можно обойтись без I2C – но в этом случае существенно увеличится количество проводов. Различие между 2004 и 1602 только в количестве строк и символов: 20x4 и 16x2 соответственно. Можем использовать любой, но я бы рекомендовал 2004 – на него еще и часы выведем) – 1 шт.
350 рублей за 2004 с I2C
4. Модуль часов реального времени. В моем случае использую DS1307. – 1 шт.
5. Соединительные провода male-male или перемычки – примерно 20 штук длиной около 10 см.
50-140 рублей. Если жаба не подписывает – можно купить моток одножильного тонкого провода и нарезать самим.
6. Клемники для подключения импульсных выводов счетчиков – 2 шт.
7. Тактовая кнопка для включения подсветки дисплея с колпачком на нее – 1 шт.
8. Необязательно: Модуль питания, позволяющий подключить обычный сетевой адаптер 6-12 вольт. Если Вы будете использовать питание через USB или от батареи – то без него можно обойтись. 1 шт.
9. Необязательно: Предусмотрите коробку, в которой разместите собранный блок. По моему опыту одним из лучших вариантов является бокс для монтажа электрощитков. Размер и стоимость их колеблются от 50 до 700 рублей.
Итого, менее чем за 1000 рублей мы можем собрать довольно удобное устройство для считывания и хранения показаний счетчиков воды.
Принцип работы импульсных счетчиков
На данный момент большинство счетчиков воды снабжены импульсными выходами. Если у вашего такого выхода нет – советую при следующей поверке озаботится их заменой на импульсные. Тем более что, как это ни странно, цена импульсных счетчиков обычно не отличается от простых той же модели (правда, встречал варианты с разницей цены в 100 рублей). Визуально такие счетчики отличаются наличием двухжильного провода. Собственно, внутри счетчика провод подключен к геркону и при проходе через счетчик очередных 10 литров геркон замыкается, а при проходе еще трех – размыкается. Как раз момент замыкания мы и будем ловить.
Описание принципов работы и подключения блока
Импульсные выводы счетчиков подключаем через клемники к нашей Arduino. При замыкании соответствующего выхода счетчик десятков литров увеличивается, соответственно, на 10, а при наборе 1000 литров – обнуляется счетчик литров и увеличивается на 1 счетчик кубометров. Все данные сразу же пишутся в энергонезависимую память EEPROM для того, чтобы при потере питания нам не пришлось бы выставлять начальные значения счетчиков заново.
Затем, при включенном дисплее (дисплей включается по кнопке примерно на 30 секунд) на экран выдаются обновленные значения показаний.
В отличие от предыдущих постов я не буду приводить код прошивки, а остановлюсь только на наиболее важных моментах, которые могут понадобиться при настройке.
Первый запуск, Обязательные параметры
При первом запуске нам надо установить ряд параметров, чтобы считыватель счетчиков верно работал. Таких параметра всего два:
1. Текущее время.
Для автоматической установки времени с компьютера при прошивке микроконтроллера установите значение константы SETTIME в 1 (строка 65). После прошивки и перезапуска, когда время будет установлено, верните значение константы в 0 и прошейте микроконтроллер заново – время будет сохранено в модуле RTC и не потребует повторной установки при пропадании питания. Если все же время не восстановилось после отключения – возможно у Вас разряжена батарея, установленная на модуле RTC: проверьте, при необходимости замените ее и заново установите время через константу SETTIME.
2. Базовые показания счетчиков горячей и холодной воды.
Для этого существуют два массива в строках 30 и 31:
В CounterHighBase содержатся показания кубометров для обоих счетчиков (сначала для холодной, потом для горячей воды), в CounterLowBase – показания для литров (то, что на вашем счетчике обычно обозначается красными цифрами). По умолчанию, если эти значения равны нулям, они берутся из энергонезависимой памяти. Если же любое из этих четырех значений отлично от нуля – оно записывается в память и далее будет считаться как базовое при следующем запуске. Например, если Вам надо при первой установке запомнить уже существующие счетчиков (допустим 01342,234 на счетчике горячей воды и 01637,110 на счетчике холодной), то эти две строки будут выглядеть следующим образом:
Обратите внимание, что лидирующие нули не пишутся – по стандартам языка С с нуля начинается число в восьмеричной системе счисления. После заливки прошивки с этими значениями в Arduino, нам надо перезапустить микроконтроллер и убедиться что значения попали в память (в этом нам поможет константа DEBUG или просто посмотрите на подключенный экран). Затем выставляем эти значения обратно в нули и заново перепрошиваем микроконтроллер.
Следующие параметры не нуждаются в обязательной модификации и понадобятся Вам, например, в том случае, если Вы решили убрать или добавить какой-то модуль, а также если Вы, в силу каких-то причин, не смогли или не захотели использовать полностью аналогичные указанным в схеме компонентам:
1. За настройку параметров экрана отвечают следующие константы:
LED_DELAY – время в миллисекундах, через которое экран будет автоматически гаснуть.
MOD_LCD_AUTO_OFF – По умолчанию установлен в 1. Если сбросить эту константу в 0, то автоотключение экрана будет недоступно, экран будет гореть до тех пот, пока мы не нажмем на кнопку включения/выключения экрана.
LCD_COL и LCD_ROW – Устанавливает количество строк и символов в строке на LCD-дисплее. Если количество строк больше двух, то в последней строке будет отображаться текущая дата и время.
2. Константы MOD_LCD и MOD_RTC – отвечают LCD-дисплей и часы реального времени. По умолчанию установлены в 1(включено). Если выставим MOD_LCD в 0, то информация на дисплей выдаваться не будет, но будет обрабатываться и сохраняться в памяти. Для чего это надо? Ну, например, если мы будем передавать данные со счетчиков по радиоканалу на некий приемник (как организовывать радиоканал я описывал в одном из предыдущих постов) – в этом случае для уменьшения потребления энергии дисплей мы можем отключить.
Константа MOD_RTC во включенном состоянии (1) указывает, что в системе присутствует модуль часов реального времени. Все данные, полученные со счетчиков будут запоминаться с учетом времени изменения. Также при отключении питания часы не надо будет выставлять заново. При отключенных часах этот функционал будет недоступен.
3. Константа DEBUG. По умолчанию выключена. Если включить ее (установить в 1) то, при подключении к компьютеру через USB-порт, лог событий можно будет просматривать в реальном времени (например, через “Монитор порта” в ArduinoIDE).
4. Константы BUTTON_PIN, HOT_COUNTER_PIN, COLD_COUNTER_PIN указывают, к каким выходам Arduino подключены кнопка выключения дисплея, счетчики горячей и хоодной воды.
Итого, если Вы соберете схему в точности с представленной в данном посте, Вам, для успешного запуска будет достаточно двух вещей:
1. Правильно установить время;
2. Установить значения счетчиков на момент подключения.
В результате у нас получается вот такое устройство:
Как я уже сказал, данный скетч разрабатывался с целью дать возможность легко подключать и отключать функциональные модули. Например, воспользовавшись одним из моих предыдущих постов, Вы легко сможете модифицировать код так, чтобы данные, считанные со счетчиков передавались по радиоканалу на другую Arduino, допустим, подключенную к локальной сети, а оттуда выводились в базу данных или на веб-страницу. Также, подключив GSM-модем или GSM-модуль организовать автоматическую передачу данных, например, в Вашу управляющую компанию. Работа c GSM-модулем или модемом мной еще не описывалась и может быть рассмотрена позднее в отдельном посте.
Ссылки на компоненты, используемые в данном устройстве.
Как уже стало традицией, ниже приведены ссылки на всем известный китайский магазин, где эти компоненты можно заказать.
1. Arduino Nano: Рекомендовал бы вариант вариант с MicroUSB – визуально качество изготовления лучше.
5. Соединительные провода
Вместо послесловия или к тем, кто задался вопросом “Зачем это вообще здесь?”
1. Да, я видел кучу статей на тему “подключаем счетчики к микроконтроллерам”. Но данная статья рассчитана именно на новичков, по возможности я попытался написать ее так, чтобы человек, мало знакомый с микроконтроллерами все же смог вынести из нее какую-то пользу.
2. Да, я знаю о ESP8266, STM32 и прочих. Но данная статья именно про Arduino (К любителям работать напрямую с мк Atmel это тоже относится).
3. Да, я знаю, что вы напишете код лучше. Но, очевидно, этот код работает, и работает достаточно хорошо (по крайней мере выполняет свои функции). Хотите улучшить? Флаг Вам в руки, никто не помешает это сделать.
В конце традиционно даю ссылку на архив с библиотеками, кодом и схемой самого блока:
И вопрос к подписчикам: делать пост про управление Arduino через GSM? Или информации, наличествующей в сети достаточно?
Устройства на микроконтроллерах
Бывает, что счетчики для воды стоят в таких неудобных местах, что снять показания с них это как совершить подвиг.
Далее представлена схема и программа для микроконтроллера Atmel AVR ATTiny84A для выносного дисплея двух счетчиков воды (холодной и горячей).
Ведется "помесячный" лог потребленной воды.
Используется строчный дисплей - LCD1602 на 3V.
Схема питается от 3.3V, плюс есть батарейка 3V для того, чтобы данные со счетчиков снимались, когда нет электричества.
Исторические данные хранятся в EEPROM микроконтроллера.
На дисплее показываются текущие показания в кубометрах, расход в этом месяце и расход в предыдущем месяце.Подсветка дисплея включается по датчику освещенности - чтобы в закрытом шкафу постоянно не горела.
Подключаем Arduino к счетчикам воды
Уже достаточно давно я не писал на тему Arduino – как-то со временем не складывалось. Месяц назад знакомый решил установить водосчетчики, но, ввиду очень неудобно расположенных вводов труб в квартиру, считывать их показания приходилось чуть ли не с фонарем и в крайне неудобной позе. Возник вопрос – а можно ли как-то вывести показания с них на более удобное место или, в дальнейшем, автоматизировать сбор и отправку данных? Дело осложнялось тем, что нужен был бюджетный вариант (не более 1000 рублей) и в крайне короткие сроки. Я решил помочь, и вот что из этого получилось.
Что мы хотим получить:
1. Читать показания со счетчика горячей и холодной воды их состояние и выводить их на экран;
2. Хранить состояние счетчиков в энергонезависимой памяти микроконтроллера на случай пропадания питания;
3. Предусмотреть возможность корректировки показаний;
4. Предусмотреть возможность масштабирования (например, если в будущем мы захотим передавать данные по радиоканалу).
Что нам понадобится:
1. Arduino Nano - 1 шт.
2. Беспаечная макетная плата размера Half+ (хотя, подойдет и большая) – 1 шт.
3. ЖК-дисплей 2004 или 1602 с I2C-модулем. Если у Вас уже есть такой дисплей без I2С, то можно купить отдельно модуль и подключить его к дисплею. Да и, в принципе, можно обойтись без I2C – но в этом случае существенно увеличится количество проводов. Различие между 2004 и 1602 только в количестве строк и символов: 20x4 и 16x2 соответственно. Можем использовать любой, но я бы рекомендовал 2004 – на него еще и часы выведем) – 1 шт.
350 рублей за 2004 с I2C
4. Модуль часов реального времени. В моем случае использую DS1307. – 1 шт.
5. Соединительные провода male-male или перемычки – примерно 20 штук длиной около 10 см.
50-140 рублей. Если жаба не подписывает – можно купить моток одножильного тонкого провода и нарезать самим.
6. Клемники для подключения импульсных выводов счетчиков – 2 шт.
7. Тактовая кнопка для включения подсветки дисплея с колпачком на нее – 1 шт.
8. Необязательно: Модуль питания, позволяющий подключить обычный сетевой адаптер 6-12 вольт. Если Вы будете использовать питание через USB или от батареи – то без него можно обойтись. 1 шт.
9. Необязательно: Предусмотрите коробку, в которой разместите собранный блок. По моему опыту одним из лучших вариантов является бокс для монтажа электрощитков. Размер и стоимость их колеблются от 50 до 700 рублей.
Итого, менее чем за 1000 рублей мы можем собрать довольно удобное устройство для считывания и хранения показаний счетчиков воды.
Принцип работы импульсных счетчиков
На данный момент большинство счетчиков воды снабжены импульсными выходами. Если у вашего такого выхода нет – советую при следующей поверке озаботится их заменой на импульсные. Тем более что, как это ни странно, цена импульсных счетчиков обычно не отличается от простых той же модели (правда, встречал варианты с разницей цены в 100 рублей). Визуально такие счетчики отличаются наличием двухжильного провода. Собственно, внутри счетчика провод подключен к геркону и при проходе через счетчик очередных 10 литров геркон замыкается, а при проходе еще трех – размыкается. Как раз момент замыкания мы и будем ловить.
Описание принципов работы и подключения блока
Импульсные выводы счетчиков подключаем через клемники к нашей Arduino. При замыкании соответствующего выхода счетчик десятков литров увеличивается, соответственно, на 10, а при наборе 1000 литров – обнуляется счетчик литров и увеличивается на 1 счетчик кубометров. Все данные сразу же пишутся в энергонезависимую память EEPROM для того, чтобы при потере питания нам не пришлось бы выставлять начальные значения счетчиков заново.
Затем, при включенном дисплее (дисплей включается по кнопке примерно на 30 секунд) на экран выдаются обновленные значения показаний.
В отличие от предыдущих постов я не буду приводить код прошивки, а остановлюсь только на наиболее важных моментах, которые могут понадобиться при настройке.
Первый запуск, Обязательные параметры
При первом запуске нам надо установить ряд параметров, чтобы считыватель счетчиков верно работал. Таких параметра всего два:
1. Текущее время.
Для автоматической установки времени с компьютера при прошивке микроконтроллера установите значение константы SETTIME в 1 (строка 65). После прошивки и перезапуска, когда время будет установлено, верните значение константы в 0 и прошейте микроконтроллер заново – время будет сохранено в модуле RTC и не потребует повторной установки при пропадании питания. Если все же время не восстановилось после отключения – возможно у Вас разряжена батарея, установленная на модуле RTC: проверьте, при необходимости замените ее и заново установите время через константу SETTIME.
2. Базовые показания счетчиков горячей и холодной воды.
Для этого существуют два массива в строках 30 и 31:
В CounterHighBase содержатся показания кубометров для обоих счетчиков (сначала для холодной, потом для горячей воды), в CounterLowBase – показания для литров (то, что на вашем счетчике обычно обозначается красными цифрами). По умолчанию, если эти значения равны нулям, они берутся из энергонезависимой памяти. Если же любое из этих четырех значений отлично от нуля – оно записывается в память и далее будет считаться как базовое при следующем запуске. Например, если Вам надо при первой установке запомнить уже существующие счетчиков (допустим 01342,234 на счетчике горячей воды и 01637,110 на счетчике холодной), то эти две строки будут выглядеть следующим образом:
Обратите внимание, что лидирующие нули не пишутся – по стандартам языка С с нуля начинается число в восьмеричной системе счисления. После заливки прошивки с этими значениями в Arduino, нам надо перезапустить микроконтроллер и убедиться что значения попали в память (в этом нам поможет константа DEBUG или просто посмотрите на подключенный экран). Затем выставляем эти значения обратно в нули и заново перепрошиваем микроконтроллер.
Следующие параметры не нуждаются в обязательной модификации и понадобятся Вам, например, в том случае, если Вы решили убрать или добавить какой-то модуль, а также если Вы, в силу каких-то причин, не смогли или не захотели использовать полностью аналогичные указанным в схеме компонентам:
1. За настройку параметров экрана отвечают следующие константы:
LED_DELAY – время в миллисекундах, через которое экран будет автоматически гаснуть.
MOD_LCD_AUTO_OFF – По умолчанию установлен в 1. Если сбросить эту константу в 0, то автоотключение экрана будет недоступно, экран будет гореть до тех пот, пока мы не нажмем на кнопку включения/выключения экрана.
LCD_COL и LCD_ROW – Устанавливает количество строк и символов в строке на LCD-дисплее. Если количество строк больше двух, то в последней строке будет отображаться текущая дата и время.
2. Константы MOD_LCD и MOD_RTC – отвечают LCD-дисплей и часы реального времени. По умолчанию установлены в 1(включено). Если выставим MOD_LCD в 0, то информация на дисплей выдаваться не будет, но будет обрабатываться и сохраняться в памяти. Для чего это надо? Ну, например, если мы будем передавать данные со счетчиков по радиоканалу на некий приемник (как организовывать радиоканал я описывал в одном из предыдущих постов) – в этом случае для уменьшения потребления энергии дисплей мы можем отключить.
Константа MOD_RTC во включенном состоянии (1) указывает, что в системе присутствует модуль часов реального времени. Все данные, полученные со счетчиков будут запоминаться с учетом времени изменения. Также при отключении питания часы не надо будет выставлять заново. При отключенных часах этот функционал будет недоступен.
3. Константа DEBUG. По умолчанию выключена. Если включить ее (установить в 1) то, при подключении к компьютеру через USB-порт, лог событий можно будет просматривать в реальном времени (например, через “Монитор порта” в ArduinoIDE).
4. Константы BUTTON_PIN, HOT_COUNTER_PIN, COLD_COUNTER_PIN указывают, к каким выходам Arduino подключены кнопка выключения дисплея, счетчики горячей и хоодной воды.
Итого, если Вы соберете схему в точности с представленной в данном посте, Вам, для успешного запуска будет достаточно двух вещей:
1. Правильно установить время;
2. Установить значения счетчиков на момент подключения.
В результате у нас получается вот такое устройство:
Как я уже сказал, данный скетч разрабатывался с целью дать возможность легко подключать и отключать функциональные модули. Например, воспользовавшись одним из моих предыдущих постов, Вы легко сможете модифицировать код так, чтобы данные, считанные со счетчиков передавались по радиоканалу на другую Arduino, допустим, подключенную к локальной сети, а оттуда выводились в базу данных или на веб-страницу. Также, подключив GSM-модем или GSM-модуль организовать автоматическую передачу данных, например, в Вашу управляющую компанию. Работа c GSM-модулем или модемом мной еще не описывалась и может быть рассмотрена позднее в отдельном посте.
Ссылки на компоненты, используемые в данном устройстве.
Как уже стало традицией, ниже приведены ссылки на всем известный китайский магазин, где эти компоненты можно заказать.
1. Arduino Nano: Рекомендовал бы вариант вариант с MicroUSB – визуально качество изготовления лучше.
5. Соединительные провода
Вместо послесловия или к тем, кто задался вопросом “Зачем это вообще здесь?”
1. Да, я видел кучу статей на тему “подключаем счетчики к микроконтроллерам”. Но данная статья рассчитана именно на новичков, по возможности я попытался написать ее так, чтобы человек, мало знакомый с микроконтроллерами все же смог вынести из нее какую-то пользу.
2. Да, я знаю о ESP8266, STM32 и прочих. Но данная статья именно про Arduino (К любителям работать напрямую с мк Atmel это тоже относится).
3. Да, я знаю, что вы напишете код лучше. Но, очевидно, этот код работает, и работает достаточно хорошо (по крайней мере выполняет свои функции). Хотите улучшить? Флаг Вам в руки, никто не помешает это сделать.
В конце традиционно даю ссылку на архив с библиотеками, кодом и схемой самого блока:
И вопрос к подписчикам: делать пост про управление Arduino через GSM? Или информации, наличествующей в сети достаточно?
Самодельный цифровой счетчик расхода воды
Итак, поехали:
1. Разбираем счетчик.
Img_20170103_142109. Самодельный цифровой счетчик расхода воды. Приборы и электр(он)ика.
Если потребуется, можно разобрать и саму емкость с расходным колесом. В регионе, где я живу - не очень хорошая вода и одна из причин забраковки моего счетчика - некорректные показания. После вскрытия счетчика выяснилась причина - довольно толстый слой солевых отложений и ржавчины.
Img_20170104_161604. Самодельный цифровой счетчик расхода воды. Приборы и электр(он)ика.
Лечится вымачиванием в туалетном "Утенке" для чистки унитазов. Для этих целей счетчик можно и не разбирать, а сразу залить "Утенком" измерительную полость счетчика на некоторое время.
2. Приклеиваем датчик Холла. В этой конструкции я использую один двухполярный цифровой датчик SS411A. Тут никаких нюансов нет, провод для подключения датчика я использую от старой компьютерной "мыши".
Img_20170103_183145. Самодельный цифровой счетчик расхода воды. Приборы и электр(он)ика.
Сразу припаиваю сопротивление 10 кОм для подтяжки на +:
Img_20170106_133036. Самодельный цифровой счетчик расхода воды. Приборы и электр(он)ика.
3. Собираем счетчик и приступаем к испытаниям. У меня под руками уже была Ардуино Нано, хотя было жалко использовать ее для вывода одного показания. Поэтому специально для этого счетчика заказал и получил Ардуино Pro Mini.
Подключаем наш расходомер к цифровому выводу D2, заливаем в контроллер скетч для проверки цифрового биполярного датчика Холла, включаем монитор порта, дуем в счетчик и . затаив дыхание видим меняющиеся "ON" и "OFF".
Img_20170127_223742. Самодельный цифровой счетчик расхода воды. Приборы и электр(он)ика.
Все, собственно электронно-механическая часть расходомера готова.
Завтра подключим наш расходомер к Ардуине.
Посл. ред. 27 Янв. 17, 23:25 от lospartos
Читайте также: