Connecting to slave with TCP Modbus on ESP32

ESP_alisitsyn
Posts: 203
Joined: Fri Feb 01, 2019 4:02 pm
Contact:

Re: Connecting to slave with TCP Modbus on ESP32

Postby ESP_alisitsyn » Mon Nov 29, 2021 7:48 pm

Hi @cslehel,

Sorry for the delay with answer.
It is really strange result. I think this is due to non-standard Modbus protocol of the device and we are missing some important aspect. The solution should be very simple. Unfortunately I don't have the device and can not reproduce. I see that your slave and master are in different subnets according to address. This may prevent them to communicate correctly if your network configuration is incorrect. However I can see that your master was able to connect to the slave and this is not an issue then.

If you have time for this investigation I would propose to download the ModbusPoll tool https://modbustools.com/quickstart.html
Configure it to connect to your slave: Menu->Connection..
Setup the register view: Menu->Setup->Read/write Definition... (See the picture).
Menu->Display communication...
Record the communication trafic and send it to me.
This will allow to check the communication trafic with your slave, find more details and help to find a reason for the issue.

I can understand if you decide to continue with the Arduino instead...
Attachments
connection_setup_rw_definitions.png
configure modbus poll tool
connection_setup_rw_definitions.png (36.72 KiB) Viewed 7160 times

cslehel
Posts: 9
Joined: Tue Nov 09, 2021 5:25 pm

Re: Connecting to slave with TCP Modbus on ESP32

Postby cslehel » Tue Nov 30, 2021 5:42 am

No problem for delay alisitsyn, until you say we stop i will try everything you say.
The modbus slave is on a guest wifi network but the devices on both networks can communicate with each other.

For the first 1 or 2 requests always getting timeout errors but after that is ok.

Communication.gif
Communication.gif (17.33 KiB) Viewed 7132 times

Here are the logs:

Code: Select all

Tx:000000-00 00 00 00 00 06 01 03 7D 59 00 01 
Tx:000001-00 01 00 00 00 06 01 03 7D 59 00 01 
Rx:000002-00 01 00 00 00 05 01 03 02 A0 00 
Tx:000003-00 02 00 00 00 06 01 03 7D 59 00 01 
Rx:000004-00 02 00 00 00 05 01 03 02 A0 00 
Tx:000005-00 03 00 00 00 06 01 03 7D 59 00 01 
Rx:000006-00 03 00 00 00 05 01 03 02 A0 00 
Tx:000007-00 04 00 00 00 06 01 03 7D 59 00 01 
Rx:000008-00 04 00 00 00 05 01 03 02 A0 00 
Tx:000009-00 05 00 00 00 06 01 03 7D 59 00 01 
Rx:000010-00 05 00 00 00 05 01 03 02 A0 00 
Tx:000011-00 06 00 00 00 06 01 03 7D 59 00 01 
Rx:000012-00 06 00 00 00 05 01 03 02 A0 00 
Tx:000013-00 07 00 00 00 06 01 03 7D 59 00 01 
Rx:000014-00 07 00 00 00 05 01 03 02 A0 00 

ESP_alisitsyn
Posts: 203
Joined: Fri Feb 01, 2019 4:02 pm
Contact:

Re: Connecting to slave with TCP Modbus on ESP32

Postby ESP_alisitsyn » Tue Nov 30, 2021 10:17 pm

cslehel,

Thank you for your patience and information. Let us try the raw fix below and then based on result I will provide the real existing fix.
Please find your esp-idf folder and the file: esp-idf/components/freemodbus/tcp_master/port/port_tcp_master.c
Fix the line 942 in the file as described below:

Code: Select all

BOOL
xMBMasterTCPPortSendResponse( UCHAR * pucMBTCPFrame, USHORT usTCPLength )
{
    BOOL bFrameSent = FALSE;
    xMbPortConfig.ucCurSlaveIndex = ucMBMasterGetDestAddress();
    MbSlaveInfo_t* pxInfo = vMBTCPPortMasterGetCurrInfo();

    // 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);
        pucMBTCPFrame[MB_TCP_UID] = 0x01; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Insert this line here after line 942
        int xRes = xMBMasterTCPPortWritePoll(pxInfo, pucMBTCPFrame, usTCPLength, MB_TCP_SEND_TIMEOUT_MS);
        if (xRes < 0) {
            ESP_LOGE(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", send data failure, err(errno) = %d(%d)."),
                                           pxInfo->xIndex, pxInfo->xSockId, pxInfo->pcIpAddr, xRes, errno);
            bFrameSent = FALSE;
            pxInfo->xError = xRes;
        } else {
            bFrameSent = TRUE;
            ESP_LOGD(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", send data successful: TID=0x%02x, %d (bytes), errno %d"),
                                                pxInfo->xIndex, pxInfo->xSockId, pxInfo->pcIpAddr, pxInfo->usTidCnt, xRes, errno);
            pxInfo->xError = 0;
            pxInfo->usRcvPos = 0;
            if (pxInfo->usTidCnt < (USHRT_MAX - 1)) {
                pxInfo->usTidCnt++;
            } else {
                pxInfo->usTidCnt = (USHORT)(pxInfo->xIndex << 8U);
            }
        }
        pxInfo->xSendTimeStamp = xMBTCPGetTimeStamp();
    } else {
        ESP_LOGD(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", send to died slave, error = %d"),
                                                  pxInfo->xIndex, pxInfo->xSockId, pxInfo->pcIpAddr, pxInfo->xError);
    }
    vMBMasterPortTimersRespondTimeoutEnable();
    xMBMasterPortEventPost(EV_MASTER_FRAME_SENT);
    return bFrameSent;
}
After fix please recompile the code and restart.

Code: Select all

idf.py fullclean
idf.py build
idf.py flash monitor
The code should include the latest changes I described before. Use the read/write functions with CID as parameter.

Send the results here. Thanks.

cslehel
Posts: 9
Joined: Tue Nov 09, 2021 5:25 pm

Re: Connecting to slave with TCP Modbus on ESP32

Postby cslehel » Sat Dec 04, 2021 12:27 pm

Dear alisitsyn,

its working, i have not received any timeout errors.

Code: Select all

(2880) Modbus Power: Start MB Master
(4880) Modbus Power: MB Master Stack Initialized...
(4880) Modbus Power: MB Test Starting
(5250) Modbus Power: Characteristic #0 Status (x) Value = (0x0200) Parameter Read Success.
(5250) Modbus Power: MB Test Completed.
(6250) Modbus Power: MB Test Starting
(6480) Modbus Power: Characteristic #0 Status (x) Value = (0x0200) Parameter Read Success.
(6480) Modbus Power: MB Test Completed.
(7480) Modbus Power: MB Test Starting
(7730) Modbus Power: Characteristic #0 Status (x) Value = (0x0200) Parameter Read Success.
(7730) Modbus Power: MB Test Completed.

(5030) Modbus Power: Characteristic #0 Status (x) Value = (0x00000200) Parameter Read Success.
(6260) Modbus Power: Characteristic #1 Active Power (W) Value = (0x02a10000) Parameter Read Success.

Active Power: 670
Device Status: On-grid 512
Thank you very much for your time and patience.

ESP_alisitsyn
Posts: 203
Joined: Fri Feb 01, 2019 4:02 pm
Contact:

Re: Connecting to slave with TCP Modbus on ESP32

Postby ESP_alisitsyn » Sat Dec 04, 2021 10:43 pm

@cslehel,

It is good to hear that this works. Your device supports the Modbus RTU over TCP and this is reason why it did not respond. The ESP_Modbus TCP Master is currently does not support the RTU over TCP and sets UID field of MBAP header to 0x00 as per spec. However there are existing fixes that would allow to add this functionality in the TCP master.
The current raw fix just sets MBAP UID field (slave address) to 0x01 just to allow your slave to answer. I expect some other issues of stack that would prevent to fully support your slave due to its non standard things. It is possible to support these things in the stack. This can be addressed in following release. Let me know if you need other help with this.

Update:
The updated master code and component (mb_component folder) that supports correct setting of UID for RTU over TCP is located here:
https://github.com/alisitsyn/modbus_sup ... cp_support

cslehel
Posts: 9
Joined: Tue Nov 09, 2021 5:25 pm

Re: Connecting to slave with TCP Modbus on ESP32

Postby cslehel » Sat Dec 11, 2021 9:07 am

Thank you very much for your support alisitsyn.

With the pucMBTCPFrame[MB_TCP_UID] = 0x01; added the polling is running for hours now.
Only once in an hour i am getting a timeout error, thats acceptable for me.

Code: Select all

(4476618) Modbus Power: Characteristic #1 Active Power (W) Value = (0x02150000) Parameter Read Success.
(4489618) MB_CONTROLLER_MASTER: mbc_master_get_parameter(83): Master get parameter failure, error=(0x107) (ESP_ERR_TIMEOUT).
(4489618) Modbus Power: Characteristic #0 Status (x), Parameter Read Fail.
(4489628) Modbus Power: MB Read Fail, ERROR = 107.
(4491058) MB_CONTROLLER_MASTER: mbc_master_get_parameter(83): Master get parameter failure, error=(0x108) (ESP_ERR_INVALID_RESPONSE).
(4491058) Modbus Power: Characteristic #1 Active Power (W), Parameter Read Fail.
(4491068) Modbus Power: MB Read Fail, ERROR = 108.
(4501508) Modbus Power: Characteristic #0 Status (x) Value = (0x00000200) Parameter Read Success.
The updated code will be available in the next idf version ?

ESP_alisitsyn
Posts: 203
Joined: Fri Feb 01, 2019 4:02 pm
Contact:

Re: Connecting to slave with TCP Modbus on ESP32

Postby ESP_alisitsyn » Thu Dec 30, 2021 2:30 pm

@cslehel,

I can guess several possible reasons for the timeout error that means the slave did not respond during the response timeout that relates to network configuration. In this case, I would recommend doing retries of the request.
The MR with the fix is under the approval and may be available in the new release.

Thank you for the update. Feel free to ask if you have issues.

Who is online

Users browsing this forum: Google [Bot], MicroController and 109 guests