-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add modbus gateway approach (slave tcp - master serial)
- Loading branch information
Showing
19 changed files
with
1,468 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# The following lines of boilerplate have to be in your project's CMakeLists | ||
# in this exact order for cmake to work correctly | ||
cmake_minimum_required(VERSION 3.5) | ||
|
||
set(EXCLUDE_COMPONENTS examples test_app test freemodbus) | ||
|
||
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. | ||
list(APPEND EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) | ||
|
||
# Include parameters from common modbus folder | ||
set(MB_PARAMS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../mb_example_common") | ||
list(APPEND EXTRA_COMPONENT_DIRS "${MB_PARAMS_DIR}") | ||
|
||
include($ENV{IDF_PATH}/tools/cmake/project.cmake) | ||
project(modbus_tcp_master) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# | ||
# This is a project Makefile. It is assumed the directory this Makefile resides in is a | ||
# project subdirectory. | ||
# | ||
|
||
PROJECT_NAME := modbus_tcp_master | ||
|
||
EXTRA_COMPONENT_DIRS := ../../../ | ||
EXTRA_COMPONENT_DIRS += ../../mb_example_common | ||
EXTRA_COMPONENT_DIRS += $(IDF_PATH)/examples/common_components/protocol_examples_common | ||
EXCLUDE_COMPONENTS := test freemodbus | ||
|
||
include $(IDF_PATH)/make/project.mk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 | | ||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | | ||
|
||
# Modbus TCP Slave to Modbus Serial gateway example | ||
|
||
This example demonstrates using of FreeModbus stack port implementation for ESP32 targets as a TCP gateway device. | ||
This implementation is able to read/write requests from external TCP Master and translate them to the slave devices connected into Modbus segment. The modbus data dictionary is not used but the mapping areas are defined in the Modbus TCP to reflect the values in its memory (this can be disabled). | ||
|
||
The Gateway gets requests from Slave TCP and translates the request to installed Modbus Master instance previously configured. | ||
The translation and mapping teqnique uses the approach with wrapped callback read/write functions to make the adapter to translate the data between instances. This example is prepared from scratch to just demonstrate possible approach for the gateway. Other approaches can be used to override the component sources and realize the gateway object for data translation. The adapter functionality is located in mb_lib library which exposes some internals of installed modbus library. | ||
|
||
STATUS: WIP, only holding registers are supported (functionality will be extended later). | ||
|
||
The instances for the modbus parameters are common for master and slave examples and located in `examples/protocols/modbus/mb_example_common` folder. | ||
|
||
The Kconfig ```Modbus slave address``` - CONFIG_MB_SLAVE_ADDR parameter in slave example can be configured to create Modbus multi slave segment. | ||
|
||
Simplified Modbus connection schematic for example test: | ||
``` | ||
MB_DEVICE_ADDR1 | ||
------------- ------------- | ||
| | Network | | | ||
| Slave 1 |---<>--+---<>---| Master | | ||
| | | | | ||
------------- ------------- | ||
``` | ||
Modbus multi slave segment connection schematic: | ||
``` | ||
MB_DEVICE_ADDR1 | ||
------------- | ||
| | | ||
| Slave 1 |---<>--+ | ||
| | | | ||
------------- | | ||
MB_DEVICE_ADDR2 | | ||
------------- | ------------- | ||
| | | | | | ||
| Slave 2 |---<>--+---<>---| Master | | ||
| | | | | | ||
------------- | ------------- | ||
MB_DEVICE_ADDR3 | | ||
------------- Network (Ethernet or WiFi connection) | ||
| | | | ||
| Slave 3 |---<>--+ | ||
| | | ||
------------- | ||
``` | ||
|
||
## Hardware required : | ||
Option 1: | ||
PC (Modbus TCP Slave application) + ESP32 based development board with modbus_tcp_slave example. | ||
|
||
Option 2: | ||
Several ESP32 based boards flashed with modbus_tcp_slave example software to represent slave devices. The IP slave addresses for each board have to be configured in `Modbus Example Configuration` menu according to the communication table of example. | ||
One ESP32 based development board should be flashed with modbus_master example and connected to the same network. All the boards require configuration of network settings as described in `examples/common_components/protocol_examples_common`. | ||
|
||
## How to setup and use an example: | ||
|
||
### Configure the application | ||
Start the command below to setup configuration: | ||
``` | ||
idf.py menuconfig | ||
``` | ||
|
||
The communication parameters of Modbus stack allow to configure it appropriately but usually it is enough to use default settings. | ||
See the help string of parameters for more information. | ||
There are three ways to configure how the master example will obtain slave IP addresses in the network: | ||
* Enable CONFIG_MB_MDNS_IP_RESOLVER option allows to query for modbus services provided by Modbus slaves in the network and automatically configure IP table. This requires to activate the same option for each slave with unique modbus slave address configured in `Modbus Example Configuration` menu. | ||
|
||
### Setup external Modbus slave devices or emulator | ||
Option 1: | ||
Configure the external Modbus master software according to port configuration parameters used in the example. The Modbus Slave application can be used with this example to emulate slave devices with its parameters. Use official documentation for software to setup emulation of slave devices. | ||
|
||
Option 2: | ||
Other option is to have the modbus_slave example application flashed into ESP32 based board and connect boards together as showed on the Modbus connection schematic above. See the Modbus slave API documentation to configure communication parameters and slave addresses as defined in "Example parameters definition" table above. | ||
|
||
### Build and flash software of master device | ||
Build the project and flash it to the board, then run monitor tool to view serial output: | ||
``` | ||
idf.py -p PORT flash monitor | ||
``` | ||
|
||
(To exit the serial monitor, type ``Ctrl-]``.) | ||
|
||
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. | ||
|
||
### Connect to the device IP from external TCP Master | ||
|
||
Connect the external Modbus TCP Master software to the slave IP address showed in the log. The mDNS service can be used to connect to the device. | ||
|
||
## Example Output | ||
Example output of the application: | ||
``` | ||
I (4463) esp_netif_handlers: example_netif_sta ip: 192.168.88.247, mask: 255.255.255.0, gw: 192.168.88.1 | ||
I (4463) example_connect: Got IPv4 event: Interface "example_netif_sta" address: 192.168.88.247 | ||
I (4473) example_common: Connected to example_netif_sta | ||
I (4473) example_common: - IPv4 address: 192.168.88.247, | ||
I (4483) wifi:Set ps type: 0, coexist: 0 | ||
I (4483) MB_TCP_SLAVE_PORT: Socket (#54), listener on port: 1502, errno=0 | ||
I (4493) MB_TCP_SLAVE_PORT: Protocol stack initialized. | ||
I (4553) uart: queue free spaces: 20 | ||
I (4553) SLAVE_TEST: Modbus master stack initialized... | ||
I (4553) SLAVE_TEST: Modbus slave stack initialized. | ||
I (4553) SLAVE_TEST: Start modbus test... | ||
I (11883) wifi:<ba-add>idx:0 (ifx:0, 64:d1:54:1a:23:5b), tid:0, ssn:5, winSize:64 | ||
I (12923) MB_TCP_SLAVE_PORT: Socket (#55), accept client connection from address: 192.168.88.249 | ||
W (13233) port_stub: callback __wrap_eMBRegHoldingCB, 0x3ffcd975, 1, 5 | ||
W (13233) GW_TCP_BUF: 54 f6 00 00 00 06 01 03 0a 00 00 05 | ||
I (13283) GW: Received response from serial slave. | ||
I (13283) SLAVE_TEST: HOLDING READ (12756870 us), ADDR:0, TYPE:2, INST_ADDR:0x3ffb4ec4, SIZE:5 | ||
W (14503) port_stub: callback __wrap_eMBRegHoldingCB, 0x3ffcd975, 1, 5 | ||
W (14503) GW_TCP_BUF: 54 f7 00 00 00 06 01 03 0a 00 00 05 | ||
I (14533) GW: Received response from serial slave. | ||
I (14543) SLAVE_TEST: HOLDING READ (14010727 us), ADDR:0, TYPE:2, INST_ADDR:0x3ffb4ec4, SIZE:5 | ||
W (15753) port_stub: callback __wrap_eMBRegHoldingCB, 0x3ffcd975, 1, 5 | ||
W (15753) GW_TCP_BUF: 54 f8 00 00 00 06 01 03 0a 00 00 05 | ||
I (15813) GW: Received response from serial slave. | ||
I (15813) SLAVE_TEST: HOLDING READ (15284289 us), ADDR:0, TYPE:2, INST_ADDR:0x3ffb4ec4, SIZE:5 | ||
W (17023) port_stub: callback __wrap_eMBRegHoldingCB, 0x3ffcd975, 1, 5 | ||
W (17023) GW_TCP_BUF: 54 f9 00 00 00 06 01 03 0a 00 00 05 | ||
I (17073) GW: Received response from serial slave. | ||
I (17073) SLAVE_TEST: HOLDING READ (16544129 us), ADDR:0, TYPE:2, INST_ADDR:0x3ffb4ec4, SIZE:5 | ||
W (18293) port_stub: callback __wrap_eMBRegHoldingCB, 0x3ffcd975, 1, 5 | ||
W (18293) GW_TCP_BUF: 54 fa 00 00 00 06 01 03 0a 00 00 05 | ||
I (18343) GW: Received response from serial slave. | ||
I (18353) SLAVE_TEST: HOLDING READ (17818814 us), ADDR:0, TYPE:2, INST_ADDR:0x3ffb4ec4, SIZE:5 | ||
W (18663) port_stub: callback __wrap_eMBRegHoldingCB, 0x3ffcd979, 1, 2 | ||
W (18663) GW_TCP_BUF: 54 fb 00 00 00 0b 01 10 00 00 00 02 04 00 00 42 | ||
W (18673) GW_TCP_BUF: 5c | ||
I (18713) GW: Received response from serial slave. | ||
I (18723) SLAVE_TEST: HOLDING WRITE (18192158 us), ADDR:0, TYPE:1, INST_ADDR:0x3ffb4ec4, SIZE:2 | ||
I (18723) SLAVE_TEST: Modbus controller destroyed. | ||
``` | ||
The example reads the characteristics from serial slave device(s) over TCP. The output line describes the characteristics read from serial slave device and reflected in this gateway. | ||
|
||
Modbus Serial Slave Log: | ||
Rx:003002-01 03 00 01 00 05 D4 09 | ||
Tx:003003-01 03 0A 5C 42 55 AA 55 AA 55 AA 55 AA 9A BC | ||
Rx:003004-01 03 00 01 00 05 D4 09 | ||
Tx:003005-01 03 0A 5C 42 55 AA 55 AA 55 AA 55 AA 9A BC | ||
Rx:003006-01 03 00 01 00 05 D4 09 | ||
Tx:003007-01 03 0A 5C 42 55 AA 55 AA 55 AA 55 AA 9A BC | ||
Rx:003008-01 03 00 01 00 05 D4 09 | ||
Tx:003009-01 03 0A 5C 42 55 AA 55 AA 55 AA 55 AA 9A BC | ||
Rx:003010-01 03 00 01 00 05 D4 09 | ||
Tx:003011-01 03 0A 5C 42 55 AA 55 AA 55 AA 55 AA 9A BC | ||
|
||
Modbus TCP Master log: | ||
Tx:007118-56 CF 00 00 00 06 01 03 00 00 00 05 | ||
Rx:007119-56 CF 00 00 00 0D 01 03 0A 14 7A 40 FE D7 0A 40 23 EB 85 | ||
Tx:007120-56 D0 00 00 00 06 01 03 00 00 00 05 | ||
Rx:007121-56 D0 00 00 00 0D 01 03 0A A3 D7 41 10 D7 0A 40 23 EB 85 | ||
Tx:007122-56 D1 00 00 00 0B 01 10 00 00 00 02 04 00 00 42 30 | ||
Rx:007123-56 D1 00 00 00 06 01 10 00 00 00 02 | ||
Tx:007124-56 D2 00 00 00 06 01 03 00 00 00 05 | ||
Rx:007125-56 D2 00 00 00 0D 01 03 0A CC CD 3F 8C D7 0A 40 23 EB 85 | ||
Tx:007126-56 D3 00 00 00 06 01 03 00 00 00 05 | ||
Rx:007127-56 D3 00 00 00 0D 01 03 0A CC CD 40 0C D7 0A 40 23 EB 85 | ||
Tx:007128-56 D4 00 00 00 06 01 03 00 00 00 05 | ||
Rx:007129-56 D4 00 00 00 0D 01 03 0A 33 34 40 53 D7 0A 40 23 EB 85 | ||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
set(PROJECT_NAME "gw_slave_tcp_master_serial") | ||
|
||
idf_component_register(SRCS "gw_slave_tcp_master_serial.c" | ||
INCLUDE_DIRS ".") | ||
|
||
add_subdirectory(mb_lib) | ||
target_link_libraries(${COMPONENT_LIB} PUBLIC mb_lib) | ||
|
||
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
menu "Modbus TCP over RTU gateway example Configuration" | ||
|
||
config MB_SLAVE_ADDR | ||
int "Modbus slave address" | ||
range 1 247 if !FMB_TCP_UID_ENABLED | ||
range 0 247 if FMB_TCP_UID_ENABLED | ||
default 1 | ||
help | ||
This is the Modbus slave address in the network. | ||
The address is used as an index to resolve slave ip address. | ||
|
||
config MB_MDNS_IP_RESOLVER | ||
bool "Resolve slave addresses using mDNS service" | ||
default y | ||
help | ||
This option allows to use mDNS service to resolve IP addresses of the Modbus slaves. | ||
If the option is disabled the ip addresses of slaves are defined in static table. | ||
|
||
config MB_UART_PORT_ONE | ||
bool | ||
default y | ||
depends on (ESP_CONSOLE_UART_NUM !=1) && (SOC_UART_NUM > 1) | ||
|
||
config MB_UART_PORT_TWO | ||
bool | ||
default y | ||
depends on (ESP_CONSOLE_UART_NUM !=2) && (SOC_UART_NUM > 2) | ||
|
||
config MB_UART_PORT_NUM | ||
int "UART port number" | ||
range 0 2 if MB_UART_PORT_TWO | ||
default 2 if MB_UART_PORT_TWO | ||
range 0 1 if MB_UART_PORT_ONE | ||
default 1 if MB_UART_PORT_ONE | ||
help | ||
UART communication port number for Modbus example. | ||
|
||
config MB_UART_BAUD_RATE | ||
int "UART communication speed" | ||
range 1200 115200 | ||
default 115200 | ||
help | ||
UART communication speed for Modbus example. | ||
|
||
config MB_UART_RXD | ||
int "UART RXD pin number" | ||
range 0 34 if IDF_TARGET_ESP32 | ||
range 0 23 if IDF_TARGET_ESP32C6 | ||
range 0 56 if IDF_TARGET_ESP32P4 | ||
default 22 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32P4 | ||
range 0 46 if IDF_TARGET_ESP32S2 | ||
range 0 47 if IDF_TARGET_ESP32S3 | ||
range 0 19 if IDF_TARGET_ESP32C3 | ||
range 0 20 if IDF_TARGET_ESP32C2 | ||
range 0 27 if IDF_TARGET_ESP32H2 | ||
default 8 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 | ||
default 8 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32H2 | ||
help | ||
GPIO number for UART RX pin. See UART documentation for more information | ||
about available pin numbers for UART. | ||
|
||
config MB_UART_TXD | ||
int "UART TXD pin number" | ||
range 0 34 if IDF_TARGET_ESP32 | ||
range 0 23 if IDF_TARGET_ESP32C6 | ||
range 0 56 if IDF_TARGET_ESP32P4 | ||
default 23 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32P4 | ||
range 0 46 if IDF_TARGET_ESP32S2 | ||
range 0 47 if IDF_TARGET_ESP32S3 | ||
range 0 19 if IDF_TARGET_ESP32C3 | ||
range 0 20 if IDF_TARGET_ESP32C2 | ||
range 0 27 if IDF_TARGET_ESP32H2 | ||
default 9 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 | ||
default 9 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32H2 | ||
help | ||
GPIO number for UART TX pin. See UART documentation for more information | ||
about available pin numbers for UART. | ||
|
||
config MB_UART_RTS | ||
int "UART RTS pin number" | ||
range 0 34 if IDF_TARGET_ESP32 | ||
range 0 23 if IDF_TARGET_ESP32C6 | ||
range 0 56 if IDF_TARGET_ESP32P4 | ||
default 20 if IDF_TARGET_ESP32P4 | ||
default 18 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32C6 | ||
range 0 46 if IDF_TARGET_ESP32S2 | ||
range 0 47 if IDF_TARGET_ESP32S3 | ||
range 0 19 if IDF_TARGET_ESP32C3 | ||
range 0 20 if IDF_TARGET_ESP32C2 | ||
range 0 27 if IDF_TARGET_ESP32H2 | ||
default 10 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 | ||
default 10 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32H2 | ||
help | ||
GPIO number for UART RTS pin. This pin is connected to | ||
~RE/DE pin of RS485 transceiver to switch direction. | ||
See UART documentation for more information about available pin | ||
numbers for UART. | ||
|
||
choice MB_COMM_MODE | ||
prompt "Modbus communication mode" | ||
default MB_COMM_MODE_RTU if CONFIG_FMB_COMM_MODE_RTU_EN | ||
help | ||
Selection of Modbus communication mode option for Modbus. | ||
|
||
config MB_COMM_MODE_RTU | ||
bool "RTU mode" | ||
depends on FMB_COMM_MODE_RTU_EN | ||
|
||
config MB_COMM_MODE_ASCII | ||
bool "ASCII mode" | ||
depends on FMB_COMM_MODE_ASCII_EN | ||
|
||
endchoice | ||
|
||
endmenu |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# | ||
# "main" pseudo-component makefile. | ||
# | ||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) |
Oops, something went wrong.