Modbus.poll() from ModbusRtu doesn't work properly

Hi,

I want to read some data from a pyranometer using Modbus, an arduino mega and a max485 converter (to create a rs485 grid, the complete proyect includes several pyranometer connected to the same port of the arduino).

I am using Modbusrtu.h library, but it doesn't seem to work correctly. I am able to transmits data, and the pyranometer responds as it should, but the function modbus.poll() doesn't receive anything. I know i am receiving things because i made a proof conecting the rx to a diferent serial port, and I read the response using Serial.read(). So, the error must be in the receiving part.
As I said, i can read the data from the pyranometer using serial.read(), but this solution is not valid to as i need in a further step to connect more than one pyranometer to the rs485, and i don't know how to manage the responses or controling the data without a library.

I've read this old Forum about the same subject, but it is closed and i don't fully understand the solution given there. What's the problem with the millis()? and how should i modify the library to solve the problem?

I put my code here (it is quite similar to the example code):

#include <ModbusRtu.h>


/**
    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
   u8txenpin pin for txen RS-485 (=0 means USB/RS232C mode)
   u8rxenpin pin for rxen RS-485 (=0 means USB/RS232C mode) NO EN ESTA LIBRERIA
*/
//  Modbus(u8id, u8serno, u8txenpin, u8rxenpin);
Modbus master(0, 3, 22); //ID: 0 (master)
                         //Serial port: 3
                         //Enable pint : any (not use)

/**
   This is an structe which contains a query to an slave device
*/
modbus_t telegram;

//-=-=-=-Variables ModBus-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
uint16_t au16data[16];
uint8_t u8state;       //!< machine state
uint8_t u8query;       //!< pointer to message query
unsigned long u32wait;


//Variables globales
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
float radiometro = 0;


//Variables de la respuesta
unsigned int respuesta[16];       //sin signo porque es como se recibe
unsigned int irradiancia_serie[4];
unsigned long int irradiancia;  //32 bits sin signo
int n_mensaje;


void setup() {

  Serial.begin(19200);
  Serial1.begin(19200);
  Serial2.begin(19200);
  Serial3.begin(19200);

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

  //ENVÍO DE TELEGRAMAS POR FIWARE
  // telegram 0: read registers
  telegram.u8id = 4; // slave address
  telegram.u8fct = 3; // function code (this one is registers read)
  telegram.u16RegAdd = 2; // start address in slave
  telegram.u16CoilsNo = 2; // number of elements (coils or registers) to read
  telegram.au16reg = au16data[0]; // pointer to a memory array in the Arduino





  Serial.println("Estoy en el setup");
  int ID;
  ID = master.getID();
  Serial.println( "ID del maestro (arduino): " + String(ID));

}



void loop() {
  // put your main code here, to run repeatedly:
  radiometro = leeRadiometro();

  Serial.println("Radiometro " + String(radiometro));
  delay(5);
}



float leeRadiometro() {
  master.query( telegram ); // Envía la petición ModBus
  u8state = 1;
  n_mensaje=1;
  do {
    master.poll(); // Chequea la entrada de mensajes
    if (master.getState() == COM_IDLE) {
      u8state = 0;
      u32wait = millis() + 1000; 
      Serial.println("mensaje leido completo ");
    }
  } while (u8state != 0);
  for(int i=0; i<16; i++){
    Serial.print("au16data" + String(i) + ": ");
    Serial.println(au16data[i]);
  }
  
  smartdelay(100);

  
  Serial.print("irradiancia (real): ");
  Serial.println(radiometro);
  Serial.println(String(radiometro));
  Serial.println("**********************************");
  return  (radiometro);
}



static void smartdelay(unsigned long ms)
{
  // Ubicamos el cursor en la primera posición(columna:0) de la segunda línea(fila:1)
  unsigned long start = millis();
  do
  {
    // Intentar recibir secuencia durante milisagundos ms
  } while (millis() - start < ms);
}

And i am using this converter:


those are different to the usuals, this don't include a DE pin, but they admit half-duplex communication

I will appreciate any advice here,
Victoria

The comment is correct, the implementation is wrong. Your au16reg field is not pointing to an array! (Hint: remove the [0]!)

And don't use the String class on AVR Arduinos!

BTW: What exactly do you think is smart in smartdelay()? It's definitely more stupid than calling delay().

okey, i've just correct the [0] thing but the code sill not working.

And don't use the String class on AVR Arduinos!

I don't know what you mean with that. Are you talking about the

Serial.println( "ID del maestro (arduino): " + String(ID));

line? or there is another issue i'm not seing? Anyway i just delete that line and all the others similar as they are not needed.

And, about the smartdelay() funtion, is a thing i have used in other proyect, to avoid the arduino to shut down all the parallel process while the delay() is working. Probably i don't need it here, but i don't have a clue where the error is, so i decided to use it anyway

I still thinking the problem migth be on the library i use, as the anwer seems to not be charge in au16data as it should. I put the link here.