
Привет, Хабр!
В предыдущей статье я уже описывал бюджетное решение для интеграции электросчетчика в системы умного дома, где всё было реализовано на базе своего DIY устройства. Но не только из электросчетчика состоит «домашний» учет энергоресурсов, поэтому в данной статье хочу поделиться личным опытом разработки аппаратного устройства для интеграции бытовых счетчиков воды в системы домашней автоматизации. Присоединяйтесь, будет интересно!
❯ Небольшая предыстория
На тот момент я не имел счетчиков учета воды со смарт функциями, поэтому, для интеграции в свою систему умного дома, использовал проект AI on the edge device, который реализован на базе модуля ESP32 CAM и для распознания значения расхода использует алгоритмы машинного обучения (платформа Tensorflow lite) на базе компьютерного зрения.
Ниже фото установленного модуля для считывания показаний на базе ESP32 CAM:

Но в процессе эксплуатации у данного решения было выявлено несколько недостатков, а именно:
- Точность распознания — очень часто передавались ошибочные показания;
- Большое потребление, что затрудняет использование в местах с отсутствием доступа к сети питания;
- Сильный нагрев. Алгоритмы машинного зрения достаточно сильно нагружают модуль, что вызывает его перегрев;
Использовав данное решение несколько месяцев, я понял, что оно меня категорически не устраивает, поэтому решил разработать собственное, тем более, срок поверки установленных счетчиков подходил к концу и появилась возможность установить подходящие для моих целей счетчики. В итоге бы�� приобретен комплект счетчиков с импульсным выходом от компании ITELMA, цена вопроса 2247 руб или $25,84. Согласовав замену счетчиков с управляющей компанией, была произведена их установка.
Установка новых счетчиков ITELMA в техническом отсеке:

❯ Разработка аппаратного устройства
Итак, счетчики установлены, концы выведены, можно сказать, что половина дела сделана :) Далее нам предстоит немного интеллектуального труда, а именно — разработать принципиальную схему устройства, исходя их наших «хотелок» (назовем их «техническим заданием»). В итоге у меня сформировалось следующее ТЗ:
- Устройство должно быть реализовано на элементной базе, которая у меня имеется в наличии;
- Устройство должно иметь возможность работы от встроенного источника питания, соответственно, иметь низкое энергопотребление;
- Устройство должно иметь коммуникацию по беспроводной сети для подключения к системе умного дома и других сервисов;
С коммуникацией ясно, как и в прошлой статье, будем использовать микроконтроллер ESP8266 от компании Espressif Systems. Но для снижения потребления энергии нам придется перенести функцию подсчета импульсов на более энергоэффективный и маломощный микроконтроллер, так как ESP8266 в активном режиме потребляет много энергии (даже с отключенным радиомодулем), если рассматривать его в контексте автономного питания. К счастью, у меня есть под рукой кандидат, который справится с этой задачей — это проверенный временем микроконтроллер от компании Microchip Technology ATtiny 2313A. В результате у нас «вырисовывается» следующая принципиальная схема устройства.
Принципиальная схема устройства:

Для достижения максимальной энергоэффективности ATtiny 2313A, согласно технической документации, необходимо обеспечить уровень питающего напряжения в 1,8 В. Ниже приведена техническая информация возможностей данного микроконтроллера:
Возможности ATtiny 2313A-SU
Features • High Performance, Low Power AVR® 8-Bit Microcontroller • Advanced RISC Architecture – 120 Powerful Instructions – Most Single Clock Cycle Execution – 32 x 8 General Purpose Working Registers – Fully Static Operation – Up to 20 MIPS Throughput at 20 MHz • Data and Non-volatile Program and Data Memories – 2/4K Bytes of In-System Self Programmable Flash • Endurance 10,000 Write/Erase Cycles – 128/256 Bytes In-System Programmable EEPROM • Endurance: 100,000 Write/Erase Cycles – 128/256 Bytes Internal SRAM – Programming Lock for Flash Program and EEPROM Data Security • Peripheral Features – One 8-bit Timer/Counter with Separate Prescaler and Compare Mode – One 16-bit Timer/Counter with Separate Prescaler, Compare and Capture Modes – Four PWM Channels – On-chip Analog Comparator – Programmable Watchdog Timer with On-chip Oscillator – USI – Universal Serial Interface – Full Duplex USART • Special Microcontroller Features – debugWIRE On-chip Debugging – In-System Programmable via SPI Port – External and Internal Interrupt Sources – Low-power Idle, Power-down, and Standby Modes – Enhanced Power-on Reset Circuit – Programmable Brown-out Detection Circuit – Internal Calibrated Oscillator • I/O and Packages – 18 Programmable I/O Lines – 20-pin PDIP, 20-pin SOIC, 20-pad MLF/VQFN • Operating Voltage – 1.8 – 5.5V • Speed Grades – 0–4MHz@1.8–5.5V – 0–10MHz@2.7–5.5V – 0–20MHz@4.5–5.5V • Industrial Temperature Range: -40°C to +85°C • Low Power Consumption – Active Mode • 190 μA at 1.8V and 1MHz – Idle Mode • 24 μA at 1.8V and 1MHz – Power-down Mode • 0.1 μA at 1.8V and +25°C
Чтобы обеспечить данный уровень питающего напряжения, в схеме предусмотрен линейный регулятор LP2985-18DBVR с низким падением напряжения и имеющий ток собственного потребления 850 мкА при максимальном загрузочном токе в 150 мА.
Моя реализация подразумевает использование в качестве источника питания li-ion аккумулятор форм фактора 18650, но также в схеме предусмотрена возможность питания от элементов АА с напряжением 1,5 В.
И, да, я сторонник использования аккумуляторов в подобных системах, так как они меньше вредят экологии из-за большего срока эксплуатации, чем обычные элементы питания.
Ниже приведена визуализация проекта печатной платы.
Трассировка и габаритные размеры платы:

Рендер трехмерной модели платы:

❯ Изготовление печатной платы
Изготовление платы выполнялось «лазерным» методом, о котором я писал статью раннее. Я просто в восторге этого метода, он позволяет значительно ускорить процесс изготовления прототипов плат, обеспечивая высокое качество и значительную экономию времени. Для общего понимания, ниже показа��ые некоторые этапы изготовления:
Активация фоторезиста лазером:

Видео процесса:
Процесс активации паяльной маски лазером:
Плата после монтажа радиокомпонентов:

❯ Корпус устройства
Здесь всё просто, по классике DIY, модель корпуса была спроектирована во FreeCAD и напечатана на моем любимом и проверенным временем принтере Flyingbear Ghost 5.
Рендер модели корпуса:

Корпус после печати:

❯ Сборка устройства
Установка системы питания в корпус:

Как можно видеть на изображении, в качестве контроллера зарядки применен модуль на базе TP4056, а в качестве разъема питания — USB Type-C. И для улучшения качества связи, применена внешняя Wi-fi антенна с разъемом SMA. А в качестве световода, для отображения индикации заряда, был применен прозрачный термоклей. Я считаю что DIY без термоклея — это не DIY.
Установка платы в корпус. Для фиксации платы в корпусе предусмотрены специальные прорези.

Пример с моделью платы:

Поэтому печатная плата без труда устанавливается и фиксируется в корпусе, как показано ниже на изображении.

Устройство в собранном виде:

Порт зарядки и выключатель:

Как вы могли заметить, для крепления устройства на трубе в техническом отсеке, применена напечатанная клипса, которая прикрепляется к корпусу устройства с помощью двух винтов.
❯ Прошивка, интеграция в «Умный дом» интерфейс устройства
Прошивка устройства
Микро ПО устройства реализовано на моей «базовой» прошивке для умных устройств. Здесь я опишу несколько важных моментов, в остальном коде вы можете «поковыряться» на моем GitHub. Для простоты реализации, используется среда разработки Arduino IDE, а для программирования ATtiny 2313 — библиотека ATtiny Сore.
Так как в устройстве применяется два микроконтроллера: ESP8266 в качестве ведущего, а ATtiny2313 в качестве ведомого, то я хотел бы описать метод коммуникации между устройствами. Ниже представлен полный код прошивки ATtiny 2313:
Исходный код прошивки ATtiny 2313
#include <Wire.h> int32_t counter0 = 0; int32_t counter1 = 0; uint16_t data = 0; uint16_t data_t; void setup() { pinMode(4, INPUT_PULLUP); // Пин счетчика 1 pinMode(5, INPUT_PULLUP); // Пин счетчика 2 attachInterrupt(0, countPulses0, FALLING); // Прерывание на INT0 при падении сигнала attachInterrupt(1, countPulses1, FALLING); // Прерывание на INT1 при падении сигнала Wire.begin(18); // Устанавливаем адрес устройства I2C //PB5: SDA (Serial Data) - 12 //PB7: SCL (Serial Clock) - 14 Wire.onRequest(sendCounters); // Устанавливаем функцию обработки запроса на передачу данных } void loop() { sender(); // Это пустая функция в точке входа, чтобы контроллер работал, иначе не работает } void countPulses0() { counter0++; } void countPulses1() { counter1++; } void sender(){ if((millis() - data_t) > data*3600000 && data >= 1 ){ // Событие которое не сработает никогда data_t = millis(); digitalWrite(10, HIGH); while((data_t + 1000) > millis()){} digitalWrite(10, LOW); } } void sendCounters() { byte byteData[8]; // массив для хранения байтов byteData[0] = (counter0 >> 24) & 0xFF; // старший байт счетчика 0 byteData[1] = (counter0 >> 16) & 0xFF; byteData[2] = (counter0 >> 8) & 0xFF; byteData[3] = counter0 & 0xFF; // младший байт счетчика 0 byteData[4] = (counter1 >> 24) & 0xFF; // старший байт счетчика 1 byteData[5] = (counter1 >> 16) & 0xFF; byteData[6] = (counter1 >> 8) & 0xFF; byteData[7] = counter1 & 0xFF; // младший байт счетчика 1 Wire.write(byteData, 8); // Отправляем данные по шине I2C }
Как можно видеть, код довольно простой. И как вы уже, наверное, могли догадаться, связь между контроллерами обеспечивается по I2C шине. Функция обмена по шине реализована с помощью библиотеки <Wire.h>, где используются методы:
- Wire.begin(18) — назначает адрес устройства;
- Wire.onRequest(sendCounters) — установка функции обработки запроса на передачу данных;
- Wire.write(byteData, 8) — метод для отправки данных;
И чтобы не один импульс со счетчика не прошел мимо, используем аппаратное прерывание для регистрации:
attachInterrupt(0, countPulses0, FALLING); // Прерывание на INT0 при падении сигнала attachInterrupt(1, countPulses1, FALLING); // Прерывание на INT1 при падении сигнала
Обратите внимание, что для обеспечения энергоэффективного режима работы микроконтроллера ATtiny2313A, необходимо использовать внутренний генератор тактирования, частота которого должна составлять 1 МГц. На данную особенность указывает техническая документация:
– Active Mode • 190 μA at 1.8V and 1MHz
Данный параметр устанавливается в среде программирования:

Запрос со стороны ведущего ESP8266:
Здесь код запроса
void read_count(){ Wire.requestFrom(SLAVE_ADDRESS, 9); // Запрос данных у ведомого устройства while (Wire.available() < 9) {} // Ожидание доставки всех данных receiveData(); // Получение данных счетчиков } void receiveData() { byte byteData[8]; // Массив для хранения принятых байтов Wire.readBytes(byteData, 9); // Чтение данных из шины I2C uint32_t receivedCounter0 = ((uint32_t)byteData[0] << 24) | ((uint32_t)byteData[1] << 16) | ((uint32_t)byteData[2] << 8) | byteData[3]; // Собираем данные счетчика 0 uint32_t receivedCounter1 = ((uint32_t)byteData[4] << 24) | ((uint32_t)byteData[5] << 16) | ((uint32_t)byteData[6] << 8) | byteData[7]; // Собираем данные счетчика 1 uint32_t c0 = receivedCounter0 - receivedCounter0_storage; uint32_t c1 = receivedCounter1 - receivedCounter1_storage; if(receivedCounter1 != 4294967295 && receivedCounter0 != 4294967295){ if(c0 > 429496652 && c1 > 429496652){ L_1 = 0; L_2 = 0; }else{ L_1 = c0; L_2 = c1; } receivedCounter0_storage = receivedCounter0; receivedCounter1_storage = receivedCounter1; ESP.rtcUserMemoryWrite(0, &receivedCounter0_storage, sizeof(receivedCounter0_storage)); ESP.rtcUserMemoryWrite(sizeof(receivedCounter0_storage), &receivedCounter1_storage, sizeof(receivedCounter1_storage)); if(!config_st){ MQTT_send_data("json", JSON_DATA()); } } }
Интеграция в Home Assistant и интерфейс устройства
Конфигурация устройства выполняется через web интерфейс. При первоначальном подключении, устройство создает точку доступа CYBEREX-COUNT с беспарольным доступом. После подключения к точке доступа, у пользователя автоматически откроется страница авторизации, где необходимо будет ввести пароль по умолчанию «admin». После входа необходимо выполнить конфигурацию устройства. Интерфейс простой и интуитивно понятный. Ниже представлены скриншоты интерфейса.
Главная страница:

Конфигурация веса импульса:

Вес импульса необходимо взять из технической документации на установленный счетчик, данный параметр определяет количество потреблённой воды на один импульс.
Настройка MQTT протокола и периодичности отправки данных:

В данном устройстве реализован механизм MQTT Auto Discovery, позволяющий в автоматическом режиме добавлять объекты счетчика в Home Assistant.
Скриншот энергомониторинга:

И для возможности интеграции в Энергомониторинг Home Assistant, в MQTT запросе реализована передача параметра:
"state_class": "total"
При необходимости, Вы можете «собрать» карточку объектов для отображения данных нашего устройства.
Пример карточки объектов:

Аппаратные органы управления
На устройстве также присутствуют кнопки управления, которые отвечают за переход в режим конфигурации и отправку данных (она же функция перезапуска устройства).

Для перехода в режим конфигурации необходимо выполнить следующие действия:
- Зажать кнопку 1 и не отпуская, кратковременно нажать кнопку 2;
- Не отпуская кнопку 1, дождаться постоянного мигания светодиода (примерно 10 секунд);
- Отжать кнопку 1 и перейти в web интерфейс для конфигурации устройства.
❯ Итоги
Давайте подведем итоги. Данная статья вышла с задержкой в восемь месяцев, именно столько времени мне потребовалось, чтобы проверить работу данного устройства. Устройство показало себя с наилучшей стороны, точность и стабильность работы на высоте. Что касается энергопотребления устройства — оно соответствует моим ожидания и полностью меня устраивает:
- Ток потребления устройства в обычном режиме: 540 мкА; (ESP8266 (DeepSleep) — 25 мкА + ATtiny2313A (Active mode) — 190 мкА + Остальное — линейные регуляторы напряжения и подтягивающие резисторы );
- Ток потребления в режиме передачи данных: 74 мА (зависит от уровня сигнала сети в точке установки).
Бюджет проекта, если рассматривать стоимость «железа», составляет не более $ 5,66.
В итоге мы получили недорогое и полезное устройство для интеграции счетчиков воды в системы домашней автоматизации. Надеюсь, мой опыт будет полезен.
Если вам понравилась статья, поддержите её стрелочкой вверх. А если есть что добавить, то добро пожаловать в комментарии. Всем добра и спасибо за внимание.
Токи потребления и фото установки
Устройство в техническом отсеке:

Токи потребления. Активный режим (режим передачи данных):

Ток потребления в обычном режиме:


Токи потребления. Активный режим (режим передачи данных):

Ток потребления в обычном режиме:


