Arduino - ethernet - weintek modbus

Hola, tengo un arduino uno, con una shield de eth, y una pantalla weintek. Mi intencion es mandar un registro de arduino a la pantalla.
La pantalla tiene configurado un campo con ide 1, y campo de registro 3x 1#3 y una ip.
Con el arduino probe todas las librerias que encontre por internet y lo maximo que consegui fue mirar que la pantalla menindicaba que tenia trafico de datos entrante y saliente, pero no llega a guardar el registro en ningun momento.
Probe con todos los ejemplos de cada libreria hasta el punto en el que tengo conflico con algunas.
La intencion es que el arduino funcione como servidor y la pantalla sea el cliente. Probe a la inversa tambien.

Algun codigo que os haya funcionado o alguna sugerencia? Lei varios temas sobre modbus en el foro, sobre todo los referidos a lo que pretendo, pero no me aclaro.
Gracias

Supongo que tienes ambos dispositivos en el mismo rango de IP ¿Estás usando cable de punto a punto o un switch? Con un switch puedes hacer ping a los dispositivos. En tu caso sería mejor que probaras con programas para PC que simularan un dispositivo servidor/cliente , de es modo podrías probar cada dispositivo por separado

Hola, en punto a punto, probe tanto con el cable cruzado como el directo, poniendo la ip estatica del "maestro" en el adaptador.
Suelo andar con un switch como intermediario, con cables directos, pero tuve que reservar las ips y poner las macs tanto para la shield como para la pantalla, porque el router no los reconoce como dispositivos conectados por cable. Y cada dispositivo ya tiene una ip estatica, si puedo hacer ping a las ips, y puerta de enlace.

Prove con los programas modbus poll, para ver bien la direccion a la que envia la cosas y ponerlo en la shield. En mi caso es con modbus tcp 3x al registro 13, asique 30012 es la direccion que le pongo. El primer campo de registro es el 0.
Consegui connel programa esclavo conectarme a la pantalla y que escribiese el dato.

Pero desde arduino al programa o la pantalla no consegui mandar nada. La primera vez la pantalla se me quedo con el cuadro de texto en ****, luego en otra prueba en 2222.

Pero ninguna cifra de las que mande desde el arduino.

Estoy usando esta libreria.

Que hasta ahora es la que me parece mas sencilla, y los pasos para la shield w5100 que tengo.

Pero ni con los set ni los add, hago nada.
Tengo claro que la pantalla es la que funciona como maestro, pero no se si con esa galeria establezco bien como esclavo al arduino.

Yo lo que pretendo es enviar un word, una cifra de 4 digitos, pero ni con los Hreg ni los Ireg, mando nada.
El comando para enviar seria.... mb.Ireg(30012, 6666);

Pero el task del loop no me lo envia. Como debe...
Veo que la pantalla en el puerto de red esta con datos en la velocidad de tx y rx, pero no guardo el valor.

¿Lo solucionaste?

No, no doy con la galeria o la sentencia de envio correcta

Dude porque lo marcaste como resuelto. Coloca el código del arduino

Hola, lo estaba escribiendo desde el móvil y ando torpe con los dedos, creo que ya esta como tema normal. El código para el envío del valor es este, luego lo combinare con el resto del código, pero primero quería ser capaz de mandar un dato a la pantalla.


#include <SPI.h>
#include <Ethernet.h>
#include <Modbus.h>
#include <ModbusEthernet.h>


const int dir = 30012; 



ModbusEthernet mb;

long ts;

void setup() {
    // The media access control (ethernet hardware) address for the shield
    byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };  
    // The IP address for the shield
    byte ip[] = { 192, 168, 1, 102 };   
    // Config Modbus TCP 
    mb.config(mac, ip);
  
    ts = millis();
}

void loop() {
   //Call once inside loop() - all magic here
   mb.task();
   
         mb.setIreg(dir, 6666);
   } 

Como decía la pantalla, me deja visualizar si hay trafico de datos en tx y rx por rj45 y hay flujo, pero no guardo en el campo el dato.

He instalado la librería de mudbus, y con algún ejemplo al modbus poll, si le escribía datos, pero en la dirección 40001, aunque pone para definir la 3x, no se como elegirla, y yo quiero escribir en el registro 13, no se como decírselo. En los ejemplos... si empezaba a escribir en el registro 5, del 0 al 4, marcaba en 0. No se si eso es normal. Este código si me funcionaba con el poll, pero... eso... sin saber ni como establecer bien la dirección y el registro

#include <SPI.h>
#include <Ethernet.h>

#include "Mudbus.h"

//#define DEBUG

Mudbus Mb;
//Function codes 1(read coils), 3(read registers), 5(write coil), 6(write register)
//signed int Mb.R[0 to 125] and bool Mb.C[0 to 128] MB_N_R MB_N_C
//Port 502 (defined in Mudbus.h) MB_PORT

void setup()
{
  uint8_t mac[]     = { 0x90, 0xA2, 0xDA, 0x00, 0x51, 0x06 };
  uint8_t ip[]      = { 192, 168, 1, 102 };
  uint8_t gateway[] = { 192, 168, 1, 1 };
  uint8_t subnet[]  = { 255, 255, 255, 0 };
  Ethernet.begin(mac, ip, gateway, subnet);
  //Avoid pins 4,10,11,12,13 when using ethernet shield

  delay(5000);  //Time to open the terminal
  Serial.begin(9600);
  
  analogReference(EXTERNAL);                      //Power the sensor with the 3.3V supply and run a wire from there to the AREF pin.  
}

#define AREF_VOLTS 3.33

void loop()
{
  Mb.Run();
  
  //Analog inputs 0-1023
  Mb.R[6] = analogRead(A2);                       //Raw signal from sensor.
  //TMP36 analog temperature sensor 1=5V 2=Signal 3=Gnd
  //From 0.1V to 2.0V = -40 to 150 C / -40 to 302 F
  //Seems like the TMP36 needs a cap on the output or it reads 10F low.  Don't know what value cap, about the size of a tic.
  double Volts = double(Mb.R[6]) / 1023 * AREF_VOLTS;
  Mb.R[7] = Volts * 1000;                         //Volts on A2 (x1000 to get digits to the right of the decimal).
  Mb.R[8] = map(Mb.R[7], 100, 2000, -400, 1500);  //Degrees C x 10
  Mb.R[9] = map(Mb.R[7], 100, 2000, -400, 3020);  //Degrees F x 10
    
 
#ifdef DEBUG
  delay(1000);
  Serial.print("A2=");
  Serial.print(Mb.R[6]);
  Serial.print("  Volts=");
  Serial.print(Mb.R[7] / 1000);
  Serial.print("  C=");
  Serial.print(Mb.R[8] / 10);
  Serial.print("  F=");
  Serial.println(Mb.R[9] / 10);
#endif
}

/*
Modpoll commands
  Read the registers Mb.R[6], Mb.R[7], and Mb.R[8]
    ./modpoll -m tcp -t4 -r7 -c4 192.168.1.8
*/

La comunicacion fue realizada con exito con este codigo, me falta integrarlo con el resto a ver va bien.

#include <SPI.h>
#include <Ethernet.h>

#include "Mudbus.h"

#define DEBUG

Mudbus Mb;
//Function codes 1(read coils), 3(read registers), 5(write coil), 6(write register)
//signed int Mb.R[0 to 125] and bool Mb.C[0 to 128] MB_N_R MB_N_C
//Port 502 (defined in Mudbus.h) MB_PORT

void setup()
{
  uint8_t mac[]     = { 0x90, 0xA2, 0xDA, 0x00, 0x51, 0x06 };
  uint8_t ip[]      = { 192, 168, 1, 102 };
  uint8_t gateway[] = { 192, 168, 1, 1 };
  uint8_t subnet[]  = { 255, 255, 255, 0 };
  Ethernet.begin(mac, ip, gateway, subnet);
  //Avoid pins 4,10,11,12,13 when using ethernet shield

  delay(5000);  //Time to open the terminal
  Serial.begin(9600);
  

}

void loop()
{
  Mb.Run();

  Mb.IR[12] = 6666; //IR es 3x  12 es la direccion
    
/* 
#ifdef DEBUG
  delay(1000);
  Serial.print("A2=");
  Serial.print(Mb.R[6]);
  Serial.print("  Volts=");
  Serial.print(Mb.R[7] / 1000);
  Serial.print("  C=");
  Serial.print(Mb.R[8] / 10);
  Serial.print("  F=");
  Serial.println(Mb.R[9] / 10);
#endif*/
}

/*
Modpoll commands
  Read the registers Mb.R[6], Mb.R[7], and Mb.R[8]
    ./modpoll -m tcp -t4 -r7 -c4 192.168.1.8
*/
  

Hola buenas, estoy también interesado en hacer una comunicación Weintek con Arduino, he visto que se podía hacer con MODbus RTU, pero de la forma que lo has hecho no lo había visto ¿Qué dirías que es mejor con Modbus o de esta forma?¿habría alguna forma de saber los componentes y como has configurado el Easybuilder?

Hola, la verdad es que no se la distincion entre modbus y modbus rtu.

En mi caso recibo los datos por lora, en un arduino uno con una shield w5100 para tener el puerto ethernet. Y le mando los datos a la pantalla directamente.

A ver si me acuerdo y mañana te mando unas fotos del programa o el archivo, de la pantalla.

Realmente ya no estoy usando ese codigo de arduino tal y como esta solo le tengo asignada la mac y la ip 102.
A la pantalla le tengo la ip 106 y como entrada de datos la ip 102.
Van ambas cosas al mismo router.
En la pantalla en la configuracion de cuando seleccionas el tipo de pantalla es donde le puse la ip. Y despues simplemente añadi un cuadro numerico, al que le añadi los datos de la direccion, y que añadiese dos decimales para la temperatura. Me dijeron que usase la direccion 3x y fue la que puse luego use como resto de direccion la 13.
En el codigo pone 12, pero es por un tema del protocolo que tiene que ir una cifra menos.

Para saber que usar para mandar a la direccion 3x y no a las otras. Abri el archivo mudbus.h y por un lao ponia las letras, aunque ahora que veo el archivo no me queda claro. Creo que puse lo de IR porque era un int.

De todas formas antes de usar la pantalla, utilice los programa modbus pool y modbus slave para saber a que direccion estaba mandando los datos.

De todas formas para leer lo que escribia en la pantalla usaba C, si mal no recuerdo. Y de tener el sensor directamente en la misma placa... en lugar de mandar 6666 que lo use como prueba. Lo cambias por la variable y ya manda el valor que tenga

#include <SoftwareSerial.h>

#include <Ethernet.h>

#include "Mudbus.h"

 

// Definir los pines UART para comunicación con LoRa

#define LORA_RX_PIN 4  // Pin RX para LoRa

#define LORA_TX_PIN 5  // Pin TX para LoRa

 

// Inicializa el puerto serie de software para LoRa

SoftwareSerial loraSerial(LORA_RX_PIN, LORA_TX_PIN); // RX, TX

 

// Dirección del servidor

const char server[] = "192.168.1.102"; // Dirección IP del servidor

 

Mudbus Mb;

void setup() {

  // Inicializa la comunicación serie

  Serial.begin(9600);

  

  // Inicializa la comunicación con el módulo LoRa por UART

  loraSerial.begin(9600); // Configura la velocidad de transmisión UART

 

  // Inicializa la Ethernet Shield

  byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

  if (Ethernet.begin(mac) == 0) {

    Serial.println("No se pudo obtener una dirección IP.");

    while (1);

  }

  delay(1000);

  Serial.print("Dirección IP: ");

  Serial.println(Ethernet.localIP());

}

 

void loop() {

  // Si hay datos disponibles desde el módulo LoRa

  if (loraSerial.available()) {

    String received = "";

    while (loraSerial.available()) {

      received += (char)loraSerial.read();

    delay(300);

    }

    

    // Mostrar los datos recibidos por LoRa

    Serial.print("Datos recibidos por LoRa: ");

    Serial.println(received);

 

//Separar los Id de los datos

String Identificador = received.substring(0, 3);

String Datos = received.substring(3, 7);

    Serial.println("----------------------");

    Serial.print("El identificador es " + Identificador);

    Serial.println("   Los datos son " + Datos);

    Serial.println("----------------------");

 

      //Convertir identificador en int y datos en int

  int dispositivo = Identificador.toInt();

  int valor = Datos.toInt();

  //Envio de datos por modbus

  Mb.Run();

  if (dispositivo == 221 ){

    Mb.IR[12] = (valor) ; //IR es 3x  12 es la direccion

    }

  if (dispositivo == 222){

    Mb.IR[13] = (valor) ; //IR es 3x  13 es la direccion

    }

  if (dispositivo == 223){

    Mb.IR[14] = (valor) ; //IR es 3x  14 es la direccion

    }

  }

 

}


El codigo mas actual es asi. Pero no es la ultima version.
Sigo trabajando en que el maestro pida datos a los esclavos y que los esclavos no esten mandando todo el rato.
Tambien para modbus. Usando milis, para que si el dato mandado es el mismo que hace media hora, vuelva a pedirlo y lo mande por modbus de nuevo. Y si no se recibe nada. Que se ponga a 0.
No se como pero mi compañero añadio una funcion de log a la pantalla para ver los datos recibidos con fecha y hora.
Y tambien sigo con mandar datos de la pantalla al arduino y poder transmitirlos por lora. Para modificar cosas del arduino sin tener que conectarlo a un "pc"

No entiendo¿ La pantalla no es el maestro?

Si si, pero con los lora tb hay maestros y esclavos. Como con los arduinos.
La pantalla como maestro esta lista para recibir un dato en una direccion. Aunque no haya hecho la peticion. Tu desde el arduino le puedes enviar datos en el formato que tiene la direccion sin problema. Un string o un char a un cuadro de texto. Un boolean a un boton y un int a un cuadro de numeros. Por ahora fue lo que probe.
Es decir en la manera en la que creo que va. Es que la pantalla siempre esta pidiendo datos para los campos. Si tengo demasiado retardo en el envio, y no se lo añado a la pantalla. La pantalla me da errores de falta de conexion de red, pero en cuanto pasa el tiempo de envio desde el arduino, el mensaje desaparece y muestra los datos que le envie

Sigo sin entender. Si la pantalla es un maestro modbus los arduinos como esclavos no envían información si no le es requerido . Otra cosa es que tengas colisiones o que los arduinos sean muy lentos. La forma de solucionarlo es escribir un macro en la pantalla , con la función getdata, y almacenarlo en varibles locales y espaciar los pedidos.

Eso también puede ser la causa. si el maestro pregunta cuando esta en delay te dará error en la comunicación.

Ese delay es solo para que lleguen los datos completos del lora. No tiene nada con modbus. Modbus esta sin delay

Sinceramente no se. Lo de la pantalla a ver si te lo mando mañana por la tarde y lo ves tu. Yo con la pantalla soy muy novato. Solo se que si no envio dato. Los campos quedan en blanco y al poco salta error de red. Y que los datos los envio constantemente.

El lora espacia las lecturas 300 milisegundos.
Pero recibe lecturas cada 7 segundos, cada 18 y cada 30, si tengo coincidencias de vez en cuando de que el dato que reciva sea de dos loras al mismo tiempo y los separo con string para coger solo el primero.
Pero en cuanto a que la pantalla no te se decir. Ya ves que solo cargo un archivo. Lo inicio. Y luego lo corro para que envie a la direccion

Esto no tiene sentido, tienes un delay en tu código, cuando tengas un dato del lora tu arduino se congelara.

En realidad no, con ese tiempo yo estoy recibiendo datos por lora constantemente y constantemente los estoy mandando a la pantalla. Con el programa modbus pool me pasaba lo mismo. Yo envio un dato y el programa lo recibia al momento.
Tenia el sensor de temperatura en la mano y conforme iba subiendo la temperatura iba mandando loa datos al arduino con el modbus configurado y este a la pantalla o al programa.
El retardo de actualizacion del dato era de 1 o 2 segundos. Ya te digo. Mañana a ver si saco unas fotos o te subo el archivo del programa para que lo veas.

De todas formas el delay esta dentro del loop, mi loop no para de repetirse nunca

Claramente hay un error de interpretación ¿Tu arduino es master o esclavo? coloca un enlace a la librería modbus que estas usando. Si tu arduino es esclavo no puede funcionar con ese delay, si es master podría , pero la pantalla tendria que ser esclavo.