Skip to content
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

RTU slave responds to requests with different slave address #709

Open
philippludwig opened this issue Aug 2, 2023 · 1 comment
Open

Comments

@philippludwig
Copy link

philippludwig commented Aug 2, 2023

I am using libmodbus 3.1.6 and have the situation, that my modbus RTU slave application answers to requests for address 1, even though it has address 10.

Debug output:

Waiting for an indication...
<01><04><75><4A><00><01><0A><10>
Request for slave 1 ignored (not 10)
[01][04][02][36][FD][6F][11]
Waiting for a confirmation...
ERROR Connection timed out: select
<01><04><75><4B><00><01><5B><D0>Confirmation to ignore
[01][04][02][4B][FC][8F][81]
Waiting for an indication...
<01><04><75><44><00><02><2B><D2>
Request for slave 1 ignored (not 10)
[01][04][04][00][00][E2][B2][33][51]
Waiting for a confirmation...
ERROR Connection timed out: select
<01><04><75><46><00><01><CA><13>Confirmation to ignore
[01][04][02][69][98][96][CA]
Waiting for an indication...
<01><04><75><47><00><01><9B><D3>
Request for slave 1 ignored (not 10)
[01][04][02][79][D8][9A][FA]
Waiting for a confirmation...

So we can see that the request for slave 1 is ignored. However, the device on the other end of the line still receives data. I tried it with a proprietary device and with modpoll: Receiving data is possible, without regard for the modbus address.

Here is the relevant part of the code (error checking omitted for brevity):

ctx = modbus_new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
modbus_connect(ctx);
modbus_set_slave(ctx, 10);

I have seen that this was also asked on the mailing list, but no responses.


From reading the libmodbus source, I believe this happens because _modbus_rtu_check_integrity returns 0 which gets propagated up in _modbus_receive_msg, which’s return code is unused in the remaining part of the RTU code – but that is just my limited understanding of the code base.


Suggested fix: I changed this code in modbus-rtu.c:

/* Following call to check_confirmation handles this error */
        return 0;

to:

/* Following call to check_confirmation handles this error */
        return -1;

And now my application only answers to requests for slave address 1. However, I did not opened a PR because I am not sure if I misunderstood either how to use libmodbus correctly or how slave addresses are supposed to work. Furthermore, I am not sure if this introduces any side-effects.

@akmubi
Copy link

akmubi commented Sep 21, 2023

I had a similar issue. modbus_receive returns message length. So if slave ID doesn't match, then you just get 0 (empty message), so you could detect this case, I guess.

The solution is just check returned message length. If it's positive (>0) you can process the message.

int rc = 0;
ctx = modbus_new_rtu("/dev/ttyUSB0", 115200, 'N', 8, 1);
modbus_set_slave(ctx, 0xF0);
modbus_rtu_set_serial_mode(ctx, MODBUS_RTU_RS232);
modbus_connect(ctx);
mb_mapping = modbus_mapping_new(MODBUS_MAX_READ_BITS, 0, MODBUS_MAX_READ_REGISTERS, 0);

while(1) {
    rc = modbus_receive(ctx, query);
    if (rc > 0) {
        print_query(query, MODBUS_RTU_MAX_ADU_LENGTH);
    }
}

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

2 participants