Consulta comunicación serial y transformación de bytes a variables

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!! :slight_smile:

En un MEGA usas esto?

#include <SoftwareSerial.h>

El Mega tiene 4puertos series físicos desde Serial Serial1, Serial2 y Serial3

No hace falta SoftwareSerial para nada y en general da problemas

Además por si fuera poco no se asigna del modo que has hecho dentro del setup la librería, el objeto y su inicialización.

#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

Uso software serial para la conexión con el Node MCU debido a que los pines físicos con que dispone el MEGA están ocupados con un módulo bluetooth y un conversor de RS-485 a TTL.

Corregiré la ubicación del mismo.

Saludos

Y el que falta que?

1 para Monito Serie
1 para BT
1 para 485
te queda 1

Mega Serial