Introducción
El ESP32 PLC 14 con el módulo ampliable Powermeter permite monitorizar en tiempo real los parámetros eléctricos de un sistema trifásico. La instalación incluye tres líneas activas (fases): Línea 1 (L1), Línea 2 (L2) y Línea 3 (L3), y una línea de neutro (N), lo que la hace adecuada para monitorizar y controlar cargas eléctricas trifásicas.
El Powermeter desempeña un papel fundamental en la medición de parámetros clave como la tensión, la corriente, el factor de potencia, el consumo de energía y otras magnitudes eléctricas de cada una de las tres líneas activas respecto al neutro. Estos parámetros se pueden monitorizar a través del PLC, lo que permite una automatización eficiente, la detección de fallos y la gestión energética dentro del sistema.
Esta integración permite recopilar y analizar datos en tiempo real, lo que hace que la instalación sea ideal para aplicaciones de automatización industrial, monitorización de la distribución eléctrica o cualquier entorno donde el consumo energético preciso y el rendimiento del sistema sean críticos.
Protocolo de comunicación
El módulo Powermeter se basa en el SoC MSP430F6779IPEU. Este chip se encarga de leer todas las medidas y de actualizar sus registros para que se puedan leer después. Para leerlos se pueden usar 2 protocolos de comunicación: I2C o RS-232. Para utilizarlos, modifica el código según el protocolo deseado:
PowerMeterCommunication com = PLC;
selectCom(com);
PowerMeterCommunication com = PLC;
selectCom(com);
PowerMeterCommunication com = RS232;
selectCom(com);
PowerMeterCommunication com = RS232;
selectCom(com);
Según el modo, la comunicación disponible será I2C o RS-232. Se puede usar el bus I2C interno de la CPU del ESP32, o incluso uno externo mediante los pines I2C dedicados situados en el lateral del PLC. Para RS-232, utiliza el conector DB9 de la parte superior del ESP32 PLC 14.
Industrial Shields ha desarrollado una librería I2C para facilitar la comunicación con el módulo Powermeter, pero no incluye todas las herramientas disponibles. Para conocer en detalle el protocolo de comunicación Energy Measurement Design Center (EMDC), que es el protocolo con el que trabaja el chip, consulta su especificación del protocolo de comunicación.
Enfoque de software
Para usar el módulo Powermeter, tendrás que descargar los siguientes archivos y guardarlos en el mismo directorio que el código de tu proyecto, o en Arduino/libraries/Powermeter.
El código de ejemplo es el siguiente:
#include "PowerMeter.h"
PowerMeterCommunication com = PLC;
PowerMeterChannel channelA = CHA;
PowerMeterChannel channelB = CHB;
PowerMeterChannel channelC = CHC;
void setup() {
// Initialize serial communication at 115200 baud rate
Serial.begin(115200);
Wire.begin();
// Start communication with the Power Meter (assuming PLC is the mode)
delay(1000);
for (int i = 0; i < 27; i++) {
Serial.println("A");
delay(10);
}
delay(1000);
Serial.println("\033[28A");
selectCom(com);
}
void loop() {
// VRMS results
Serial.print("VRMS A: ");
Serial.print((float)get_VRMS(channelA) / 1000.0, 3);
Serial.println(" V");
Serial.print("VRMS B: ");
Serial.print((float)get_VRMS(channelB) / 1000.0, 3);
Serial.println(" V");
Serial.print("VRMS C: ");
Serial.print((float)get_VRMS(channelC) / 1000.0, 3);
Serial.println(" V");
// IRMS results
Serial.print("IRMS A: ");
Serial.print((float)get_IRMS(channelA) / 1000000.0, 3);
Serial.println(" A");
Serial.print("IRMS B: ");
Serial.print((float)get_IRMS(channelB) / 1000000.0, 3);
Serial.println(" A");
Serial.print("IRMS C: ");
Serial.print((float)get_IRMS(channelC) / 1000000.0, 3);
Serial.println(" A");
// VPEAK results
Serial.print("VPEAK A: ");
Serial.print((float)get_VPEAK(channelA) / 1000.0, 3);
Serial.println(" V");
Serial.print("VPEAK B: ");
Serial.print((float)get_VPEAK(channelB) / 1000.0, 3);
Serial.println(" V");
Serial.print("VPEAK C: ");
Serial.print((float)get_VPEAK(channelC) / 1000.0, 3);
Serial.println(" V");
// IPEAK results
Serial.print("IPEAK A: ");
Serial.print((float)get_IPEAK(channelA) / 1000000.0, 3);
Serial.println(" A");
Serial.print("IPEAK B: ");
Serial.print((float)get_IPEAK(channelB) / 1000000.0, 3);
Serial.println(" A");
Serial.print("IPEAK C: ");
Serial.print((float)get_IPEAK(channelC) / 1000000.0, 3);
Serial.println(" A");
// Power factor results
Serial.print("Power factor A: ");
Serial.print((float)get_PowerFactor(channelA) / 10000.0, 3);
Serial.println();
Serial.print("Power factor B: ");
Serial.print((float)get_PowerFactor(channelB) / 10000.0, 3);
Serial.println();
Serial.print("Power factor C: ");
Serial.print((float)get_PowerFactor(channelC) / 10000.0, 3);
Serial.println();
// Frequency results
Serial.print("Frequency A: ");
Serial.print((float)get_Frequency(channelA) / 100.0, 3);
Serial.println(" Hz");
Serial.print("Frequency B: ");
Serial.print((float)get_Frequency(channelB) / 100.0, 3);
Serial.println(" Hz");
Serial.print("Frequency C: ");
Serial.print((float)get_Frequency(channelC) / 100.0, 3);
Serial.println(" Hz");
// Active power results
Serial.print("Active power A: ");
Serial.print((float)get_ActivePower(channelA) / 1000000.0, 3);
Serial.println(" W");
Serial.print("Active power B: ");
Serial.print((float)get_ActivePower(channelB) / 1000000.0, 3);
Serial.println(" W");
Serial.print("Active power C: ");
Serial.print((float)get_ActivePower(channelC) / 1000000.0, 3);
Serial.println(" W");
// Reactive power results
Serial.print("Reactive power A: ");
Serial.print((float)get_ReactivePower(channelA) / 1000000.0, 3);
Serial.println(" VAr");
Serial.print("Reactive power B: ");
Serial.print((float)get_ReactivePower(channelB) / 1000000.0, 3);
Serial.println(" VAr");
Serial.print("Reactive power C: ");
Serial.print((float)get_ReactivePower(channelC) / 1000000.0, 3);
Serial.println(" VAr");
// Apparent power results
Serial.print("Apparent power A: ");
Serial.print((float)get_ApparentPower(channelA) / 1000000.0, 3);
Serial.println(" VA");
Serial.print("Apparent power B: ");
Serial.print((float)get_ApparentPower(channelB) / 1000000.0, 3);
Serial.println(" VA");
Serial.print("Apparent power C: ");
Serial.print((float)get_ApparentPower(channelC) / 1000000.0, 3);
Serial.println(" VA");
delay(10);
Serial.println("\033[28A");
}
#include "PowerMeter.h"
PowerMeterCommunication com = PLC;
PowerMeterChannel channelA = CHA;
PowerMeterChannel channelB = CHB;
PowerMeterChannel channelC = CHC;
void setup() {
// Initialize serial communication at 115200 baud rate
Serial.begin(115200);
Wire.begin();
// Start communication with the Power Meter (assuming PLC is the mode)
delay(1000);
for (int i = 0; i < 27; i++) {
Serial.println("A");
delay(10);
}
delay(1000);
Serial.println("\033[28A");
selectCom(com);
}
void loop() {
// VRMS results
Serial.print("VRMS A: ");
Serial.print((float)get_VRMS(channelA) / 1000.0, 3);
Serial.println(" V");
Serial.print("VRMS B: ");
Serial.print((float)get_VRMS(channelB) / 1000.0, 3);
Serial.println(" V");
Serial.print("VRMS C: ");
Serial.print((float)get_VRMS(channelC) / 1000.0, 3);
Serial.println(" V");
// IRMS results
Serial.print("IRMS A: ");
Serial.print((float)get_IRMS(channelA) / 1000000.0, 3);
Serial.println(" A");
Serial.print("IRMS B: ");
Serial.print((float)get_IRMS(channelB) / 1000000.0, 3);
Serial.println(" A");
Serial.print("IRMS C: ");
Serial.print((float)get_IRMS(channelC) / 1000000.0, 3);
Serial.println(" A");
// VPEAK results
Serial.print("VPEAK A: ");
Serial.print((float)get_VPEAK(channelA) / 1000.0, 3);
Serial.println(" V");
Serial.print("VPEAK B: ");
Serial.print((float)get_VPEAK(channelB) / 1000.0, 3);
Serial.println(" V");
Serial.print("VPEAK C: ");
Serial.print((float)get_VPEAK(channelC) / 1000.0, 3);
Serial.println(" V");
// IPEAK results
Serial.print("IPEAK A: ");
Serial.print((float)get_IPEAK(channelA) / 1000000.0, 3);
Serial.println(" A");
Serial.print("IPEAK B: ");
Serial.print((float)get_IPEAK(channelB) / 1000000.0, 3);
Serial.println(" A");
Serial.print("IPEAK C: ");
Serial.print((float)get_IPEAK(channelC) / 1000000.0, 3);
Serial.println(" A");
// Power factor results
Serial.print("Power factor A: ");
Serial.print((float)get_PowerFactor(channelA) / 10000.0, 3);
Serial.println();
Serial.print("Power factor B: ");
Serial.print((float)get_PowerFactor(channelB) / 10000.0, 3);
Serial.println();
Serial.print("Power factor C: ");
Serial.print((float)get_PowerFactor(channelC) / 10000.0, 3);
Serial.println();
// Frequency results
Serial.print("Frequency A: ");
Serial.print((float)get_Frequency(channelA) / 100.0, 3);
Serial.println(" Hz");
Serial.print("Frequency B: ");
Serial.print((float)get_Frequency(channelB) / 100.0, 3);
Serial.println(" Hz");
Serial.print("Frequency C: ");
Serial.print((float)get_Frequency(channelC) / 100.0, 3);
Serial.println(" Hz");
// Active power results
Serial.print("Active power A: ");
Serial.print((float)get_ActivePower(channelA) / 1000000.0, 3);
Serial.println(" W");
Serial.print("Active power B: ");
Serial.print((float)get_ActivePower(channelB) / 1000000.0, 3);
Serial.println(" W");
Serial.print("Active power C: ");
Serial.print((float)get_ActivePower(channelC) / 1000000.0, 3);
Serial.println(" W");
// Reactive power results
Serial.print("Reactive power A: ");
Serial.print((float)get_ReactivePower(channelA) / 1000000.0, 3);
Serial.println(" VAr");
Serial.print("Reactive power B: ");
Serial.print((float)get_ReactivePower(channelB) / 1000000.0, 3);
Serial.println(" VAr");
Serial.print("Reactive power C: ");
Serial.print((float)get_ReactivePower(channelC) / 1000000.0, 3);
Serial.println(" VAr");
// Apparent power results
Serial.print("Apparent power A: ");
Serial.print((float)get_ApparentPower(channelA) / 1000000.0, 3);
Serial.println(" VA");
Serial.print("Apparent power B: ");
Serial.print((float)get_ApparentPower(channelB) / 1000000.0, 3);
Serial.println(" VA");
Serial.print("Apparent power C: ");
Serial.print((float)get_ApparentPower(channelC) / 1000000.0, 3);
Serial.println(" VA");
delay(10);
Serial.println("\033[28A");
}
El código hace lo siguiente:
- Inicia el puerto Serial y el I2C.
- Imprimimos un total de 27 "A" y después subimos el cursor 28 filas. Esto permite escribir encima de los caracteres ya impresos y resultará muy útil al imprimir todos los datos leídos.
- Tras la inicialización, empezamos a leer desde el bus I2C los parámetros de todos los canales (A, B, C), que son las 3 líneas activas del PLC. Después de imprimirlo todo, volvemos a subir el cursor al principio para imprimir de nuevo.
Como se puede ver en las capturas anteriores, en la imagen de la izquierda no hay nada conectado a las líneas activas, por lo que todos los valores relevantes son 0. Cuando se conecta el canal A (imagen de la derecha), se aprecia claramente que VRMS A es 243.071V y que todos los parámetros del canal A tienen su valor correspondiente.