Error leyendo datos sensor solar con rs485 modbus [SOLUCIONADO]

Buenas, estoy intentando leer la información proveniente de un sensor solar, el SolarMEMS mass60, lo conecto a arduino mediante el max485, adjuntaré el conexionado por medio de imagen, el hecho es que a pesar de que lee bastante información de forma correcta, numero de referencia, modelo, identificador, elevacion... Otros como por ejemplo la radiación siempre está a cero tenga o no sol y por otro lado la temperatura muestra de forma aleatoria el 310 y 64917.

El sensor funciona correcamente pues si conecto los pines rs485+ y rs485- al pc por medio de un convertidor usb y uso el programa del fabricante si lee todos los valores de forma correcta.

Por lo que el único cambio de conexión de pines del sensor es el de esos dos al pasarlos al max485.

No entiendo por qué no lee todos los valores de forma correcta. Espero alguien me puede ayudar. Gracias de antemano.

Adjunto documentacion del sensor, codigo, y valores leidos.

#include <ModbusRtu.h>



// declaracion de variables




uint16_t au16data[22]; // array de datos
uint8_t u8state;  //estado de maquina
uint8_t u8query; //puntero query message


// fin declaracion de variables

// configuracion


/**
 *  Modbus object declaration
 *  u8id : node id = 0 for master, = 1..247 for slave
 *  u8serno : serial port (use 0 for Serial)
 *  u8txenpin : 0 for RS-232 and USB-FTDI 
 *               or any pin number > 1 for RS-485
 */
 
Modbus master(0,1,10);  //LO CONECTO EN SERIAL1 ARDUINO MEGA


//fin configuracion


//this is a structure which contains a query to a slave device

modbus_t telegram;

//fin


unsigned long u32wait; //timer for the modbus


void setup() {

  pinMode(SSerialTxcontrol,OUTPUT);
  
 //telegram 0:read registers
 
 telegram.u8id=1;  //slave address

 telegram.u8fct=3; //function code (registers read)

 telegram.u16RegAdd=1; //start address in slave 

 telegram.u16CoilsNo=22; //number of coils or registers to read

 telegram.au16reg=au16data; //pointer to a memory array in the Arduino



 master.begin(19200,SERIAL_8N1); //baud-rate at 19200
 master.setTimeOut(5000); //if there is no anwers roll over
 u32wait=millis()+1000;
 u8state=u8query=0;


 //comunicacion serie

 Serial.begin(19200);

}

void loop() {

  switch(u8state) {
    case 0:
      if(millis()>u32wait) u8state++; //wait state
      break;

    case 1:
      master.query(telegram);//send query only once
      u8state++;
      break;

    case 2:
      master.poll(); //check incoming messages 

      if (master.getState() == COM_IDLE) {
        u8state ++;
        u32wait=millis()+1000;}
        break;

    case 3:
      u8state=0;

      Serial.print("identificador  : ");
      Serial.println(au16data[0]);

      Serial.print("FOV : ");
      Serial.println(au16data[1]);
      
      Serial.print("MODELO : ");
      Serial.println(au16data[2]);

      Serial.print("REF : ");
      Serial.println(au16data[3]);
      
      Serial.print("BIT ");
      Serial.println(au16data[4]);
      
      Serial.print("PARITY: ");
      Serial.println(au16data[5]);
      
      Serial.print("STOP : ");
      Serial.println(au16data[6]);
      
      Serial.print("ADITIONAL ");
      Serial.println(au16data[7]);

      Serial.print("RAD ");
      Serial.println(au16data[8]);
      
      Serial.print("TEMP ");
      Serial.println(au16data[9]);
      
      Serial.print("AZ : ");
      Serial.println(au16data[14]);
      
      Serial.print("ELEV : ");
      Serial.println(au16data[15]);

      Serial.print("ACEL Z");
      Serial.println(au16data[22]);
      
      

      
      Serial.println("_____________________");
      delay(2000);


      break;



  }






}

LECTURAS:

CONEXIONADO:

MASS_Technical_Specifications.pdf (631 KB)

Ninguna idea del motivo? Sigo probando cosas incluso otro código y obtengo mismas lecturas erróneas.

Indicar que el sensor funciona pues conectándolo a través de usb al pc y usando el programa que trae si arroja lecturas válidas.
Gracias

cambiaste el timeout?

surbyte:
cambiaste el timeout?

master.setTimeOut(5000); //if there is no anwers roll over

A esto te refieres verdad? Sí acabo de probar a subirlo y sigo obteniendo mismo resultado.

Sigo probando cosas y nada, no sé si será un problema de código o hardware. Pero creo están todas las conexiones correctas y el sensor conectandolo por medio de rs485-usb al pc y usando el programita que trae sí da los valores correctos.

Gracias por tu respuesta

Los primeros datos estan bien?

Tengo una observación.
EL manual dice que los datos son enteros con signo y lo destaca
Tu estas solicitando enteros SIN SIGNO

uint16_t au16data[22]; // array de datos

intenta usar

int au16data[22];

Sí, los primeros datos son correctos y los muestra bien, el identificador, modelo, numero de referencia... incluso los valores de elevación por ejemplo.

Sí tienes razón se me pasó cambiar el formato a entero con signo, lo acabo de hacer y aunque arroja valores con "más sentido" siguen sin ser válidos, ahora arroja de forma aleatoria el 310 y -619 en la temperatura y sigue mostrando 0 en la radiación.

Muchas gracias por la aportación

Añado imagen del programa que trae de fábrica para su lectura, indicar que en este algunas veces tambien ocurre de forma identica lo de la temperatura, es decir conmuta aleatoriamente entre 310 -619, pero si conecto y desconecto la alimentación del sensor ya funciona correctamente.

En este captura se ve como funciona correctamente dando de forma estable una temp de 29,5, la radiación es cero pero porque no le está incidiendo sol en el mmento de la imagen.

Si funcionando de forma correcta en el pc, unicamente cambiando los pines rs485+ y rs485-y pasandolos al modulo max485 del arduino, ya empieza como siempre a dar el problema.

Creo he sacado alguna conclusiones del motivo por el que falla:

En vez de usar directamente el programa de fábrica he probado a descargar otro, donde los parámetros a configurar son los mismos que los que se configuran en el código Arduino:

Como se ve, la trama que se envía es: 01 03 00 01 00 16, pero esta difiere de la que aparece en el programa propio y original del sensor que como vemos de la imagen del comentario anterior es: 01 03 00 08 00 0F 84 0C. Por tanto usando este programa y como se ve en la imagen obtengo los mismos datos erróneos que en Arduino.

Me descargué otro programa de comunicacón Modbus en el cual sí me dejaba modificar más parámetros como "FIRST REGISTER" y "MINUS OFFSET" los cuales modificándolos sí he podido crear una trama idéntica a la del programa original y ya mencionada:01 03 00 08 00 0F 84 0C. Ahora sí funciona de forma correcta:

La pregunta es, como introduzco dichos parámetros en el código Arduino? Y existe alguna forma de imprimir por pantalla la trama que estoy enviando con Arduino al sensor para comprobar si es la correcta?

Muchas Gracias

Por lo visto tienes mal la configuración del telegrama. La respuesta debe estar en la implementación de Modbus que utilices en tu arduino. Dicho sea de paso ¿que librería estas utilizando?

Justamente yo le pedí x MP que pasara el link para poder ver si hay modo de mostrar el telegrama.

Puede haber dos errores, uno en el formato de la palabra: el protocolo modbus no especifica el orden de los dos byte que se utilizan para formar una palabra.
Y el otro es leer en un formato equivocado, por ejemplo en este caso leer una palabra sin signo por una con signo. No basta cambiar el formato de la variable que recibe el dato, tiene que ser una forma diferente de leer el dato desde la implementación de la librería. Me inclino por este error porque suele leer correctamente los datos menores a 256 y ser incoherentes si son mayores.

Aquí adjunto el link a la librería usada:

Finalmente lo pude solucionar, más un poco prueba error que otra cosa pero bueno, ya funciona correctamente. El problema era efectivamente el primer registro de lectura, que había definido a 1 y viendo la trama que enviaba el programa original y luego usando otros como los ya mencionados programas de pc para comunicación pude deducir después de alguna que otra prueba fallida que el inicio de trama era el 8;

Muchas gracias a ambos por vuestra ayuda.

Un saludo