esp-idf: Missing MB_TCP_UID in xMBMasterTCPPortSendResponse ( ) (IDFGH-4636)
Environment
- Module or chip used: [ESP32-WROOM-32]
- IDF version:
v4.3-dev-2586-g526f682397 - Build System: [idf.py]
- Compiler version :
xtensa-esp32-elf-gcc (crosstool-NG esp-2020r3) 8.4.0 - Operating System: [Linux]
- Using an IDE?: [Yes] Eclipse
- Power Supply: [USB]
Problem Description
I am implementing a Modbus TCP/IP application where I need to use the slave addresses [1, 2, 200]. Despite the issue I reported
a few days ago (https://github.com/espressif/esp-idf/issues/6437), I came across another one. The problem lies in the function
xMBMasterTCPPortSendResponse() in port_tcp_master.c and specifically in this part of the code (lines 900+):
// If socket active then send data
if (pxInfo->xSockId > -1) {
// Apply TID field to the frame before send
pucMBTCPFrame[MB_TCP_TID] = (UCHAR)(pxInfo->usTidCnt >> 8U);
pucMBTCPFrame[MB_TCP_TID + 1] = (UCHAR)(pxInfo->usTidCnt & 0xFF);
int xRes = xMBMasterTCPPortWritePoll(pxInfo, pucMBTCPFrame, usTCPLength, MB_TCP_SEND_TIMEOUT_MS);
When we send data using Modbus TCP/IP usually we don’t need to include the Unit Identifier byte and we set it to 0. However,
in applications where we need the slave address this byte needs to be set to the desired value. I searched throughout the entire
Modbus software you provided and there isn’t any set of the pucMBTCPFrame[MB_TCP_UID] value. Therefore, I propose, in the above piece of code to be added the following line:
pucMBTCPFrame[MB_TCP_UID] = (UCHAR)(xMbPortConfig.ucCurSlaveIndex & 0xFF);
I checked the send and receive packets and the problem was that the MB_TCP_UID byte in the pucMBTCPFrame was always 0.
Steps to reproduce
- If you don’t have a Modbus device ready, use a slave simulator and set a simple holding register with slave address !=0
- Create a trivial Modbus master TCP/IP application with the esp32 (maybe the example provided already in github) and try to get the value on that slave address of the slave.
- Print the send and receive data in
port_tcp_master.cin (the end ofvMBTCPPortMasterReadPacket()and inxMBMasterTCPPortWritePoll()
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 17
Hi @crmabs ,
Can the kconfig option “FMB_TCP_UID_ENABLED” help you to communicate with your inverter? There are many different modbus devices with custom options and behavior that for example support UID = 0, and also other UIDs at the same time. Please tell your interesting stories here… Thanks.
@crmabs ,
the master init is here master supports the list of slaves. The master takes the uid for slave from data dictionary. The ip address is defined in the
slave_ip_address_tablewhich is assigned using the fieldip_addrin the communication structure. During the initialization master creates the list of slaves info where associates each slave uid with its IP address then uses it to connect to each slave. If the initialization of master is not completed correctly the master can not write to the slave which is not correctly registered in the port layer and is not connected.The
slave_uidin the communication structure is used only for slave and is dummy field for the master. In current implementation if you need to send data to different slave UID with the same IP you need to add the additional CID in data dictionary and add the same address in IP table for this CID.As per your log and code the master assigns the UID field incorrectly as if the
CONFIG_FMB_TCP_UID_ENABLEDis not set, but it is set according to your sdkconfig. Then your slave drops the frame because of this. The functionality related toFMB_TCP_UID_ENABLEDis tested before the merge and confirmed as functional. The issue can be observed due to incorrectFMB_TCP_UID_ENABLEDconfiguration or if the incorrect version of the component is compiled instead of correct one. Please make sure you exclude the old component and use new one in your application. To exclude old component you need to include the line ‘set(EXCLUDE_COMPONENTS freemodbus)’ in your CMakeLists.txt file and use the manifest file like here. Please take a look to your *.map file to make sure if correct component is included into your project. I think you may be using the esp-idf v4.4 and do not exclude that component correctly. The generatatedsdkconfigfile should include theCONFIG_FMB_TCP_UID_ENABLED=yThe below is the log of TCP master with component esp-modbus v1.0.10. The “UID to send: 1” is what is actually set in the MBAP frame.
Please check the recommendations above then clean and rebuild your project. Let me know if you still have problems with this.
Update: not related but please decrease your
CONFIG_FMB_PORT_TASK_PRIOto lower value. The priority = 23, may prevent esp-timer to work correctly.