Tabla de Contenidos
- Por qué hacer un monitor de energía eléctrica
- Cómo funciona el monitor de energía eléctrica
- Componentes del monitor de energía eléctrica eléctrica
- Cómo construir el monitor
- Leyendo los datos del sensor
- Guardando los valores en una base de datos
- Visualizando los datos
- Usando los datos del sensor
- Mejoras futuras
- Más recursos
- Código Completo
En este post, explicaré cómo hacer un monitor de energía eléctrica IoT usando un sensor de corriente, un ESP32 y un raspberry pi. Aquí está el enlace al repositorio de github.
Por qué hacer un monitor de energía eléctrica
Puedes hacer un monitor de energía eléctrica IoT para verificar el consumo de electricidad de un negocio o casa.
En este caso, la idea surgió como una forma de ayudarnos en otro proyecto: Instalar paneles solares y medir sus efectos en el consumo de energía eléctrica.
Los paneles solares son costosos y el retorno de la inversión puede tomar varios años, así que queríamos calcular cuántos se necesitaban para llevar los costos de electricidad a un mínimo. Todos los paneles tienen una clasificación nominal de producción de energía, pero como todos sabemos, es mejor verificar antes de hacer una inversión sustancial de cualquier tipo.
Cómo funciona el monitor de energía eléctrica
La teoría
La potencia eléctrica, medida en Watts, puede expresarse como:
Watts (W) = Corriente (I) x Voltaje (V)
En México el voltaje se proporciona a 120V. Otras partes del mundo usan 240V.
Si asumimos que 120V son constantes, al medir la corriente en nuestro circuito podemos calcular razonablemente bien el consumo de energía eléctrica en un momento dado.
Luego podemos registrar las mediciones en una base de datos y sumar el uso a lo largo del tiempo para obtener el consumo total de energía eléctrica.
Como beneficio adicional, también podemos visualizar los datos y analizar la información de otras formas para obtener insights.
Cómo construirlo
Para medir la corriente, podemos usar un sensor de corriente no invasivo SCT-013.
Podemos conectarlo a un microcontrolador ESP32 para leer y enviar los datos a través de WiFi, usando el protocolo MQTT.
El ESP32 toma mediciones cada 5 minutos y transforma el valor del sensor en mA a una estimación en Amperes.
Los valores de voltaje están codificados a 120V, pero podrías sustituirlo con un sensor de voltaje si necesitas valores más precisos.
Las mediciones se envían luego a través de WiFi por el ESP32 a un broker MQTT instalado en un Raspberry Pi.
Usando un programa llamado Node-Red, el Raspberry escribe los valores MQTT en una base de datos InfluxDB para almacenamiento.
Finalmente, podemos usar un software de visualización de datos de código abierto llamado Grafana para mostrar los datos de una manera visualmente atractiva e interactiva.
De esta forma, podemos verificar el monitor de energía eléctrica IoT desde un teléfono celular o computadora en cualquier momento siempre que estemos en la misma LAN.
Componentes del monitor de energía eléctrica eléctrica
En este caso, tuvimos que medir 3 líneas eléctricas separadas, así que construimos el monitor de energía eléctrica para recibir entradas de tres sensores.
Se necesita un microcontrolador ESP32 para la versión de 3 sensores, pero para una versión de 1 sensor, un ESP8266 también funcionará. (Ver la imagen del primer prototipo abajo).
Lista de componentes de hardware:
- 1 ESP32
- 3 sensores de corriente SCT-013
- 3 Capacitores de 10uF
- 9 Resistencias de 10k
- 3 Resistencias de 20k
- Una conexión eléctrica para alimentar el ESP32
- Un protoboard o PCB
- Un Raspberry Pi
Software:
- Librería de placas ESP8266, instalada desde el Administrador de Placas
- Librería de Arduino: EspMQTTClient.h
- Librería Emonlib (Parte del proyecto open energy monitor)
- Mosquitto MQTT
Extras:
Diseñé una carcasa impresa en 3D para el proyecto para darle una mejor apariencia. Puedes encontrar el modelo 3D aquí.
Para las conexiones de hardware, también hice mi propio PCB usando una máquina CNC mini. También puedes hacer que tu cableado se vea mejor encargando un PCB con una empresa profesional. Es muy barato, solo tienes que esperar un poco para que lleguen.
Para que el monitor funcione, debe estar en el alcance de tu red WiFi.
Cómo construir el monitor
Diagrama eléctrico
Si quieres construir el sensor, simplemente puedes seguir el diagrama eléctrico a continuación. El circuito del primer sensor simplemente se duplica para los otros dos sensores:
El diagrama eléctrico del monitor de energía eléctrica. Usa un ESP32 y tres sensores de corriente SCT-013 con algunas resistencias y capacitores.
Diseñando el diagrama de cableado
Para crear el diagrama anterior, revisamos varios proyectos IoT que usan el sensor de corriente SCT-013, que enumero en la sección de recursos al final del post. Después fue un poco de experimentación y mucho ensayo y error.
Nuestro objetivo inicial era hacer que un solo sensor funcionara usando un protoboard y un ESP8266. Una vez que funcionó, creamos una versión impresa en 3D del diagrama para facilitar la comprensión y compartir el cableado:
El primer prototipo del monitor de energía eléctrica usando un ESP8266 y un solo sensor de corriente SCT-013. El diagrama está impreso en 3D.
Luego volvimos al protoboard y agregamos los circuitos para los otros dos sensores. Fue entonces cuando descubrimos que el ESP8266 solo tiene un pin de entrada analógica, y necesitábamos cambiar a un ESP32 para usar múltiples sensores.
La siguiente versión del prototipo de monitor de energía eléctrica eléctrica IoT usando un protoboard, ESP32 y tres sensores de corriente SCT-013
Fabricando el PCB
La configuración estaba funcionando en el protoboard, era hora de mover el circuito a una configuración más permanente. Decidimos hacer el diseño del PCB y tallarlo.
Diagrama de cableado del PCB usando Autodesk Eagle
Inicialmente hice un diagrama de cableado usando Fritzing, un software de diseño electrónico simple, pero luego tuve muchas dificultades traduciendo el archivo de salida en instrucciones CNC, así que terminé cambiando a Autodesk Eagle, que tiene un plugin para hacer exactamente eso (PCB Gcode). Si decides enviar tu diseño de PCB a un fabricante, Fritzing funcionará perfectamente.
Para probar todo, hice algunos prototipos usando cartón y luego fui por el real:
Máquina CNC fresando un prototipo de PCB del monitor de energía eléctrica DIY
Cuando usas un router CNC, las conexiones de cobre que sustituyen los cables deben ser más gruesas que en un PCB normal. Las conexiones delgadas son un problema con el router CNC, ya que las brocas del router pueden cortar los conectores y romper la conexión. Se necesita bastante experimentación para hacerlo bien, pero aún creo que vale la pena para prototipado rápido. Aquí hay algunas imágenes de cómo salió el PCB:
Pruebas de PCB de cartón y cobre usando la máquina CNC para el monitor de energía eléctrica
PCB del monitor de energía eléctrica terminado en una prensa listo para soldar.
Conectando los componentes
Después de hacer el PCB, etiquetamos y soldamos todo en el otro lado:
Parte posterior del PCB del monitor de energía eléctrica con componentes listos para soldar
Para proteger el cobre de la corrosión, agregué esmalte transparente al frente.
PCB del monitor de energía eléctrica junto al microcontrolador ESP32 soldado y conectado
Una vez que el PCB estuvo listo, conectamos todo y lo probamos.
Vista posterior del PCB del monitor de energía eléctrica con componentes conectados al ESP32 y los sensores SCT-013
Algunas piezas tuvieron que ser re-soldadas porque los cables del sensor se doblaron y seguían rompiéndose, pero al final todo funcionó.
Una vez que todo funcionó, metimos los componentes en la carcasa impresa en 3D y pegamos todo.
Monitor de energía eléctrica terminado con carcasa impresa en 3D: Vista posterior
Monitor de energía eléctrica terminado con carcasa impresa en 3D: Vista frontal sin tapa
Monitor de energía eléctrica terminado con carcasa impresa en 3D: Vista frontal con tapa
Agregando el software
Después de configurar el sensor, cargamos el archivo de Arduino en el ESP32.
Este es el código para el sensor. También está disponible en el repositorio de github.
C++ (Arduino)
// Código para medir corriente usando tres SCT-013 y un ESP32
// Placa utilizada: NODEMCU-32S
// Importar librería Emon del proyecto open energy monitor
#include "EmonLib.h"
// Función Mills
const unsigned long event_interval = 300000; // Intervalo de 5 minutos, 300 segundos
unsigned long previous_time = 0;
// Incluir conexión MQTT
#include "EspMQTTClient.h"
// Definir pines de entrada
#define ADC_INPUT_1 34 // Sensor 1
#define ADC_INPUT_2 32 // Sensor 2
#define ADC_INPUT_3 35 // Sensor 3
#define WIFI_SSID "<WiFi_username_here>"
#define WIFI_PASS "<WiFi_password_here>"
#define BROKER_IP "<local_ip_address>"
#define BROKER_USERNAME "<broker_username>"
#define BROKER_PASSWORD "<broker_password>"
#define CLIENT_NAME "<MQTT_name_to_identify_device>"
#define BROKER_PORT 1883
#define lastwill_topic "<last_will_topic>"
#define lastwill_text "El sensor de corriente se ha desconectado inesperadamente."
String client_name = CLIENT_NAME;
String startup_topic = "<startup_topic>";
String medidor_corriente1_topic = "<topic_to_report_sensor_1>";
String medidor_corriente2_topic = "<topic_to_report_sensor_2>";
String medidor_corriente3_topic = "<topic_to_report_sensor_3>";
// Voltaje asumido
float voltajeRed = 120.0;
// Crear 3 instancias de EnergyMonitor
EnergyMonitor energyMonitor1;
EnergyMonitor energyMonitor2;
EnergyMonitor energyMonitor3;
// Función para conectar a MQTT
EspMQTTClient client(
WIFI_SSID,
WIFI_PASS,
BROKER_IP,
BROKER_USERNAME,
BROKER_PASSWORD,
CLIENT_NAME, // Nombre del cliente para identificar tu dispositivo de forma única
BROKER_PORT
);
void setup()
{
Serial.begin(115200);
// Habilitar mensajes de depuración enviados a la salida serial
client.enableDebuggingMessages();
// Habilitar el actualizador web.
client.enableHTTPWebUpdater();
// MQTT Último Testamento
client.enableLastWillMessage( lastwill_topic , lastwill_text);
// Pin donde los sensores están conectados
// Valor de calibración: Modificar al calibrar
energyMonitor1.current(ADC_INPUT_1, 0.145);
energyMonitor2.current(ADC_INPUT_2, 0.145);
energyMonitor3.current(ADC_INPUT_3, 0.145);
}
//Conexión inicial MQTT
void onConnectionEstablished()
{
client.publish(startup_topic, String(client_name + " está ahora en línea."));
}
void loop()
{
// Bucle MQTT: Debe llamarse una vez por bucle.
client.loop();
// Bucle Mills
unsigned long current_time = millis();
// Declaración If de Mills
if(current_time - previous_time >= event_interval) {
// Número de muestras a tomar
double Irms1 = energyMonitor1.calcIrms(1484);
// Calcular corriente
double potencia1 = Irms1 * voltajeRed;
// Número de muestras a tomar
double Irms2 = energyMonitor2.calcIrms(1484);
// Calcular corriente
double potencia2 = Irms2 * voltajeRed;
// Número de muestras a tomar
double Irms3 = energyMonitor3.calcIrms(1484);
// Calcular corriente
double potencia3 = Irms3 * voltajeRed;
// Mostrar información en el monitor serial
Serial.print("Potencia 1 = ");
Serial.print(potencia1);
Serial.print(" Irms 1 = ");
Serial.println(Irms1);
// Mostrar información en el monitor serial
Serial.print("Potencia 2 = ");
Serial.print(potencia2);
Serial.print(" Irms 2 = ");
Serial.println(Irms2);
// Mostrar información en el monitor serial
Serial.print("Potencia 3 = ");
Serial.print(potencia3);
Serial.print(" Irms 3 = ");
Serial.println(Irms3);
Serial.print('\n');
Serial.print('\n');
// Publicador cliente MQTT
client.publish(medidor_corriente1_topic, String(potencia1));
client.publish(medidor_corriente2_topic, String(potencia2));
client.publish(medidor_corriente3_topic, String(potencia3));
Serial.print('\n');
// Actualizar tiempo para la próxima vez
previous_time = current_time;
}
}
Calibrando los sensores
Para calibrar los sensores, usamos el siguiente procedimiento:
- Dividir un cable de extensión para que los cables de línea y neutro estuvieran separados.
- Conectar el cable de extensión al tomacorriente eléctrico.
- Conectar un calentador al cable de extensión.
- Conectar los sensores a una de las líneas del cable de extensión.
- Conectar un medidor de pinza a la misma línea del cable de extensión.
- Encender el calentador y comparar los valores en los sensores con los valores en el medidor de pinza.
- Ajustar el valor de calibración en el código e intentar de nuevo hasta que las lecturas coincidan.
También verificamos que las lecturas fueran consistentes en los diferentes rangos de calentamiento.
Las líneas de código para calibrar los sensores son:
C++ (Arduino)
// Función Mills
const unsigned long event_interval = 300000; // Intervalo de 5 minutos, 300 segundos
Puedes modificar esta línea para hacer que el sensor reporte valores cada 5 segundos en lugar de cada 5 minutos para la prueba de calibración:
C++ (Arduino)
energyMonitor1.current(ADC_INPUT_1, 0.145);
energyMonitor2.current(ADC_INPUT_2, 0.145);
energyMonitor3.current(ADC_INPUT_3, 0.145);
Luego, para calibrar los valores, modifica el valor de 0.145 hasta que todas las lecturas sean consistentes.
Aquí hay un gif del procedimiento:
Calibración del sensor del monitor de energía eléctrica
Leyendo los datos del sensor
Una vez que el sensor estaba calibrado y reportando valores, era hora de guardar los datos y visualizarlos.
Para hacer esto, habíamos instalado previamente Mosquitto MQTT, InfluxDB y Grafana en un Raspberry Pi 4. Explicar cómo hacer esto tomaría demasiado tiempo, pero seguimos las instrucciones explicadas en este video.
Primero, verificamos que el sensor estuviera enviando datos correctamente. Abrimos el monitor serial de Arduino y obtuvimos el siguiente mensaje de confirmación:
Monitor serial de Arduino después de cargar el código al ESP32
Luego usamos SSH para conectar mi computadora al Raspberry Pi y abrimos Mosquitto, el broker MQTT para monitorear los valores que el ESP32 reportaba en tiempo real.
En este ejemplo, nos suscribimos a un solo tema de sensor llamado "Cordilleras/medidor_corriente1", no a los tres sensores.
Salida de terminal, usando Mosquitto MQTT y suscrito al tema del sensor1
Guardando los valores en una base de datos
Después de verificar que MQTT estaba funcionando correctamente, abrimos Node-Red y configuramos algunos nodos para leer los datos MQTT de los tres sensores, los guardamos como objetos JSON y luego los escribimos en la base de datos InfluxDB que había configurado previamente.
Aquí hay una imagen de la configuración de Node-Red:
Configuración de Node-RED en Raspberry Pi
Los nodos morados leen la información MQTT. Los nodos de función naranjas guardan la información de cada sensor como una variable. Los nodos verdes son para depuración y pruebas. El nodo azul se ejecuta automáticamente cada 5 minutos. El nodo naranja guarda las tres variables como un solo payload. Finalmente, el nodo marrón guarda la información en InfluxDB.
Para verificar las lecturas en la base de datos, iniciamos sesión usando la línea de comandos para ver los valores:
Terminal mostrando la base de datos InfluxDB con marcas de tiempo y lecturas de energía eléctrica
Visualizando los datos
Grafana es una gran herramienta para visualización de datos porque es de código abierto, fácil de usar, y tiene excelentes gráficas que pueden ajustarse para diferentes períodos de tiempo.
A continuación hay una imagen de cómo se ve la información al mostrar un período de 24 horas.
Gráfica del monitor de energía eléctrica usando Grafana mostrando el uso de energía eléctrica durante un período de 24 horas.
En la gráfica, puedes ver cómo la primera línea eléctrica (medidor 1) usa más electricidad que la segunda o la tercera línea.
También puedes ver picos periódicos de aproximadamente 5 amperes. Este es el motor del refrigerador encendiéndose. Finalmente, puedes ver algunos picos masivos a las 8am, 4pm y 8:30pm. Este es el microondas encendiéndose durante el desayuno, comida y cena.
Usando los datos del sensor
Al comparar el consumo de electricidad de las líneas 1, 2 y 3, es claro que las cargas están desbalanceadas, ya que la mayor parte del consumo eléctrico está en la línea 1.
Re-arreglamos las cargas eléctricas para que el microondas estuviera en una línea, el refrigerador en una línea separada y el resto de los tomacorrientes eléctricos en una tercera línea.
Durante la mayor parte del día, la carga eléctrica está por debajo de 5 Amperes, lo que significa que generar esa cantidad de energía sería suficiente para sustituir mi factura de energía eléctrica durante las horas de luz solar. Para responder la pregunta inicial que comenzó este proyecto: Para reducir la electricidad durante todo el día, tendríamos que comprar suficientes paneles solares para generar 5 Amperes, o 600 Watts (5 amperes x 120 voltios) durante 24 horas (14,400W/h).
Los paneles promedio producen 270 Watts/hora durante un período de 5 horas por día (según la estimación de solargis para la Ciudad de México), o 1,350 Watts por día, necesitaríamos aproximadamente 11 paneles solares para compensar completamente todos los costos de electricidad con energía renovable.
Mejoras futuras
Si bien este monitor de energía eléctrica ha demostrado ser una herramienta valiosa para comprender los patrones de consumo de electricidad, hay varias formas en que podría mejorarse para obtener mediciones más precisas y mejores insights.
Mayor frecuencia de medición
Actualmente, el sistema toma mediciones cada 5 minutos. Esto funciona bien para entender los patrones generales de consumo, pero puede perder eventos de corta duración. Por ejemplo, si un compresor de refrigerador se enciende durante solo 2 minutos dentro de un intervalo de 5 minutos, es posible que no capturemos su consumo total de energía con precisión.
Un mejor enfoque sería aumentar drásticamente la frecuencia de medición. El ESP32 puede manejar fácilmente tomar 10 o más mediciones por segundo. Esto nos permitiría capturar incluso ráfagas cortas de consumo de energía que de otro modo podrían perderse.
Para evitar saturar la base de datos con datos, podríamos continuar transmitiendo al servidor cada 5 minutos, pero en lugar de enviar una sola lectura instantánea, enviaríamos el promedio (o suma) de todas las mediciones tomadas durante ese período. Esto nos daría una imagen mucho más precisa del consumo real de energía.
Enfoque de implementación
Los cambios en el código implicarían:
- Tomar mediciones varias veces por segundo (por ejemplo, cada 100-200ms)
- Almacenar estas mediciones en un array o suma acumulada
- Cada 5 minutos, calcular el consumo promedio para ese período
- Transmitir solo el valor promediado para reducir el tráfico de red y el almacenamiento en la base de datos
Esta mejora sería particularmente valiosa para detectar y medir:
- Ciclos de refrigeradores y aires acondicionados que pueden funcionar solo unos pocos minutos
- Aparatos de alta potencia de corta duración como microondas o cafeteras
- Picos o caídas repentinas en el consumo que indican posibles problemas eléctricos
- Cálculos más precisos del consumo total de energía
Esta mejora haría que el monitor de energía sea significativamente más preciso mientras mantiene el mismo enfoque eficiente de transmisión y almacenamiento de datos.
Más recursos
Espero que hayas encontrado este post interesante.
Si decides construir un sensor de corriente, a continuación encontrarás algunos recursos adicionales que usamos para hacer posible este proyecto.
No dudes en contactarme si necesitas ayuda.
Pablo.
Código Completo
Aquí está el código usado en el microcontrolador ESP32. Para más información asegúrate de ir al repositorio de github.
C++ (Arduino)
// Código para medir corriente usando tres SCT-013 y un ESP32
// Placa utilizada: NODEMCU-32S
// Importar librería Emon del proyecto open energy monitor
#include "EmonLib.h"
// Función Mills
const unsigned long event_interval = 300000; // Intervalo de 5 minutos, 300 segundos
unsigned long previous_time = 0;
// Incluir conexión MQTT
#include "EspMQTTClient.h"
// Definir pines de entrada
#define ADC_INPUT_1 34 // Sensor 1
#define ADC_INPUT_2 32 // Sensor 2
#define ADC_INPUT_3 35 // Sensor 3
#define WIFI_SSID "<WiFi_username_here>"
#define WIFI_PASS "<WiFi_password_here>"
#define BROKER_IP "<local_ip_address>"
#define BROKER_USERNAME "<broker_username>"
#define BROKER_PASSWORD "<broker_password>"
#define CLIENT_NAME "<MQTT_name_to_identify_device>"
#define BROKER_PORT 1883
#define lastwill_topic "<last_will_topic>"
#define lastwill_text "El sensor de corriente se ha desconectado inesperadamente."
String client_name = CLIENT_NAME;
String startup_topic = "<startup_topic>";
String medidor_corriente1_topic = "<topic_to_report_sensor_1>";
String medidor_corriente2_topic = "<topic_to_report_sensor_2>";
String medidor_corriente3_topic = "<topic_to_report_sensor_3>";
// Voltaje asumido
float voltajeRed = 120.0;
// Crear 3 instancias de EnergyMonitor
EnergyMonitor energyMonitor1;
EnergyMonitor energyMonitor2;
EnergyMonitor energyMonitor3;
// Función para conectar a MQTT
EspMQTTClient client(
WIFI_SSID,
WIFI_PASS,
BROKER_IP,
BROKER_USERNAME,
BROKER_PASSWORD,
CLIENT_NAME, // Nombre del cliente para identificar tu dispositivo de forma única
BROKER_PORT
);
void setup()
{
Serial.begin(115200);
// Habilitar mensajes de depuración enviados a la salida serial
client.enableDebuggingMessages();
// Habilitar el actualizador web.
client.enableHTTPWebUpdater();
// MQTT Último Testamento
client.enableLastWillMessage( lastwill_topic , lastwill_text);
// Pin donde los sensores están conectados
// Valor de calibración: Modificar al calibrar
energyMonitor1.current(ADC_INPUT_1, 0.145);
energyMonitor2.current(ADC_INPUT_2, 0.145);
energyMonitor3.current(ADC_INPUT_3, 0.145);
}
//Conexión inicial MQTT
void onConnectionEstablished()
{
client.publish(startup_topic, String(client_name + " está ahora en línea."));
}
void loop()
{
// Bucle MQTT: Debe llamarse una vez por bucle.
client.loop();
// Bucle Mills
unsigned long current_time = millis();
// Declaración If de Mills
if(current_time - previous_time >= event_interval) {
// Número de muestras a tomar
double Irms1 = energyMonitor1.calcIrms(1484);
// Calcular corriente
double potencia1 = Irms1 * voltajeRed;
// Número de muestras a tomar
double Irms2 = energyMonitor2.calcIrms(1484);
// Calcular corriente
double potencia2 = Irms2 * voltajeRed;
// Número de muestras a tomar
double Irms3 = energyMonitor3.calcIrms(1484);
// Calcular corriente
double potencia3 = Irms3 * voltajeRed;
// Mostrar información en el monitor serial
Serial.print("Potencia 1 = ");
Serial.print(potencia1);
Serial.print(" Irms 1 = ");
Serial.println(Irms1);
// Mostrar información en el monitor serial
Serial.print("Potencia 2 = ");
Serial.print(potencia2);
Serial.print(" Irms 2 = ");
Serial.println(Irms2);
// Mostrar información en el monitor serial
Serial.print("Potencia 3 = ");
Serial.print(potencia3);
Serial.print(" Irms 3 = ");
Serial.println(Irms3);
Serial.print('\n');
Serial.print('\n');
// Publicador cliente MQTT
client.publish(medidor_corriente1_topic, String(potencia1));
client.publish(medidor_corriente2_topic, String(potencia2));
client.publish(medidor_corriente3_topic, String(potencia3));
Serial.print('\n');
// Actualizar tiempo para la próxima vez
previous_time = current_time;
}
}
¡Contáctame!
Actualmente estoy disponible para trabajar y estaría feliz de conversar.
No dudes en contactarme si estás interesado en lo que puedo aportar
a tu proyecto o equipo.