8000 Reason for the Unaddressed Slave's "Waiting for Confirmation" in Modbus RTU · Issue #799 · stephane/libmodbus · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Reason for the Unaddressed Slave's "Waiting for Confirmation" in Modbus RTU #799

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
hadeszon opened this issue Mar 7, 2025 · 4 comments

Comments

@hadeszon
Copy link
hadeszon commented Mar 7, 2025

I'm trying to understand the behavior of the Addressed Slave and Unaddressed Slave in Libmodbus.

When there's a request for the Slave (Addressed Slave), it respond appropriately.

Waiting for indication...
<00><00><00><00><00><00><00><00>
[00][00][00][00][00][00][00][00][00][00][00]

When there's a request but it is not for the Slave (Unaddressed Slave), it ignores the request.

Waiting for indication...
<01><00><00><00><00><00><00><00>
Request for slave 1 ignored (not 0)
Waiting for confirmation...
ERROR Connection timed out: select
Confirmation to ignore.
Waiting for indication...

But why after ignoring the request, does the Unaddressed Slave also needs to do the "Waiting for confirmation..."?

To give context, it is mentioned in the library the context for "Waiting for confirmation" (wait for response) and "Waiting for indication" (wait for request)

Further looking at the source of Libmodbus, this behavior seems to be intentional.

static int _modbus_rtu_receive(modbus_t *ctx, uint8_t *req)
{
    int rc;
    modbus_rtu_t *ctx_rtu = ctx->backend_data;

    if (ctx_rtu->confirmation_to_ignore) {
        _modbus_receive_msg(ctx, req, MSG_CONFIRMATION);
        /* Ignore errors and reset the flag */
        ctx_rtu->confirmation_to_ignore = FALSE;
        rc = 0;
        if (ctx->debug) {
            printf("Confirmation to ignore\n");
        }
    } else {
        rc = _modbus_receive_msg(ctx, req, MSG_INDICATION);
        if (rc == 0) {
            /* The next expected message is a confirmation to ignore */
            ctx_rtu->confirmation_to_ignore = TRUE;
        }
    }
    return rc;
}

But why does the Unaddressed Slave, waits for a response? What is the purpose or reason for "Waiting for confirmation" in this behavior? And is the behavior even necessary? Is it possible to completely change this to directly ignore without any further implications?

@mhei
Copy link
Contributor
mhei commented Mar 8, 2025

Modbus is typically used with multiple slave devices on one bus, e.g. on a RS-485 bus. When the request is not for your device, then usually there is another one which responds - the addressed one. libmodbus - since on the same shared bus - sees this response too and thus needs to discard it.

@hadeszon
Copy link
Author
hadeszon commented Mar 9, 2025

Thank you mhei, and to further provide explaination regarding your answer, here's a scenario

Master request
01 03 00 01 00 02 97 5B

Slave 1

Waiting for indication….   		(<--- Slave 1 waits for request)
01 03 00 01 00 02 97 5B 		(<--- Master request is received)
01 03 04 00 1D 00 30 6A 21 		(<--- Slave 1 respond)

Slave 0

Waiting for indication….  		  		(<--- Slave 0 waits for request)
01 03 00 01 00 02 97 5B  		  		(<--- Master request is received)
Request for slave 11 ignore (not 20)  		(<--- Slave 20 ignore the request)
Waiting for confirmation…  		  		(<--- To expect the response of another slave)
01 03 04 00 1D 00 30 6A 21  		  		(<--- Slave 1 response)
Confirmation to ignore.  		  		(<--- Ignore the response and discard it)

If Slave 0, does not do the “Waiting for confirmation” and directly listen to request again by doing the “Waiting for indication”, it will accept the response of other slaves in this case Slave 1

Slave 0

Waiting for indication….  		  		(<--- Slave 0 waits for request)
11 03 00 01 00 02 97 5B  		  		(<--- Master request is received)
Request for slave 11 ignore (not 20)  		(<--- Slave 20 ignore the request)
Ignore  		  		  		  		(<--- To not expect the response of another slave)
Waiting for indication….  		  		(<--- Slave 0 waits for request)
01 03 04 00 1D 00 30 6A 21  		  		(<--- Slave 1 response is received as a request)
ERROR CRC received  		  		  	(<--- The request frame is not valid)

In this case, it will process the frame but since the CRC of that frame is invalid, an error will occur then the remaining frame …21 is accepted, which results to error again.

Slave 0 must do the “Waiting for confirmation” to expect that the next receive is the response of another slave in this case Slave 1 and to discard or ignore it.

@mhei
Copy link
Contributor
mhei commented Mar 9, 2025

I think we can close the issue here?

@Zhaotianzheng
Copy link
Zhaotianzheng commented Jun 6, 2025

I got a question. if there is two server device address 1 and 2, device 2 is offline, and client wants to request in a loop act like:

request address 2;     client -> server 2
timeout;                     client time out because device 2 is offline         
request address 1;     client -> server 1
timeout;                     client time out because device 1 is expecting a confirmation to ignore
request address 2;     client -> server 2
...and so on

in this case, the client request address 2, and the address 2 device is offline, at this moment the address 1 server will ignore the further one package. If client after request address 2 and timeout then directly request address 1 server, the address 1 server will ignore this request and needs client to retransmit, but if client just loop this will be a infinite fail loop.

Is this situation should be handled by the client? I feel like if the server just don't wait for confirmation which is not for the server address, there will not have this problem, and even the server get the response comes from other server, because the address is not for it, it will ignore the package anyway. Is there a recommended way to solve this kind of problem?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants
0