Modbus RTU piranómetro RS-RA-N01-JT

Muchachos
Adquirí un piranómetro RS-RA-N01-JT https://www.renkeer.com/upload/file/content/2020/05/5ed0b487e93d3.pdf
el cual se comunica con el standard Modbus-RTU interfaz RS485
El datasheet ofrece las siguientes indicaciones para la medición de la radiación:

Data frame format definition
Initial structure ≥ 4 bytes of time //NO entiendo que significa 4 bytes de tiempo
Address code = 1 byte
Function code = 1 byte
Data area = N bytes
Error check = 16-bit CRC code
End structure ≥ 4 bytes of time
Address code: is the address of the transmitter, which is unique in the communication network
(factory default 0x01).
Function code: The instruction function of the command sent by the host. The transmitter can use
function code 0x03 (read register data) 0x06 (write register).
Data area: The data area is the specific communication data. Note that the 16-bit data high byte is in front!
CRC code: Two-byte check code.

De acuerdo con la definición del formato de datos se debe enviar inicialmente >= 4 bytes
y posteriormente el codigo de dirección. Aqui el código:

// Programa Modbus-RTU del piranometro RS-RA-N01-JT

const int ledPin=13;
const int EnTxPin=2; //HIGH:TX LOW:RX
const int EnRxPin=3; ///HIGH:TX LOW:RX
//char CodigoLeerRD1[8] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A};//
String cadena="";
  
void setup() {
  Serial.begin(9600);
  Serial1.begin(4800);
  Serial1.setTimeout(1000);
  pinMode(ledPin,OUTPUT);
  pinMode(EnTxPin,OUTPUT);
  digitalWrite(ledPin,LOW);
  digitalWrite(EnTxPin,HIGH); //RS485 como Tx
  digitalWrite(EnRxPin,HIGH); //RS485 como Tx
}

void loop() {
  Lectura_RX();
  digitalWrite(ledPin,HIGH);
  delay(1000);
  Solicitar();
  digitalWrite(ledPin,LOW);
  delay(1000); 
}

void Solicitar(){
  int Inicial_Byte1=0xFF;
  int Inicial_Byte2=0xFF;
  int Inicial_Byte3=0xFF;
  int Inicial_Byte4=0xFF;
  int ID=0x01;
  int function=0x03;
  int Starting_address=0x00;
  int Finish_address=0x00;
  int Data_length_low=0x00;
  int Data_length_high=0x01;
  int Check_low=0x84;
  int Check_high=0x0A;
  int Final_Byte1=0xFF;
  int Final_Byte2=0xFF;
  int Final_Byte3=0xFF;
  int Final_Byte4=0xFF;
  digitalWrite(EnTxPin,HIGH); //RS485 como Tx
  digitalWrite(EnRxPin,HIGH); //RS485 como Tx
  Serial.println("Radiacion");
  Serial1.write(Inicial_Byte1);
  Serial1.write(Inicial_Byte2);
  Serial1.write(Inicial_Byte3); 
  Serial1.write(Inicial_Byte4);           
  Serial1.write(ID);   
  Serial1.write(function);
  Serial1.write(Starting_address);
  Serial1.write(Finish_address);
  Serial1.write(Data_length_low);
  Serial1.write(Data_length_high);
  Serial1.write(Check_low);
  Serial1.write(Check_high);
  Serial1.write(Final_Byte1);  
  Serial1.write(Final_Byte2);
  Serial1.write(Final_Byte3);  
  Serial1.write(Final_Byte4);    
  digitalWrite(EnTxPin,LOW); //RS485 como Rx
  digitalWrite(EnRxPin,LOW); //RS485 como Rx
  delay(1000);
}

void Lectura_RX(){
   if (Serial1.available())
   {
    while(Serial1.available())
    {
   char data=Serial1.read();
      cadena+=data;
    }
   Serial.println(cadena);
   Serial1.println(cadena);
   cadena="";
    }
   //digitalWrite(EnTxPin,HIGH); //RS485 como Tx
}

Para verificar si los codigos hexadecimales enviados por Arduino Mega2560 son correctos, utilice una interfaz RS485-USB al puerto 2 con una terminal virtual a 4800 bps 8,N,1.
Los códigos para leer la medición de radiacion instantanea son:

Desafortunadamente el piranómetro no tiene indicadores led de "on" o que envíe alguna cadena de datos de inicio (como hacen los modem enfora AT-ok). NO he logrado que responda aunque fuera una cadena de respuesta con un codigo de error. En el monitor serie solo aparace 0x0A y 0x0D. Al inicio pense que se trataba de alguna señal de respuesta del piranómetro pero lo desconecté de la alimentación y siguen apareciendo 0x0A y 0x0D.
Alguna recomendación? Gracias de antemano.

Serial1.write(Inicial_Byte1);
Serial1.write(Inicial_Byte2);
Serial1.write(Inicial_Byte3);
Serial1.write(Inicial_Byte4);

Esas líneas sobran.

Creo que los chinos cuando dicen "initial structure >= 4", es que lo que mandes debe tener una longitud mayor que cuatro. Cualquier trama modbus tiene 4 bytes minimo (byte de id, funcion y dos bytes de CRC).

Despues veo en el loop que primero lees y luego solicitas, con lo que no vas a tener respuesta. Primero solicita y luego lee.

Veo que tu no eres el autor del post, o has cambiado de nick y
este post estaba sin actividad desde hace mucho, deberías haber creado un hilo
nuevo, a no ser que las normas hayan cambiado con el nuevo look del foro, Por otro lado, el código debería ir entre etiquetas code.

@victorjam agradezco tu pronta respuesta. He probado quitando los 4 bytes del principio (me deje llevar por el initial estructure) y complentando los que le faltaban al ID y a la función. Sin embrago, el piranómetro no da señales de ningún tipo. siguen apareciendo 0x0A y 0x0D, aún si alimentarlo.

void Solicitar(){
  int ID_low=0x00;
  int ID_high=0x01;
  int function_low=0x00;
  int function=0x03;
  int Starting_address=0x00;
  int Finish_address=0x00;
  int Data_length_low=0x00;
  int Data_length_high=0x01;
  int Check_low=0x84;
  int Check_high=0x0A;
  digitalWrite(EnTxPin,HIGH); //RS485 como Tx
  digitalWrite(EnRxPin,HIGH); //RS485 como Tx
  Serial.println("Radiacion");
  Serial1.write(ID_low);           
  Serial1.write(ID_high);
  Serial1.write(function_low);    
  Serial1.write(function);
  Serial1.write(Starting_address);
  Serial1.write(Finish_address);
  Serial1.write(Data_length_low);
  Serial1.write(Data_length_high);
  Serial1.write(Check_low);
  Serial1.write(Check_high);   
  digitalWrite(EnTxPin,LOW); //RS485 como Rx
  digitalWrite(EnRxPin,LOW); //RS485 como Rx
  delay(1000);
}

No soy el autor original del post. continué con el hilo del post con animos de que se trata el mismo tema. En mis proximas participaciones crearé nuevos hilos.
Un saludo.

Moderador:
@germanuribecolin edita tu post inicial usando etiquetas.
Mira como queda y asegúrate que sea correctamente, simplemente compara con lo que @victorjam te ha posteado y si no luce igual lo haces de nuevo (editas).
Cuando un hilo tiene mas de 4 meses, ni hablar de 2 años, se crea otro.

Estamos en un foro nuevo, las tareas de moderación se han vuelto por ahora trabajosas hasta que el uso cotidiano las haga simples.
Hay que leer las normas y respetar lo que se debe hacer.

La trama que estas enviando es incorrecta. Estás enviando el identificador y la función con dos bytes, cuando ocupan solo uno.

Serial1.write(ID_low);           
Serial1.write(ID_high);
Serial1.write(function_low);    
Serial1.write(function);

¿Cómo sería la trama correcta?

digitalWrite(EnTxPin, HIGH);
digitalWrite(EnRxPin, HIGH);
Serial1.write(0x01); // Id
Serial1.write(0x03); // función
Serial1.write(0x00); // Dirección parte alta.
Serial1.write(0x00); // Dirección parte baja.
Serial1.write(0x00); // Cantidad de registros parte alta.
Serial1.write(0x01); // Cantidad de registros parte baja.
Serial1.write(0x84); // CRC parte baja.
Serial1.write(0x0A); // CRC parte alta.
digitalWrite(EnTxPin, LOW);
digitalWrite(EnRxPin, LOW);

Me he comido los nombres de las variables puesto que no es necesario y se reduce el codigo bastante, con lo que se ve mejor.

De todas formas revisa las conexiones, el piranómetro no debería enviar nada, y no deberías recibir nada, sobre todo si no está alimentado.

Tampoco has especificado las conexiones que has hecho.

@victorjam
En pruebas anteriores ya intente enviando una trama igual a tu última propuesta.
Voy a iniciar una nueva prueba con el piranómetro conectado a la interfaz RS485-USB y con el simulador Modsim 32. Posteriormente, les comparto los diagramas de conexión y los resultados para migrarlos a Arduino.
Saludos

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.