▷ Practica 8 #PlcLab: WebServer PZEM-014/016 AC Energy Meter

 

Repositorio:

Materiales:

  • 1 PLC-LAB
  • 1 Sensor PZEM016 (Link)

Requisitos previos:

API REST

El API REST es un conjunto de requisitos que permite la comunicación de datos entre diferentes aplicaciones. La ventaja de crear una API en nuestro ESP32 es que podemos permitir que otras aplicaciones puedan solicitar datos de nuestros módulos RS485, cuando sea necesario.





Código Principal:
/*
Autor: Vidal Bazurto (avbazurt@espol.edu.ec)
GitHub: https://github.com/avbazurt/CURSO-PLC-LAB
Practica #8: API Rest PZEM-014/016 AC Energy Meter
*/
//Librerias necesarias
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ModbusMaster.h>
#include <ArduinoJson.h>
#include <TaskScheduler.h>
/*
Configuramos credenciales WiFi
*/
#define ssid ""
#define password ""
/*
Pines Dedicados modulo PLC-LAB
*/
#define RS485_SERIAL Serial2
#define MAX485_DE GPIO_NUM_27 // Define DE Pin to Arduino pin. Connect DE Pin of Max485 converter module
#define MAX485_RE GPIO_NUM_26 // Define RE Pin to Arduino pin. Connect RE Pin of Max485 converter module
#define RS485_SERIAL_RX GPIO_NUM_25
#define RS485_SERIAL_TX GPIO_NUM_14
/*
Configuracion RS485
*/
#define PZEM014_MODBUS_ADDR 0x01
#define PZEM014_MODBUS_BAUD 9600
//Estructura datos Electricos Sensor
struct PZEM {
float voltaje = 0;
float corriente = 0;
float potencia = 0;
float energia = 0;
float frecuencia = 0;
float FP = 0;
};
//Definimos la estructura
PZEM Sensor;
//Clase Modbus necesaria
ModbusMaster mbus_sensor;
// WEB SERVER
AsyncWebServer server(80);
void notFound(AsyncWebServerRequest *request) {
request->send(404, "text/plain", "Not found");
}
// TASK
Scheduler runner;
void muestreoCallback(void);
Task task_muestreoCallback(500, TASK_FOREVER, &muestreoCallback, &runner);
void printIP(void);
Task task_printIP(5000, TASK_FOREVER, &printIP, &runner);
void setup() {
//Iniciamos el Serial
Serial.begin(115200);
//Nos conectamos al WiFi
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("WiFi Failed");
while (1) {
delay(1000);
}
}
//Habilitamos los pines como salida
pinMode(MAX485_DE, OUTPUT);
pinMode(MAX485_RE, OUTPUT);
//Iniciamos con los pines en bajo
RS485_switch2RX();
//Configuramos el Serial para RS485
RS485_SERIAL.begin(9600, SERIAL_8N1, RS485_SERIAL_RX, RS485_SERIAL_TX);
//Iniciamos el ModbusMaster
mbus_sensor.begin(PZEM014_MODBUS_ADDR, RS485_SERIAL);
//Agregmos los callback para pre y pos Transmision
mbus_sensor.preTransmission(RS485_switch2TX);
mbus_sensor.postTransmission(RS485_switch2RX);
// Configuro la REST API
server.on("/all", HTTP_GET, [](AsyncWebServerRequest * request) {
StaticJsonDocument<400> doc;
doc["voltaje"] = Sensor.voltaje;
doc["corriente"] = Sensor.corriente;
doc["potencia"] = Sensor.potencia;
doc["energia"] = Sensor.energia;
doc["frecuencia"] = Sensor.frecuencia;
doc["FP"] = Sensor.FP;
char buffer[100];
serializeJson(doc, buffer);
request->send(200, "application/json", buffer);
});
server.on("/voltaje", HTTP_GET, [](AsyncWebServerRequest * request) {
StaticJsonDocument<400> doc;
doc["voltaje"] = Sensor.voltaje;
char buffer[100];
serializeJson(doc, buffer);
request->send(200, "application/json", buffer);
});
server.on("/corriente", HTTP_GET, [](AsyncWebServerRequest * request) {
StaticJsonDocument<400> doc;
doc["corriente"] = Sensor.corriente;
char buffer[100];
serializeJson(doc, buffer);
request->send(200, "application/json", buffer);
});
server.on("/potencia", HTTP_GET, [](AsyncWebServerRequest * request) {
StaticJsonDocument<400> doc;
doc["potencia"] = Sensor.potencia;
char buffer[100];
serializeJson(doc, buffer);
request->send(200, "application/json", buffer);
});
server.on("/energia", HTTP_GET, [](AsyncWebServerRequest * request) {
StaticJsonDocument<400> doc;
doc["energia"] = Sensor.energia;
char buffer[100];
serializeJson(doc, buffer);
request->send(200, "application/json", buffer);
});
server.on("/frecuencia", HTTP_GET, [](AsyncWebServerRequest * request) {
StaticJsonDocument<400> doc;
doc["frecuencia"] = Sensor.frecuencia;
char buffer[100];
serializeJson(doc, buffer);
request->send(200, "application/json", buffer);
});
// Iniciamos la REST API
server.onNotFound(notFound);
server.begin();
// Iniciamos el task
task_muestreoCallback.enable();
task_printIP.enable();
}
void loop() {
runner.execute();
}
void RS485_switch2TX(void)
{
digitalWrite(MAX485_DE, HIGH);
digitalWrite(MAX485_RE, HIGH);
}
void RS485_switch2RX(void)
{
digitalWrite(MAX485_DE, LOW);
digitalWrite(MAX485_RE, LOW);
}
void printIP(void) {
IPAddress IP = WiFi.localIP();
Serial.println("AP IP address: ");
Serial.println(IP);
Serial.println(" ");
}
void muestreoCallback(void)
{
uint8_t res;
// La trama MODBUS mostrada en el folleto se traduce en esta petición de
// biblioteca:
res = mbus_sensor.readInputRegisters(0x0000, 9);
uint32_t tempdouble = 0x00000000;
Sensor.voltaje = mbus_sensor.getResponseBuffer(0x0000) / 10.0;
tempdouble = mbus_sensor.getResponseBuffer(0x0002) + mbus_sensor.getResponseBuffer(0x0001);
Sensor.corriente = tempdouble / 1000.00;
tempdouble = mbus_sensor.getResponseBuffer(0x0004) + mbus_sensor.getResponseBuffer(0x0003);
Sensor.potencia = tempdouble / 10.0;
tempdouble = mbus_sensor.getResponseBuffer(0x0006) + mbus_sensor.getResponseBuffer(0x0005);
Sensor.energia = tempdouble;
Sensor.frecuencia = mbus_sensor.getResponseBuffer(0x0007) / 10.0;
Sensor.FP = mbus_sensor.getResponseBuffer(0x0008) / 100.00;
}
view raw PLC-LAB-P8.ino hosted with ❤ by GitHub




Capturas:





Comments

Popular posts from this blog

▷ Practica 7 #PlcLab: WebServer PZEM-014/016 AC Energy Meter

▷ Practica 10 #PlcLab: MQTT PZEM-014/016 AC Energy Meter