Умный счётчик электроэнергии своими руками: мониторинг потребления в реальном времени

Пошаговое руководство: как собрать умный счётчик для мониторинга потребления энергии в реальном времени с ESP32, MQTT и Home Assistant. DIY проект для умного дома.
Приветствую всех, кто любит собирать полезные электронные штуки для дома! Сегодня мы займёмся проектом, который не только интересен с технической точки зрения, но и даёт реальную практическую пользу — умный счётчик электроэнергии. Я расскажу, как своими руками собрать систему, которая будет считывать показания с обычного индукционного или электронного счётчика, отправлять данные на сервер и позволит вам в реальном времени видеть, сколько энергии потребляет ваш дом, квартира или даже отдельный прибор.
Зачем это нужно? Во-первых, это просто увлекательно — превратить «немую» коробку на стене в часть вашей умной экосистемы. Во-вторых, это экономия: понимая, когда и что «жрёт» больше всего тока, можно оптимизировать потребление и снизить счета. И в-третьих, это основа для автоматизации: например, можно настроить уведомления о превышении порога или автоматическое отключение неэссенциальных приборов в часы пик.
В качестве «мозга» нашего проекта я выбрал ESP32. Эта плата идеальна для таких задач: у неё есть Wi-Fi для отправки данных, достаточная вычислительная мощность и низкое энергопотребление, что важно для круглосуточного мониторинга. Если вы ещё не определились с микроконтроллером, рекомендую почитать моё сравнение ESP32 vs ESP8266: Что выбрать для своего DIY-проекта в 2024 году.
Принцип работы и выбор датчика
Большинство современных счётчиков, даже индукционных (с диском), имеют световой индикатор — мигающий светодиод. Частота его мигания пропорциональна потребляемой мощности: например, 3200 импульсов на 1 кВт*ч. Наша задача — считать эти импульсы. Для электронных счётчиков с оптическим портом (обычно это тёмное окошко) принцип похож — там мигает инфракрасный светодиод.
Мы будем использовать фототранзистор или фотодиод в качестве датчика. Он будет реагировать на вспышки света от счётчика. Это бесконтактный метод, который не требует вмешательства в схему счётчика и не нарушает пломбы, что очень важно.
Что нам понадобится
- Микроконтроллер: ESP32 (например, DevKit V1). Подойдёт и ESP8266, но у ESP32 больше возможностей на будущее.
- Датчик: Фототранзистор (например, L-53P3C) или готовый модуль с фототранзистором и подстроечным резистором.
- Резисторы: 10 кОм (для подтяжки), 1-10 кОм (для настройки чувствительности, если используем отдельный фототранзистор).
- Макетная плата и провода.
- Корпус для аккуратного монтажа.
- Источник питания: USB-зарядка на 5В.
Сборка аппаратной части
Схема подключения очень проста. Фототранзистор работает как ключ: когда на него падает свет, его сопротивление падает, и на входе микроконтроллера появляется логический ноль. Когда темно — сопротивление высокое, и подтягивающий резистор формирует логическую единицу.
Подключим фототранзистор к пину GPIO4 ESP32.
// Схема подключения (фототранзистор в NPN-конфигурации):
// VCC (3.3V на ESP32) -> | Фототранзистор (коллектор)
// |
// GPIO4 (D4) ------------ | Фототранзистор (эмиттер) -> Резистор 10 кОм -> GND
//
// Важно: Длинная ножка фототранзистора — это обычно коллектор.
Если вы используете готовый модуль, просто подключите его выход (OUT) к GPIO4, VCC к 3.3V, а GND к земле.
Типичная ошибка: неправильная полярность фототранзистора или подключение его без подтягивающего резистора. Это приведёт к нестабильным показаниям или их отсутствию. Всегда проверяйте даташит на ваш конкретный компонент.
Настройка программной части
Мы будем использовать PlatformIO в VSCode или Arduino IDE. Убедитесь, что у вас установлена поддержка плат ESP32.
Шаг 1: Базовый скетч для подсчёта импульсов
Создадим простую программу, которая считает количество импульсов за определённый интервал времени (например, за 5 секунд) и выводит данные в Serial Monitor.
// Умный счётчик на ESP32 - базовый счётчик импульсов
// Датчик подключен к GPIO4
const int sensorPin = 4; // Пин подключения датчика
unsigned long pulseCount = 0; // Счётчик импульсов
unsigned long lastTime = 0; // Время последнего расчёта
const long interval = 5000; // Интервал расчёта в миллисекундах (5 сек)
float power = 0; // Рассчитанная мощность в Ваттах
float energy = 0; // Накопленная энергия в кВт*ч
// Константа счётчика: сколько импульсов соответствует 1 кВт*ч
// Узнайте это значение на передней панели вашего счётчика (например, 3200 imp/kWh)
const float impulsesPerKwh = 3200.0;
// Обработчик прерывания - вызывается при КАЖДОМ изменении сигнала
void IRAM_ATTR countPulse() {
pulseCount++;
}
void setup() {
Serial.begin(115200);
pinMode(sensorPin, INPUT_PULLUP); // Используем внутреннюю подтяжку к +3.3V
// Настраиваем прерывание на пине sensorPin.
// Прерывание срабатывает на FALLING (переход из HIGH в LOW, т.е. начало вспышки).
attachInterrupt(digitalPinToInterrupt(sensorPin), countPulse, FALLING);
Serial.println("Умный счётчик запущен. Ожидание импульсов...");
lastTime = millis();
}
void loop() {
unsigned long currentTime = millis();
// Каждые 'interval' миллисекунд вычисляем мощность и энергию
if (currentTime - lastTime >= interval) {
// Запрещаем прерывания на время чтения и сброса счётчика
detachInterrupt(digitalPinToInterrupt(sensorPin));
// Рассчитываем мощность (Ватты):
// (pulseCount / impulsesPerKwh) = кВт*ч за интервал времени
// Переводим интервал времени в часы: (interval / 1000.0 / 3600.0)
// Формула: P = (ΔE / Δt) = (pulseCount / impulsesPerKwh) / (interval / 1000 / 3600)
// Упрощаем: P = (pulseCount * 3600000) / (impulsesPerKwh * interval)
power = (pulseCount * 3600000.0) / (impulsesPerKwh * interval);
// Прибавляем потреблённую за интервал энергию к общему счёту
energy += pulseCount / impulsesPerKwh;
// Выводим данные в Serial
Serial.print("Импульсов за "); Serial.print(interval/1000); Serial.print(" сек: "); Serial.println(pulseCount);
Serial.print("Мощность: "); Serial.print(power); Serial.println(" Вт");
Serial.print("Накопленная энергия: "); Serial.print(energy, 4); Serial.println(" кВт*ч");
Serial.println("---");
// Сбрасываем счётчик и обновляем время
pulseCount = 0;
lastTime = currentTime;
// Включаем прерывание обратно
attachInterrupt(digitalPinToInterrupt(sensorPin), countPulse, FALLING);
}
// Небольшая задержка для стабильности
delay(10);
}
Важные моменты:
1. IRAM_ATTR: Этот атрибут помещает функцию обработки прерывания в оперативную память (IRAM), что гарантирует её быстрое выполнение.
2. digitalPinToInterrupt(sensorPin): Корректно преобразует номер пина в номер прерывания для ESP32.
3. Отключение прерываний: На время чтения и сброса переменной pulseCount мы временно отключаем прерывание, чтобы избежать конфликтов при записи.
Шаг 2: Отправка данных в систему умного дома (Home Assistant)
Теперь сделаем наш счётчик сетевым. Мы отправим данные через MQTT — это стандартный протокол для IoT. Для этого нам понадобится брокер MQTT. Его можно развернуть на том же сервере, где стоит Home Assistant, или использовать публичный тестовый брокер.
Установите библиотеки PubSubClient и WiFiManager через менеджер библиотек.
// Умный счётчик на ESP32 с отправкой данных по MQTT
#include <WiFi.h>
#include <PubSubClient.h>
#include <WiFiManager.h>
// Константы
const int sensorPin = 4;
const float impulsesPerKwh = 3200.0;
unsigned long pulseCount = 0;
unsigned long lastSendTime = 0;
const long sendInterval = 10000; // Отправляем данные каждые 10 секунд
float totalEnergy = 0; // Общая энергия с момента старта
// MQTT настройки
const char* mqtt_server = "192.168.1.10"; // IP вашего MQTT брокера
const char* mqtt_topic_power = "home/energy/power";
const char* mqtt_topic_energy = "home/energy/total";
const char* mqtt_client_id = "esp32_smart_meter";
WiFiClient espClient;
PubSubClient client(espClient);
void IRAM_ATTR countPulse() {
pulseCount++;
}
void setup_wifi() {
WiFiManager wm;
// При первом запуске создаст точку доступа для настройки Wi-Fi
// После настройки параметры сохранятся в памяти ESP32
bool res = wm.autoConnect("SmartMeter_AP");
if(!res) {
Serial.println("Не удалось подключиться к Wi-Fi. Перезагрузка...");
ESP.restart();
}
Serial.println("Подключено к Wi-Fi!");
Serial.print("IP адрес: ");
Serial.println(WiFi.localIP());
}
void reconnect_mqtt() {
while (!client.connected()) {
Serial.print("Попытка подключения к MQTT брокеру...");
if (client.connect(mqtt_client_id)) {
Serial.println("успешно!");
} else {
Serial.print("ошибка, код: ");
Serial.print(client.state());
Serial.println(" Повтор через 5 секунд...");
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
pinMode(sensorPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(sensorPin), countPulse, FALLING);
setup_wifi();
client.setServer(mqtt_server, 1883); // Стандартный порт MQTT
lastSendTime = millis();
}
void loop() {
if (!client.connected()) {
reconnect_mqtt();
}
client.loop();
unsigned long now = millis();
if (now - lastSendTime >= sendInterval) {
detachInterrupt(digitalPinToInterrupt(sensorPin));
// Расчёт мощности и энергии
float power = (pulseCount * 3600000.0) / (impulsesPerKwh * sendInterval);
totalEnergy += pulseCount / impulsesPerKwh;
// Публикация данных в MQTT
char msgPower[10];
char msgEnergy[15];
dtostrf(power, 1, 2, msgPower); // Преобразуем float в строку
dtostrf(totalEnergy, 1, 4, msgEnergy);
client.publish(mqtt_topic_power, msgPower);
client.publish(mqtt_topic_energy, msgEnergy);
Serial.print("Отправлено - Мощность: "); Serial.print(msgPower); Serial.print(" Вт, ");
Serial.print("Энергия: "); Serial.print(msgEnergy); Serial.println(" кВт*ч");
pulseCount = 0;
lastSendTime = now;
attachInterrupt(digitalPinToInterrupt(sensorPin), countPulse, FALLING);
}
delay(10);
}
Интеграция с Home Assistant
В Home Assistant добавьте MQTT-сенсоры через configuration.yaml:
# Пример конфигурации в configuration.yaml
sensor:
- platform: mqtt
name: "Потребляемая мощность"
state_topic: "home/energy/power"
unit_of_measurement: "W"
device_class: power
state_class: measurement
value_template: "{{ value | float }}"
- platform: mqtt
name: "Суммарное потребление энергии"
state_topic: "home/energy/total"
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
value_template: "{{ value | float }}"
После перезагрузки Home Assistant вы увидите новые сенсоры. Для них можно создать красивый дашборд с графиками.
Проверка результата и калибровка
- Физическая установка: Закрепите фототранзистор напротив мигающего светодиода на счётчике. Используйте чёрную изоленту или термоклей, чтобы оградить датчик от постороннего света. Идеально напечатать или подобрать небольшой корпус.
- Калибровка: Включите нагрузку с известной мощностью (например, обогреватель на 1000 Вт). Посмотрите на показания в Serial Monitor или Home Assistant. Если показания отличаются, можно ввести поправочный коэффициент в формулу расчёта мощности.
- Тестирование: Протестируйте систему в разных условиях: при разной освещённости в комнате, с разной нагрузкой. Убедитесь, что датчик не «ловит» помехи от ламп освещения.
Возможные проблемы и их решение
- Нет импульсов: Проверьте подключение датчика. Поднесите его к свету телефона — в Serial Monitor должны идти данные. Отрегулируйте положение относительно светодиода счётчика.
- Слишком много импульсов (шум): Увеличьте значение подтягивающего резистора (например, до 47 кОм) или добавьте небольшой конденсатор (10-100 нФ) между пином датчика и землей для фильтрации помех. Закройте датчик от внешнего света.
- Потеря соединения Wi-Fi/MQTT: Используйте
WiFiManagerдля удобного переподключения. Добавьте в код Watchdog таймер для автоматической перезагрузки ESP32 при длительном отсутствии связи.
Куда развивать проект
- Локальное сохранение данных: Добавьте microSD модуль для записи показаний на карту, чтобы данные не терялись при обрыве сети.
- Расширенная аналитика: Направляйте данные в базу данных (например, InfluxDB) и создавайте сложные отчёты в Grafana.
- Многотарифный учёт: Настройте логику для учёта потребления по разным тарифам (день/ночь), если ваш счётчик это поддерживает.
- Резервное питание: Для полной автономности добавьте аккумулятор и солнечную панель, особенно если счётчик вынесен в распределительный щиток на улице. Для таких энергоэффективных проектов отлично подходит Orange Pi Zero 3: самый доступный одноплатник для умного дома, если вы решите перенести логику на более мощный компьютер.
Заключение
Мы собрали полноценную систему мониторинга энергопотребления с нуля. Это отличный пример того, как с помощью недорогих компонентов и своих рук можно получить умный и полезный девайс, который обычно стоит немалых денег в готовом виде. Экспериментируйте, дорабатывайте проект под свои нужды и делитесь результатами! Удачи в сборке!
Понравилась статья?
Поставьте лайк и сохраните полезный материал в закладки.
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.
Мониторинг качества воздуха: CO2, PM2.5 и VOC своими руками на ESP32
DIY умный звонок с камерой на ESP32-CAM и Home Assistant
GPS-трекер на ESP32 для велосипеда или автомобиля: DIY-проект для умного дома
Умный аквариум своими руками: автодолив, контроль температуры и освещение по расписанию
DIY ИБП для Raspberry Pi: как не дать умному дому «уснуть» при отключении света
Умная кормушка для кота на ESP32: кормим питомца по расписанию