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

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

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

Пошаговое руководство: как собрать умный счётчик для мониторинга потребления энергии в реальном времени с 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 вы увидите новые сенсоры. Для них можно создать красивый дашборд с графиками.

Проверка результата и калибровка

  1. Физическая установка: Закрепите фототранзистор напротив мигающего светодиода на счётчике. Используйте чёрную изоленту или термоклей, чтобы оградить датчик от постороннего света. Идеально напечатать или подобрать небольшой корпус.
  2. Калибровка: Включите нагрузку с известной мощностью (например, обогреватель на 1000 Вт). Посмотрите на показания в Serial Monitor или Home Assistant. Если показания отличаются, можно ввести поправочный коэффициент в формулу расчёта мощности.
  3. Тестирование: Протестируйте систему в разных условиях: при разной освещённости в комнате, с разной нагрузкой. Убедитесь, что датчик не «ловит» помехи от ламп освещения.

Возможные проблемы и их решение

  • Нет импульсов: Проверьте подключение датчика. Поднесите его к свету телефона — в Serial Monitor должны идти данные. Отрегулируйте положение относительно светодиода счётчика.
  • Слишком много импульсов (шум): Увеличьте значение подтягивающего резистора (например, до 47 кОм) или добавьте небольшой конденсатор (10-100 нФ) между пином датчика и землей для фильтрации помех. Закройте датчик от внешнего света.
  • Потеря соединения Wi-Fi/MQTT: Используйте WiFiManager для удобного переподключения. Добавьте в код Watchdog таймер для автоматической перезагрузки ESP32 при длительном отсутствии связи.

Куда развивать проект

  1. Локальное сохранение данных: Добавьте microSD модуль для записи показаний на карту, чтобы данные не терялись при обрыве сети.
  2. Расширенная аналитика: Направляйте данные в базу данных (например, InfluxDB) и создавайте сложные отчёты в Grafana.
  3. Многотарифный учёт: Настройте логику для учёта потребления по разным тарифам (день/ночь), если ваш счётчик это поддерживает.
  4. Резервное питание: Для полной автономности добавьте аккумулятор и солнечную панель, особенно если счётчик вынесен в распределительный щиток на улице. Для таких энергоэффективных проектов отлично подходит Orange Pi Zero 3: самый доступный одноплатник для умного дома, если вы решите перенести логику на более мощный компьютер.

Заключение

Мы собрали полноценную систему мониторинга энергопотребления с нуля. Это отличный пример того, как с помощью недорогих компонентов и своих рук можно получить умный и полезный девайс, который обычно стоит немалых денег в готовом виде. Экспериментируйте, дорабатывайте проект под свои нужды и делитесь результатами! Удачи в сборке!

Понравилась статья?

Поставьте лайк и сохраните полезный материал в закладки.

Комментарии (0)
Добавить комментарий
Ваш комментарий
Кликните на изображение чтобы обновить код, если он неразборчив

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