Привет, Хабр!
В предыдущей статье я уже описывал бюджетное решение для интеграции электросчетчика в системы умного дома, где всё было реализовано на базе своего 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 В. Ниже приведена техническая информация возможностей данного микроконтроллера:
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:
#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.
В итоге мы получили недорогое и полезное устройство для интеграции счетчиков воды в системы домашней автоматизации. Надеюсь, мой опыт будет полезен.
Если вам понравилась статья, поддержите её стрелочкой вверх. А если есть что добавить, то добро пожаловать в комментарии. Всем добра и спасибо за внимание.
Токи потребления. Активный режим (режим передачи данных):
Ток потребления в обычном режиме:
Ссылки к статье:
Автор: Valeriy