Hola, tengo dudas respecto a un proyecto que estoy realizando. Estoy trabajando en el código de un NodeMcu v 3.0, el cual quiero que reciba datos vía serial de un Arduino Mega, para luego subirlos a una página web.
En mi código tengo solucionada la conexión a WiFi y (al parecer) la última fase de subir los datos, sin embargo, tengo problemas con la conexion serial, en específico con la recepción de bytes y posterior transformación a variables.
Son 6 variables que se envían originalmente del Arduino Mega, y según pude ver en el código (que no hice yo) son de 2 bytes cada una.
Código Arduino Mega
#define SERIAL_OUTPUT 1
#if SERIAL_OUTPUT
# define SERIAL_BEGIN(...) Serial.begin(__VA_ARGS__)
# define SERIAL_PRINT(...) Serial.print(__VA_ARGS__)
# define SERIAL_PRINTLN(...) Serial.println(__VA_ARGS__)
#else
# define SERIAL_BEGIN(...)
# define SERIAL_PRINT(...)
# define SERIAL_PRINTLN(...)
#endif
#include "ModbusSensor.h"
#define MB_SERIAL_PORT &Serial1
#define MB_BAUDRATE 2400 // VELOCIDAD EN BITS * SEG
#define MB_BYTEFORMAT SERIAL_8N2
#define TxEnablePin 17 // PIN CONMUTADOR TX RX
#define ID_1 1
#define REFRESH_INTERVAL 500 // TIEMPO DE REFRESCO MS
#define WRITE_INTERVAL 200UL
#define KWH_2_WS 36000000
#define VOL_ADR 0x0000 // VOLTAJE.
#define CUR_ADR 0x0006 // CORRIENTE.
#define POW_ADR 0x000C // POTENCIA ACTIVA.
#define APO_ADR 0x0012 // Potencia Aparente.
#define PFA_ADR 0x001E // Factor de potencia.
#define FRE_ADR 0x0046 // Frecuencia.
#define PEN_ADR 0x0048 // ENERGIA IMPORTADA KWH
#define REN_ADR 0x004A // Energia exportada.
#define TEN_ADR 0x0156 // Energia activa Total.
#define TRE_ADR 0x0158 // Energia reactiva Total.
// factor de division
#define VOL_FAC 10
#define CUR_FAC 100
#define POW_FAC 10
#define PFA_FAC 100
#define FRE_FAC 10
#define ENE_FAC 100
modbusMaster MBserial(MB_SERIAL_PORT, TxEnablePin); // instance to collect data using Modbus protocol over RS485
//variables a pedir formato para comunicarse con scketch modbus sensor y pedir datos
modbusSensor volt(&MBserial, ID_1, VOL_ADR, CHANGE_TO_ZERO);
modbusSensor curr(&MBserial, ID_1, CUR_ADR, CHANGE_TO_ZERO);
modbusSensor pwr(&MBserial, ID_1, POW_ADR, CHANGE_TO_ZERO);
modbusSensor enrg(&MBserial, ID_1, PEN_ADR, HOLD_VALUE);
modbusSensor freq(&MBserial, ID_1, FRE_ADR, CHANGE_TO_ZERO);
modbusSensor aPwr(&MBserial, ID_1, APO_ADR, CHANGE_TO_ZERO);
modbusSensor pwrFact(&MBserial, ID_1, PFA_ADR, CHANGE_TO_ONE);
// generamos variables que puedan contener 16 bits dentro de ellas
uint16_t voltage, maxVoltage, minVoltage; // factor x10
uint16_t current, maxCurrent, minCurrent; // factor x100
uint16_t power, maxPower, minPower; // factor x10
uint16_t lastEnergy, energy, avgPower; // factor x100
uint16_t frequency, maxFreq, minFreq; // factor x100
uint16_t aPower, maxApower, minApower; // factor x10
uint16_t powerFactor, maxPF, minPF; // factor x100
// cuenta en milisegundos para hacer los intervalos de refresco escritura
unsigned long previousMillis = 0;
unsigned long currentMillis = 0;
// variable utilizada para ver si hay datos
boolean firstData;
// variable para enviar datos a travez de puerto serial
char buffer[10];
int contador=0;
void setup() {
Serial3.begin(9600);
SERIAL_BEGIN(9600);
//inicia serial 1 con caracteristicas especificadas antes
MBserial.begin(MB_BAUDRATE, MB_BYTEFORMAT, REFRESH_INTERVAL);
delay(95);
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // Debido a que los pines TX y RX se encuentran utilizados, se asignan como pines virtuales RX y TX, 10 y 11 respectivamente.
mySerial.begin(9600); //inicia comunicación serial con Node Mcu
// inicializa datos en cero
firstData = false;
power = 0;
maxPower = 0;
minPower = 0;
lastEnergy = 0;
energy = lastEnergy;
}
void loop() {
// abilita interrupciones en el programa
sei();
// si puerto serial1 disponible hace
if (MBserial.available()) {
// leemos variables desde modbus sensor y guardamos en variables ejemplo leemos volt que tiene un formato predefinido lo pedimos con un factor que puede ser 10 o 100 dependiendo de la variable para guardar como entero esta y lo guardamos en voltaje
voltage = volt.read(VOL_FAC);
current = curr.read(CUR_FAC);
power = pwr.read(POW_FAC);
aPower = aPwr.read(POW_FAC);
frequency = freq.read(FRE_FAC);
energy = enrg.read(ENE_FAC);
powerFactor = pwrFact.read(PFA_FAC);
if (!firstData) {
if (maxVoltage < voltage) maxVoltage = voltage;
if (minVoltage > voltage) minVoltage = voltage;
if (maxCurrent < current) maxCurrent = current;
if (minCurrent > current) minCurrent = current;
if (maxPower < power) maxPower = power;
if (minPower > power) minPower = power;
if (maxApower < aPower) maxApower = aPower;
if (minApower > aPower) minApower = aPower;
if (maxFreq < frequency) maxFreq = frequency;
if (minFreq > frequency) minFreq = frequency;
if (maxPower < power) maxPower = power;
if (minPower > power) minPower = power;
}
else {
maxVoltage = voltage;
minVoltage = voltage;
maxCurrent = current;
minCurrent = current;
maxPower = power;
minPower = power;
maxApower = aPower;
minApower = aPower;
maxFreq = frequency;
minFreq = frequency;
firstData = false;
}
}
// se saca una muestra de millisegundos para comprara
currentMillis = millis();
//si los milisegundos son mayores o iguales a intervalo se hace
if (currentMillis - previousMillis >= WRITE_INTERVAL) {
previousMillis = currentMillis;
firstData = true;
contador = contador+1;
// realentiza envio de buffer
if (contador >= 20){
SERIAL_PRINT(currentMillis / 1000);
SERIAL_PRINT(",");
SERIAL_PRINT((float)maxVoltage / VOL_FAC, 1);
SERIAL_PRINT(",");
SERIAL_PRINT((float)minVoltage / VOL_FAC, 1);
SERIAL_PRINT(",");
SERIAL_PRINT((float)maxCurrent / CUR_FAC, 2);
SERIAL_PRINT(",");
SERIAL_PRINT((float)minCurrent / CUR_FAC, 2);
SERIAL_PRINT(",");
SERIAL_PRINT((float)maxPower / POW_FAC, 2);
SERIAL_PRINT(",");
SERIAL_PRINT((float)minPower / POW_FAC, 2);
SERIAL_PRINT(",");
SERIAL_PRINT((float)maxApower / POW_FAC, 2);
SERIAL_PRINT(",");
SERIAL_PRINT((float)minApower / POW_FAC, 2);
SERIAL_PRINT(",");
SERIAL_PRINT((float)maxFreq / FRE_FAC, 2);
SERIAL_PRINT(",");
SERIAL_PRINT((float)minFreq / FRE_FAC, 2);
SERIAL_PRINT(",");
SERIAL_PRINT((float)powerFactor / ENE_FAC, 2);
SERIAL_PRINT(",");
SERIAL_PRINTLN((float)energy / ENE_FAC, 2);
Serial.println("enviando datos");
sprintf(buffer, "%d,%d,%d,%d,%d,%d",energy,maxVoltage,maxCurrent,maxPower,powerFactor,maxFreq);
Serial3.println(buffer);
sprintf(buffer, "%d,%d,%d,%d,%d,%d",energy,maxVoltage,maxCurrent,maxPower,powerFactor,maxFreq);
mySerial.println(buffer);
contador = 0;
}
Código NodeMCU actual
#include <ESP8266WiFi.h>
#include <SoftwareSerial.h>
String str = "";
const char separator = ',';
const int dataLength = 3;
int data[dataLength];
void setup()
{
Serial.begin(9600);
WiFi.disconnect();
Serial.println("Inicio. Intentando conectar a red.");
delay(3000);
WiFi.begin("my-net","");
while ((WiFi.status() == WL_CONNECTED)){
delay(300);
}
Serial.println("Conectado!");
}
void loop()
{
if (Serial.available()>0)
int datos = Serial.read ();
// Se crea un url para el pedido delservidor
String url = "/medidores.test";
String key = "?pass=1234";
String dato1 = "&energy=";
String dato2 = "&maxVoltaje=";
String dato3 = "&maxCurrent=";
String dato4 = "&maxPower=";
String dato5 = "&powerFactor=";
String dato6 = "&maxFreq=";
Serial.print("Requesting URL: ");
Serial.println(url);
// Esto enviará el pedido al servidor
client.print(String("GET ") + url + key + dato1 + dato2 + dato3 + dato4 + dato5 + dato6 + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
Serial.println(">>> Client Timeout !");
client.stop();
return;
}
}
}
Gracias de antemano y saludos!!