MODBUS not working, RS-485

Hello, I'm having problems trying to make the MODBUS RTU Client code work on my board.

I'm devoloping with nrf Connect SDK v2.1.0, using Visual Studio Code.

The board uses an nRF52832 microcontroller, it also has an SN65HVD72DRBR IC(which is like a max3485 module, with different footprint) for RS-485 communication. And I have connected on the other side a TUF-2000 flow meter.

The conection to the RS-485 IC is the following:

PO_02 -> D
PO_03 -> R
PO_04 -> DE
PO_06 -> RE

I have these definitions in the .dts file:

&uart0 {
	modbus-serial {
		compatible = "zephyr,modbus-serial";
		
	};
	status = "okay";
};

These definitions in the .overlay file:

aliases {
    pincarga0 = &pincarga;
	pinpg0 = &pinpg;
    ledrojo = &led0;
    ledazul = &led1;
    uartcaudal = &uart0;
};

&uart0 {
    compatible = "nordic,nrf-uart";
    current-speed = <9600>;
    tx-pin = <2>;
    rx-pin = <3>;
    label = "uart_caudal";
    modbus-serial {
        compatible = "zephyr,modbus-serial";
        status = "okay";
		de-gpios = < &gpio0 4 GPIO_ACTIVE_HIGH >;
        re-gpios = < &gpio0 6 GPIO_ACTIVE_LOW >;
        label = "zephyr_modbus_serial";
  };
};

I added the "label = "zephyr_modbus_serial"", in order for the firmware to compile this part:

#define MODBUS_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(zephyr_modbus_serial)

static int init_modbus_client(void)
{
	const char iface_name[] = {DEVICE_DT_NAME(MODBUS_NODE)};

	client_iface = modbus_iface_get_by_name(iface_name);

	return modbus_init_client(client_iface, client_param);
}

This is the prj.conf part of the modbus_serial:

# UART
CONFIG_SERIAL=y
CONFIG_UART_INTERRUPT_DRIVEN=n
CONFIG_UART_ASYNC_API=y
CONFIG_MODBUS_SERIAL=y
CONFIG_MODBUS=y
CONFIG_MODBUS_ROLE_CLIENT=y
CONFIG_MODBUS_LOG_LEVEL_DBG=y

In the RTU Client example there is no initialization of the uart, nor the uart pins, this is very confusing to me. Seems to me that there is some kind of magic in the "@Arduino_serial" in the overlay file.

I tried adding the "@Arduino_serial" in my overlay or dts files but the firmware does not compile at all, so I kept using "@uart0" as my previous firmware used to work and added the modbus_serial to it.

So, what is the situation now? The firmware compiles, the funtions are called, everything happens except that there is no data coming off the RS-485 module.

Here is the code that uses this modbus client:

caudal_status_t caudal_obtener_lectura(caudal_mensaje_lectura_t *data)
{
  if (init_modbus_client()) {
		LOG_ERR("Modbus RTU client initialization failed");
		return 0;
	}
  uint16_t buffer[8];
  //Leer registro 1: caudal instantaneo
  int err = modbus_read_holding_regs(client_iface, 1, 1, buffer, 2);
  if (err != 0) {
  LOG_ERR("Reading holding register ID 1, 2 words: failed with error %d", err);
  }
  else
  {
    LOG_INF("Caudal instantaneo: %04X%04X", buffer[0], buffer[1]);
  }
  //Leer registro 9: caudal acumulado positivo
  err = modbus_read_holding_regs(client_iface, 1, 9, buffer, 2);
  if (err != 0) {
  LOG_ERR("Reading holding register ID 9, 2 words: failed with error %d", err);
  }
  else
  {
    LOG_INF("Caudal acumulado positivo: %04X%04X", buffer[0], buffer[1]);
  }
  //Leer registro 13: caudal acumulado negativo
  err = modbus_read_holding_regs(client_iface, 1, 13, buffer, 2);
  if (err != 0) {
  LOG_ERR("Reading holding register ID 9, 2 words: failed with error %d", err);
  }
  else
  {
    LOG_INF("Caudal acumulado negativo: %04X%04X", buffer[0], buffer[1]);
  }
  return CAUDAL_STATUS_OK;
}

The logged data in the Ozone Debugger shows rx_timeout:

[00787876] <inf> modbus_serial: RTU timeout 4010 us
[00787877] <dbg> modbus_serial: rtu_tx_adu: uart_buf
                                01 03 00 01 00 02 95 cb                          |........         
[00787878] <dbg> modbus_serial: rtu_tx_adu: Start frame transmission
[00787879] <inf> lorawan_manager: MBOX_GPE_LORAWAN_TX
[00789519] <wrn> modbus: Client wait-for-RX timeout
[00789519] <err> caudal: Reading holding register ID 1, 2 words: failed with error -116
[00789521] <dbg> modbus_serial: rtu_tx_adu: uart_buf
                                01 03 00 09 00 02 14 09                          |........         
[00789521] <dbg> modbus_serial: rtu_tx_adu: Start frame transmission
[00791162] <wrn> modbus: Client wait-for-RX timeout
[00791162] <err> caudal: Reading holding register ID 9, 2 words: failed with error -116
[00791164] <dbg> modbus_serial: rtu_tx_adu: uart_buf
[00792806] <wrn> modbus: Client wait-for-RX timeout
[00792807] <err> caudal: Reading holding register ID 9, 2 words: failed with error -116

I hooked up B, A, DE and RE lines with a logic analizer, this is observed on the moment th function init_modbus_client() is called:

After this moment, there is no change in any of the lines (B, A, RE and DE).

I am very confused as to why there is nothing happening in any of the RS-485 lines. Maybe there is something not intialized correctly, or not initialized at all. I searched through the forum and the internet for answers, they got me this far...

Before all of these, I was using uart_tx function and handling the DE and RE pins separetly, which worked but was very flawed. So I started to look into modbus_serial implemtentation but haven't yet make it work.

If anyone has any inside on this problem I will appreciate it very much.

Related