Как стать автором
Обновить
0
Timeweb Cloud
То самое облако

Каждая капля на счету или как я счетчик умным делал

Уровень сложностиСредний
Время на прочтение9 мин
Количество просмотров4.6K


Привет, Хабр!

В предыдущей статье я уже описывал бюджетное решение для интеграции электросчетчика в системы умного дома, где всё было реализовано на базе своего 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.

В итоге мы получили недорогое и полезное устройство для интеграции счетчиков воды в системы домашней автоматизации. Надеюсь, мой опыт будет полезен.

Если вам понравилась статья, поддержите её стрелочкой вверх. А если есть что добавить, то добро пожаловать в комментарии. Всем добра и спасибо за внимание.

Токи потребления и фото установки
Устройство в техническом отсеке:


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


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



Ссылки к статье:





Читайте также:

Новости, обзоры продуктов и конкурсы от команды Timeweb.Cloud — в нашем Telegram-канале

Теги:
Хабы:
Если эта публикация вас вдохновила и вы хотите поддержать автора — не стесняйтесь нажать на кнопку
+27
Комментарии22

Публикации

Информация

Сайт
timeweb.cloud
Дата регистрации
Дата основания
Численность
201–500 человек
Местоположение
Россия
Представитель
Timeweb Cloud

Истории