ESP-Modbus¶
Overview¶
The Modbus serial communication protocol is de facto standard protocol widely used to connect industrial electronic devices. Modbus allows communication among many devices connected to the same network, for example, a system that measures temperature and humidity and communicates the results to a computer. The Modbus protocol uses several types of data: Holding Registers, Input Registers, Coils (single bit output), Discrete Inputs. Versions of the Modbus protocol exist for serial port and for Ethernet and other protocols that support the Internet protocol suite. There are many variants of Modbus protocols, some of them are:
Modbus RTU
— This is used in serial communication and makes use of a compact, binary representation of the data for protocol communication. The RTU format follows the commands/data with a cyclic redundancy check checksum as an error check mechanism to ensure the reliability of data. Modbus RTU is the most common implementation available for Modbus. A Modbus RTU message must be transmitted continuously without inter-character hesitations. Modbus messages are framed (separated) by idle (silent) periods. The RS-485 interface communication is usually used for this type.
Modbus ASCII
— This is used in serial communication and makes use of ASCII characters for protocol communication. The ASCII format uses a longitudinal redundancy check checksum. Modbus ASCII messages are framed by leading colon (“:”) and trailing newline (CR/LF).
Modbus TCP/IP or Modbus TCP
— This is a Modbus variant used for communications over TCP/IP networks, connecting over port 502. It does not require a checksum calculation, as lower layers already provide checksum protection.
Modbus port specific API overview¶
ESP-IDF supports Modbus Serial/TCP slave and master protocol stacks (port) and provides Modbus controller interface API to interact with user application.
The functions below are used to create and then initialize actual Modbus controller interface for Serial/TCP port accordingly:
-
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
-
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
-
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_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
Modbus common interface API overview¶
The function initializes the Modbus controller interface and its active context (tasks, RTOS objects and other resources).
-
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.
-
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.
The function is used to setup communication parameters of the Modbus stack. See the Modbus controller API documentation for more information. Note: The communication structure provided as a parameter is different for serial and TCP communication mode.
mbc_slave_set_descriptor()
: Initialization of slave descriptor.
mbc_master_set_descriptor()
: Initialization of master descriptor.
The Modbus stack uses parameter description tables (descriptors) for communication. These are different for master and slave implementation of stack and should be assigned by the API call before start of communication.
-
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_master_start
(void)¶ Start Modbus communication stack.
- Return
ESP_OK Success
ESP_ERR_INVALID_ARG Modbus stack start error
Modbus controller start function. Starts stack and interface and allows communication.
-
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_master_destroy
(void)¶ Destroy Modbus controller and stack.
- Return
ESP_OK Success
ESP_ERR_INVALID_STATE Parameter error
This function stops Modbus communication stack and destroys controller interface.
There are some configurable parameters of modbus_controller interface and Modbus stack that can be configured using KConfig values in “Modbus configuration” menu. The most important option in KConfig menu is “Enable Modbus stack support …” for appropriate communication mode that allows to select master or slave stack for implementation. See the examples for more information about how to use these API functions.
Modbus slave interface API overview¶
The slave stack requires the user defined structures which represent Modbus parameters accessed by stack. These structures should be prepared by user and be assigned to the modbus_controller interface using mbc_slave_set_descriptor()
API call before start of communication.
The interface API functions below are used for Modbus slave application:
-
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
The function initializes Modbus communication descriptors for each type of Modbus register area (Holding Registers, Input Registers, Coils (single bit output), Discrete Inputs). Once areas are initialized and the mbc_slave_start()
API is called the Modbus stack can access the data in user data structures by request from master. See the mb_register_area_descriptor_t
and example for more information.
-
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
The blocking call to function waits for event specified in the input parameter as event mask. Once master access the parameter and event mask matches the parameter the application task will be unblocked and function will return ESP_OK. See the mb_event_group_t
for more information about Modbus event masks.
-
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 structuretimeout
: Timeout in milliseconds to read information from parameter queue
The function gets information about accessed parameters from modbus controller event queue. The KConfig ‘CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE’ key can be used to configure the notification queue size. The timeout parameter allows to specify timeout for waiting notification. The mb_param_info_t
structure contain information about accessed parameter.
Modbus master interface API overview¶
The Modbus master implementation requires parameter description table be defined before start of stack. This table describes characteristics (physical parameters like temperature, humidity, etc.) and links them to Modbus registers in specific slave device in the Modbus segment. The table has to be assigned to the modbus_controller interface using mbc_master_set_descriptor()
API call before start of communication.
Below are the interface API functions that are used to setup and use Modbus master stack from user application and can be executed in next order:
-
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 tablenum_elements
: number of elements in the table
Assigns parameter description table for Modbus controller interface. The table has to be prepared by user according to particular implementation. Note: TCP communication stack requires to setup additional information about modbus slaves that corresponds to each address(index) used in description table. This information with IP addresses of the slaves is assigned using communication structure and interface setup call.
-
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)
This function sends data request as defined in parameter request, waits response from corresponded slave and returns status of command execution. This function provides a standard way for read/write access to Modbus devices in the network.
-
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 idparam_info
: pointer to pointer of characteristic data.
The function gets information about supported characteristic defined as cid. It will check if characteristic is supported and returns its description.
-
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.
The function reads data of characteristic defined in parameters from Modbus slave device and returns its data. The additional data for request is taken 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.
The function writes characteristic’s value defined as a name and cid parameter in corresponded slave device. The additional data for parameter request is taken from master parameter description table.
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.
protocols/modbus/serial/mb_slave
protocols/modbus/serial/mb_master
protocols/modbus/tcp/mb_tcp_slave
protocols/modbus/tcp/mb_tcp_master
Please refer to the specific example README.md for details.