I have tried init modbus RTU on my nRF9160 with SDK2.5.2 using max485 module but i have faced an error.
This is the error:
*** Booting nRF Connect SDK v2.5.2 ***
[00:00:00.253,417] <inf> modbus_test: Starting Program...
[00:00:00.253,448] <inf> modbus_test: Iface name: ZEPHYR_MODBUS_SERIAL
[00:00:00.253,448] <inf> modbus_test: Client iface: 0
[00:00:00.253,479] <err> modbus_serial: Failed to configure UART
[00:00:00.253,479] <err> modbus: Failed to init MODBUS over serial line
[00:00:00.253,509] <err> modbus_test: Modbus RTU client initialization failed
This is my app.overlay
/*
* Copyright (c) 2024 Your Name
* SPDX-License-Identifier: Apache-2.0
*/
/ {
/*
* Set zephyr,console to uart0, which is the VCOM port on many nRF9160 devkits.
* This keeps your logging separate from the Modbus communication.
*/
chosen {
zephyr,console = &uart0;
};
};
/*
* UART1: Configured for Modbus RTU communication.
*
* Pinout matches your original configuration:
* TX: P0.03
* RX: P0.05
*/
&uart1 {
compatible = "nordic,nrf-uarte";
status = "okay";
current-speed = <9600>; /* Common baud rate for Modbus */
parity = "even"; /* Common parity for Modbus */
/* Pin control for active and sleep states */
pinctrl-0 = <&uart1_default>;
pinctrl-1 = <&uart1_sleep>;
pinctrl-names = "default", "sleep";
modbus0: modbus_serial {
de-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; /* DE control on P0.04 */
re-gpios = <&gpio0 4 GPIO_ACTIVE_LOW>; /* RE control on P0.06 */
compatible = "zephyr,modbus-serial";
status = "okay";
label = "ZEPHYR_MODBUS_SERIAL";
};
};
/*
* UART0: Used for console output (logging).
* This configuration is standard for the nRF9160 DK.
*/
&uart0 {
status = "okay";
current-speed = <115200>;
pinctrl-0 = <&uart0_default>;
pinctrl-1 = <&uart0_sleep>;
pinctrl-names = "default", "sleep";
};
/*
* Pin control definitions for all peripherals.
*/
&pinctrl {
/* Active state pins for Modbus UART */
uart1_default: uart1_default {
group1 {
/* TX pin from your original configuration */
psels = <NRF_PSEL(UART_TX, 0, 3)>;
};
group2 {
/* RX pin from your original configuration */
psels = <NRF_PSEL(UART_RX, 0, 5)>;
bias-pull-up; /* Good practice for RX lines */
};
};
/* Sleep state pins for Modbus UART */
uart1_sleep: uart1_sleep {
group1 {
psels = <NRF_PSEL(UART_TX, 0, 3)>,
<NRF_PSEL(UART_RX, 0, 5)>;
low-power-enable;
};
};
};
This is my main.c:
#include <zephyr/kernel.h>
#include <zephyr/sys/util.h>
#include <zephyr/modbus/modbus.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(modbus_test, LOG_LEVEL_INF);
static int client_iface;
const static struct modbus_iface_param client_param = {
.mode = MODBUS_MODE_RTU,
.rx_timeout = 50000,
.serial =
{
.baud = 9600,
.parity = UART_CFG_PARITY_EVEN,
},
};
#define MODBUS_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(zephyr_modbus_serial)
#define SLAVE_ID 1
#define REG_ADDR 0x1132
static int init_modbus_client(void)
{
const char *iface_name = DT_LABEL(MODBUS_NODE);
LOG_INF("Iface name: %s", iface_name);
client_iface = modbus_iface_get_by_name(iface_name);
if (client_iface < 0)
{
LOG_ERR("Couldn't get client iface");
return -1;
}
LOG_INF("Client iface: %d", client_iface);
return modbus_init_client(client_iface, client_param);
}
void main(void)
{
uint16_t reg_val;
int err;
LOG_INF("Starting Program...");
if (init_modbus_client() != 0)
{
LOG_ERR("Modbus RTU client initialization failed");
return 0;
}
err = modbus_read_holding_regs(client_iface, SLAVE_ID, REG_ADDR, ®_val, 1);
if (err != 0)
{
LOG_ERR("FC03 failed with %d", err);
return 0;
}
else
{
LOG_INF("Reg[4402]=%u", reg_val);
}
}and this is my prj.conf:
# ====================================================================== # FINAL prj.conf # ====================================================================== CONFIG_LOG=y # GPIO CONFIG_GPIO=y # UART CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=n CONFIG_UART_ASYNC_API=y CONFIG_MODBUS=y CONFIG_MODBUS_ROLE_CLIENT=y