Arduino Forum

International => Español => Software => Topic started by: joaquinmoreno123 on Aug 18, 2019, 08:30 pm

Title: Problema trabajando con Comunicación Serial
Post by: joaquinmoreno123 on Aug 18, 2019, 08:30 pm
Hola, estoy implementando un proyecto que es la continuación de otro ya existente. Estoy trabajando con un totalizador que envía por medio de un módulo bluetooth a una app los datos de consumo de distintas cargas eléctricas que se puedan conectar al           mismo.
La mejora que intento hacer es tomar esos mismos datos y enviarlos a una página web alojada en un servidor local que diseñé con ese fin. La página web ya está lista, sin embargo, al ser nuevo en arduino, me he encontrado con muchas dificultades para programar el mismo.
La placa con que cuenta el proyecto original es un Arduino Mega, del cual se encuentran utilizados los 6 pines Rx y Tx. Mi idea es comunicarlo con un Módulo Wifi NodeMCU v3.0, vía serial, esto lo haré a través de la librería Sofware.Serial, utilizando 2 pines digitales. Adjunto el código original modificado por mi (creo que está bien).
Code: [Select]

#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;
}
    

Sin embargo, tengo problemas desarrollando el código de la placa NodeMCU, ya que tiene que conectar a wifi, recibir los datos vía serial y tomar esa información y subirla a la página web. Además de que los datos deben llegar de forma separada, por lo que el código se complica aún más. ¿Me podrían sugerir algún código que sirviera para tales efectos? De antemano, muchas gracias.

Code: [Select]
#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())
   {
      str = Serial.readStringUntil('\n');
      for (int i = 0; i < dataLength ; i++)
      {
         int index = str.indexOf(separator);
         data[i] = str.substring(0, index).toInt();
         str = str.substring(index + 1);
         Serial.print("Recibido: ");
         Serial.println(incomingByte, DEC);
      }
      DEBUG_ARRAY(data);

                        

}
Title: Re: Problema trabajando con Comunicación Serial
Post by: surbyte on Aug 18, 2019, 08:46 pm
Hola joaquinmoreno123, bienvenido al foro Arduino.
Lee las normas del foro y edita tu post visualizando los códigos relevantes.
No es solo venir y postear. Hay que hacerlo responsablemente!!
Title: Re: Problema trabajando con Comunicación Serial
Post by: joaquinmoreno123 on Aug 18, 2019, 08:56 pm
Hola, gracias por avisar, está arreglado.

Saludos