Possible Communication Issues And Solutions

If the examples do not work as expected and slave and master boards are not able to communicate correctly, it is possible to find the reason for errors. The most important errors are described in master example output and formatted as below:

E (1692332) MB_CONTROLLER_MASTER: mbc_master_get_parameter(111): SERIAL master get parameter failure error=(0x107) (ESP_ERR_TIMEOUT).
Table 5 Modbus error codes and troubleshooting

Error

Description

Possible solution

0x106

ESP_ERR_NOT_SUPPORTED - Invalid register request - slave returned an exception because the requested register is not supported.

Refer to slave register map. Check the master data dictionary for correctness.

0x107

ESP_ERR_TIMEOUT - Slave response timeout - Modbus slave did not send response during configured slave response timeout.

Measure and increase the maximum slave response timeout idf.py menuconfig, option CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND. Check physical connection or network configuration and make sure that the slave response can reach the master side. If the application has some high performance tasks with higher priority than CONFIG_FMB_PORT_TASK_PRIO it is recommended to place Modbus tasks on the other core using an option CONFIG_FMB_PORT_TASK_AFFINITY. Configure the Modbus task’s priority CONFIG_FMB_PORT_TASK_PRIO to ensure that the task gets sufficient processing time to handle Modbus stack events.

0x108

ESP_ERR_INVALID_RESPONSE - Received unsupported response from slave or frame check failure. Master can not execute command handler because the command is either not supported or is incorrect.

Check the physical connection then refer to register map of your slave to configure the master data dictionary properly.

0x103

ESP_ERR_INVALID_STATE - Critical failure or FSM sequence failure or master FSM is busy processing previous request.

Make sure your physical connection is working properly. Increase task stack size and check Modbus initialization sequence.

Application Example

The examples below use the FreeModbus library port for serial TCP slave and master implementations accordingly. The selection of stack is performed through KConfig menu option “Enable Modbus stack support …” for appropriate communication mode and related configuration keys.

Please refer to the specific example README.md for details.

API Reference

Unions

union mb_communication_info_t
#include <esp_modbus_common.h>

Device communication structure to setup Modbus controller.

Public Members

mb_mode_type_t mode

Modbus communication mode

uint8_t slave_addr

Modbus slave address field (dummy for master)

uart_port_t port

Modbus communication port (UART) number

uint32_t baudrate

Modbus baudrate

uart_parity_t parity

Modbus UART parity settings

uint16_t dummy_port

Dummy field, unused

struct mb_communication_info_t::[anonymous] [anonymous]
mb_mode_type_t ip_mode

Modbus communication mode

uint16_t ip_port

Modbus port

mb_tcp_addr_type_t ip_addr_type

Modbus address type

void *ip_addr

Modbus address table for connection

void *ip_netif_ptr

Modbus network interface

struct mb_communication_info_t::[anonymous] [anonymous]

Macros

MB_RETURN_ON_FALSE(a, err_code, tag, format, ...)
MB_CONTROLLER_STACK_SIZE
MB_CONTROLLER_PRIORITY
MB_DEVICE_ADDRESS
MB_DEVICE_SPEED
MB_UART_PORT
MB_PAR_INFO_TOUT
MB_PARITY_NONE
_XFER_4_RD(dst, src)
_XFER_2_RD(dst, src)
_XFER_4_WR(dst, src)
_XFER_2_WR(dst, src)

Type Definitions

typedef esp_err_t (*iface_init)(void **)

common interface method types Interface method init

typedef esp_err_t (*iface_destroy)(void)

Interface method destroy

typedef esp_err_t (*iface_setup)(void *)

Interface method setup

typedef esp_err_t (*iface_start)(void)

Interface method start

Enumerations

enum mb_port_type_t

Types of actual Modbus implementation.

Values:

MB_PORT_SERIAL_MASTER = 0x00

Modbus port type serial master.

MB_PORT_SERIAL_SLAVE

Modbus port type serial slave.

MB_PORT_TCP_MASTER

Modbus port type TCP master.

MB_PORT_TCP_SLAVE

Modbus port type TCP slave.

MB_PORT_COUNT

Modbus port count.

MB_PORT_INACTIVE = 0xFF
enum mb_event_group_t

Event group for parameters notification.

Values:

MB_EVENT_NO_EVENTS = 0x00
MB_EVENT_HOLDING_REG_WR = BIT0

Modbus Event Write Holding registers.

MB_EVENT_HOLDING_REG_RD = BIT1

Modbus Event Read Holding registers.

MB_EVENT_INPUT_REG_RD = BIT3

Modbus Event Read Input registers.

MB_EVENT_COILS_WR = BIT4

Modbus Event Write Coils.

MB_EVENT_COILS_RD = BIT5

Modbus Event Read Coils.

MB_EVENT_DISCRETE_RD = BIT6

Modbus Event Read Discrete bits.

MB_EVENT_STACK_STARTED = BIT7

Modbus Event Stack started

enum mb_param_type_t

Type of Modbus parameter.

Values:

MB_PARAM_HOLDING = 0x00

Modbus Holding register.

MB_PARAM_INPUT

Modbus Input register.

MB_PARAM_COIL

Modbus Coils.

MB_PARAM_DISCRETE

Modbus Discrete bits.

MB_PARAM_COUNT
MB_PARAM_UNKNOWN = 0xFF
enum mb_mode_type_t

Modbus serial transmission modes (RTU/ASCII).

Values:

MB_MODE_RTU

RTU transmission mode.

MB_MODE_ASCII

ASCII transmission mode.

MB_MODE_TCP

TCP communication mode.

MB_MODE_UDP

UDP communication mode.

enum mb_tcp_addr_type_t

Modbus TCP type of address.

Values:

MB_IPV4 = 0

TCP IPV4 addressing

MB_IPV6 = 1

TCP IPV6 addressing

Functions

esp_err_t mbc_master_init_tcp(void **handler)

Initialize Modbus controller and stack for TCP port.

Return

  • ESP_OK Success

  • ESP_ERR_NO_MEM Parameter error

  • ESP_ERR_NOT_SUPPORTED Port type not supported

  • ESP_ERR_INVALID_STATE Initialization failure

Parameters
  • [out] handler: handler(pointer) to master data structure

esp_err_t mbc_master_init(mb_port_type_t port_type, void **handler)

Initialize Modbus Master controller and stack for Serial port.

Return

  • ESP_OK Success

  • ESP_ERR_NO_MEM Parameter error

  • ESP_ERR_NOT_SUPPORTED Port type not supported

  • ESP_ERR_INVALID_STATE Initialization failure

Parameters
  • [out] handler: handler(pointer) to master data structure

  • [in] port_type: type of stack

void mbc_master_init_iface(void *handler)

Initialize Modbus Master controller interface handle.

Parameters
  • [in] handler: - pointer to master data structure

esp_err_t mbc_master_destroy(void)

Destroy Modbus controller and stack.

Return

  • ESP_OK Success

  • ESP_ERR_INVALID_STATE Parameter error

esp_err_t mbc_master_start(void)

Start Modbus communication stack.

Return

  • ESP_OK Success

  • ESP_ERR_INVALID_ARG Modbus stack start error

esp_err_t mbc_master_setup(void *comm_info)

Set Modbus communication parameters for the controller.

Return

  • ESP_OK Success

  • ESP_ERR_INVALID_ARG Incorrect parameter data

Parameters
  • comm_info: Communication parameters structure.

esp_err_t mbc_master_set_descriptor(const mb_parameter_descriptor_t *descriptor, const uint16_t num_elements)

Assign parameter description table for Modbus controller interface.

Return

  • esp_err_t ESP_OK - set descriptor successfully

  • esp_err_t ESP_ERR_INVALID_ARG - invalid argument in function call

Parameters
  • [in] descriptor: pointer to parameter description table

  • num_elements: number of elements in the table

esp_err_t mbc_master_send_request(mb_param_request_t *request, void *data_ptr)

Send data request as defined in parameter request, waits response from slave and returns status of command execution. This function provides standard way for read/write access to Modbus devices in the network.

Return

  • esp_err_t ESP_OK - request was successful

  • esp_err_t ESP_ERR_INVALID_ARG - invalid argument of function

  • esp_err_t ESP_ERR_INVALID_RESPONSE - an invalid response from slave

  • esp_err_t ESP_ERR_TIMEOUT - operation timeout or no response from slave

  • esp_err_t ESP_ERR_NOT_SUPPORTED - the request command is not supported by slave

  • esp_err_t ESP_FAIL - slave returned an exception or other failure

Parameters
  • [in] request: pointer to request structure of type mb_param_request_t

  • [in] data_ptr: pointer to data buffer to send or received data (dependent of command field in request)

esp_err_t mbc_master_get_cid_info(uint16_t cid, const mb_parameter_descriptor_t **param_info)

Get information about supported characteristic defined as cid. Uses parameter description table to get this information. The function will check if characteristic defined as a cid parameter is supported and returns its description in param_info. Returns ESP_ERR_NOT_FOUND if characteristic is not supported.

Return

  • esp_err_t ESP_OK - request was successful and buffer contains the supported characteristic name

  • esp_err_t ESP_ERR_INVALID_ARG - invalid argument of function

  • esp_err_t ESP_ERR_NOT_FOUND - the characteristic (cid) not found

  • esp_err_t ESP_FAIL - unknown error during lookup table processing

Parameters
  • [in] cid: characteristic id

  • param_info: pointer to pointer of characteristic data.

esp_err_t mbc_master_get_parameter(uint16_t cid, char *name, uint8_t *value, uint8_t *type)

Read parameter from modbus slave device whose name is defined by name and has cid. The additional data for request is taken from parameter description (lookup) table.

Return

  • esp_err_t ESP_OK - request was successful and value buffer contains representation of actual parameter data from slave

  • esp_err_t ESP_ERR_INVALID_ARG - invalid argument of function or parameter descriptor

  • esp_err_t ESP_ERR_INVALID_RESPONSE - an invalid response from slave

  • esp_err_t ESP_ERR_INVALID_STATE - invalid state during data processing or allocation failure

  • esp_err_t ESP_ERR_TIMEOUT - operation timed out and no response from slave

  • esp_err_t ESP_ERR_NOT_SUPPORTED - the request command is not supported by slave

  • esp_err_t ESP_ERR_NOT_FOUND - the parameter is not found in the parameter description table

  • esp_err_t ESP_FAIL - slave returned an exception or other failure

Parameters
  • [in] cid: id of the characteristic for parameter

  • [in] name: pointer into string name (key) of parameter (null terminated)

  • [out] value: pointer to data buffer of parameter

  • [out] type: parameter type associated with the name returned from parameter description table.

esp_err_t mbc_master_set_parameter(uint16_t cid, char *name, uint8_t *value, uint8_t *type)

Set characteristic’s value defined as a name and cid parameter. The additional data for cid parameter request is taken from master parameter lookup table.

Return

  • esp_err_t ESP_OK - request was successful and value was saved in the slave device registers

  • esp_err_t ESP_ERR_INVALID_ARG - invalid argument of function or parameter descriptor

  • esp_err_t ESP_ERR_INVALID_RESPONSE - an invalid response from slave during processing of parameter

  • esp_err_t ESP_ERR_INVALID_STATE - invalid state during data processing or allocation failure

  • esp_err_t ESP_ERR_TIMEOUT - operation timed out and no response from slave

  • esp_err_t ESP_ERR_NOT_SUPPORTED - the request command is not supported by slave

  • esp_err_t ESP_FAIL - slave returned an exception or other failure

Parameters
  • [in] cid: id of the characteristic for parameter

  • [in] name: pointer into string name (key) of parameter (null terminated)

  • [out] value: pointer to data buffer of parameter (actual representation of json value field in binary form)

  • [out] type: pointer to parameter type associated with the name returned from parameter lookup table.

Unions

union mb_parameter_opt_t
#include <esp_modbus_master.h>

Modbus parameter options for description table.

Public Members

int opt1

Parameter option1

int opt2

Parameter option2

int opt3

Parameter option3

struct mb_parameter_opt_t::[anonymous] [anonymous]
int min

Parameter minimum value

int max

Parameter maximum value

int step

Step of parameter change tracking

struct mb_parameter_opt_t::[anonymous] [anonymous]

Structures

struct mb_parameter_descriptor_t

Characteristics descriptor type is used to describe characteristic and link it with Modbus parameters that reflect its data.

Public Members

uint16_t cid

Characteristic cid

const char *param_key

The key (name) of the parameter

const char *param_units

The physical units of the parameter

uint8_t mb_slave_addr

Slave address of device in the Modbus segment

mb_param_type_t mb_param_type

Type of modbus parameter

uint16_t mb_reg_start

This is the Modbus register address. This is the 0 based value.

uint16_t mb_size

Size of mb parameter in registers

uint16_t param_offset

Parameter name (OFFSET in the parameter structure)

mb_descr_type_t param_type

Float, U8, U16, U32, ASCII, etc.

mb_descr_size_t param_size

Number of bytes in the parameter.

mb_parameter_opt_t param_opts

Parameter options used to check limits and etc.

mb_param_perms_t access

Access permissions based on mode

struct mb_param_request_t

Modbus register request type structure.

Public Members

uint8_t slave_addr

Modbus slave address

uint8_t command

Modbus command to send

uint16_t reg_start

Modbus start register

uint16_t reg_size

Modbus number of registers

Macros

MB_MASTER_CHECK(a, err_code, format, ...)
MB_MASTER_ASSERT(con)

Enumerations

enum mb_descr_type_t

Modbus descriptor table parameter type defines.

Values:

PARAM_TYPE_U8 = 0x00

Unsigned 8

PARAM_TYPE_U16 = 0x01

Unsigned 16

PARAM_TYPE_U32 = 0x02

Unsigned 32

PARAM_TYPE_FLOAT = 0x03

Float type

PARAM_TYPE_ASCII = 0x04

ASCII type

enum mb_descr_size_t

Modbus descriptor table parameter size in bytes.

Values:

PARAM_SIZE_U8 = 0x01

Unsigned 8

PARAM_SIZE_U16 = 0x02

Unsigned 16

PARAM_SIZE_U32 = 0x04

Unsigned 32

PARAM_SIZE_FLOAT = 0x04

Float size

PARAM_SIZE_ASCII = 0x08

ASCII size

PARAM_SIZE_ASCII24 = 0x18

ASCII24 size

PARAM_MAX_SIZE
enum mb_param_perms_t

Permissions for the characteristics.

Values:

PAR_PERMS_READ = 1 << BIT0

the characteristic of the device are readable

PAR_PERMS_WRITE = 1 << BIT1

the characteristic of the device are writable

PAR_PERMS_TRIGGER = 1 << BIT2

the characteristic of the device are triggerable

PAR_PERMS_READ_WRITE = PAR_PERMS_READ | PAR_PERMS_WRITE

the characteristic of the device are readable & writable

PAR_PERMS_READ_TRIGGER = PAR_PERMS_READ | PAR_PERMS_TRIGGER

the characteristic of the device are readable & triggerable

PAR_PERMS_WRITE_TRIGGER = PAR_PERMS_WRITE | PAR_PERMS_TRIGGER

the characteristic of the device are writable & triggerable

PAR_PERMS_READ_WRITE_TRIGGER = PAR_PERMS_READ_WRITE | PAR_PERMS_TRIGGER

the characteristic of the device are readable & writable & triggerable

Functions

esp_err_t mbc_slave_init_tcp(void **handler)

Initialize Modbus Slave controller and stack for TCP port.

Return

  • ESP_OK Success

  • ESP_ERR_NO_MEM Parameter error

  • ESP_ERR_NOT_SUPPORTED Port type not supported

  • ESP_ERR_INVALID_STATE Initialization failure

Parameters
  • [out] handler: handler(pointer) to master data structure

esp_err_t mbc_slave_init(mb_port_type_t port_type, void **handler)

Initialize Modbus Slave controller and stack for Serial port.

Return

  • ESP_OK Success

  • ESP_ERR_NO_MEM Parameter error

  • ESP_ERR_NOT_SUPPORTED Port type not supported

  • ESP_ERR_INVALID_STATE Initialization failure

Parameters
  • [out] handler: handler(pointer) to master data structure

  • [in] port_type: the type of port

void mbc_slave_init_iface(void *handler)

Initialize Modbus Slave controller interface handle.

Parameters
  • [in] handler: - pointer to slave interface data structure

esp_err_t mbc_slave_destroy(void)

Destroy Modbus controller and stack.

Return

  • ESP_OK Success

  • ESP_ERR_INVALID_STATE Parameter error

esp_err_t mbc_slave_start(void)

Start Modbus communication stack.

Return

  • ESP_OK Success

  • ESP_ERR_INVALID_ARG Modbus stack start error

esp_err_t mbc_slave_setup(void *comm_info)

Set Modbus communication parameters for the controller.

Return

  • ESP_OK Success

  • ESP_ERR_INVALID_ARG Incorrect parameter data

Parameters
  • comm_info: Communication parameters structure.

mb_event_group_t mbc_slave_check_event(mb_event_group_t group)

Wait for specific event on parameter change.

Return

  • mb_event_group_t event bits triggered

Parameters
  • group: Group event bit mask to wait for change

esp_err_t mbc_slave_get_param_info(mb_param_info_t *reg_info, uint32_t timeout)

Get parameter information.

Return

  • ESP_OK Success

  • ESP_ERR_TIMEOUT Can not get data from parameter queue or queue overflow

Parameters
  • [out] reg_info: parameter info structure

  • timeout: Timeout in milliseconds to read information from parameter queue

esp_err_t mbc_slave_set_descriptor(mb_register_area_descriptor_t descr_data)

Set Modbus area descriptor.

Return

  • ESP_OK: The appropriate descriptor is set

  • ESP_ERR_INVALID_ARG: The argument is incorrect

Parameters
  • descr_data: Modbus registers area descriptor structure

Structures

struct mb_param_info_t

Parameter access event information type.

Public Members

uint32_t time_stamp

Timestamp of Modbus Event (uS)

uint16_t mb_offset

Modbus register offset

mb_event_group_t type

Modbus event type

uint8_t *address

Modbus data storage address

size_t size

Modbus event register size (number of registers)

struct mb_register_area_descriptor_t

Parameter storage area descriptor.

Public Members

uint16_t start_offset

Modbus start address for area descriptor

mb_param_type_t type

Type of storage area descriptor

void *address

Instance address for storage area descriptor

size_t size

Instance size for area descriptor (bytes)

Macros

MB_SLAVE_CHECK(a, err_code, format, ...)
MB_SLAVE_ASSERT(con)