libmodbus
libmodbus copied to clipboard
Modbus ASCII issue,
Please read the following carefully before submitting this new issue.
-
Please ensure, that you are really reporting a bug. When in doubt, post a message on https://groups.google.com/forum/#!forum/libmodbus or send an email to [email protected]
-
Please do not open issues to ask questions about using libmodbus. Use the mailing list for this as there are many more people reading that list, who could help you.
-
When using libmodbus from a distribution (Debian, Fedora...), please report the bug first in the bug tracker of the distribution. The reason for doing so is that the package maintainer should have a chance to look at the issue first as it might be a packaging error. If/when the package maintainer comes to the conclusion that is really an upstream bug, then he/she will usually report it here by himself/herself. This is because he/she is interested in staying in the notification chain to decide about a backport as soon as a bugfix is available. Otherwise you (distribution user) will be asked to do so explicitely.
When you get here and you are still convinced that you want report a bug:
-
Use a clear and decriptive title for the issue to identify
-
Which version of libmodbus are you using? you can obtain this information from your package manager or by running
pkg-config --modversion libmodbus
. You can provide the sha1 of the commit if you have fetched the code withgit
. -
Which operating system are you using?
-
Describe the exact steps which reproduce the problem in as many details as possible. For example, the software/equipement which runs the Modbus server, how the clients are connected (TCP, RTU, ASCII) and the source code you are using.
-
Enable the debug mode, libmodbus provides a function to display the content of the Modbus messages and it's very convenient to analyze issues (http://libmodbus.org/docs/latest/modbus_set_debug.html).
Good bug reports provide right and quick fixes!
Finally, thank you very much for using libmodbus and taking the time to file a good bug report. Doing so signals your respect for the developers.
The following template helps you to address the points above. Please delete everything up to and including the following line which starts with ---.
libmodbus version
OS and/or distribution
<e.g. Windows, Linux... version>
Environment
<e.g. CPU architecture, 32 vs. 64 bit...>
Description
<...>
Expected behaviour
<...>
Actual behaviour
<...>
Steps to reproduce the behavior (commands or source code)
<...>
libmodbus output with debug mode enabled
<...>
I'm using libmodbus for ASCII. I'm able to send the request but i'm not getting any response. Can you please help. here is my code below.
modbus_t *ctx = modbus_new_ascii("COM4", 9600, 'N', 8, 1);
int retVal = modbus_set_slave(ctx, 1);
if (retVal == -1)
{
// no error
}
retVal = modbus_connect(ctx);
if (retVal == -1)
{
// no error
}
uint16_t tab_reg[32];
memset(tab_reg, 0, 1 * sizeof(tab_reg));
retVal = modbus_read_registers(ctx, 25,1, tab_reg);
if (retVal == -1)
{
// retrun -1 always
}
What does the documentation for modbus_read_registers say? What would a negative value for parameter number 3 mean?
- My appology, this is type error.@karlp
- While sending this info to slave, I have monitored the port(COM4), it looks like timeout error. Can anyone suggest why it's that. Did I miss anything.
- It throws MODBUS_EXCEPTION_GATEWAY_TARGET exception. what's this mean.
most likely the remote device doesn't understand you and ignored you. You are either using the wrong protocol, wrong wiring (on the other side of your gateway) or have the wrong configuration of your gateway/port/device itself. I don't believe you have any issue that can be resovled with libmodbus tickets though.
By considering your input i have sent the same Ascii frame to the same remote device by using some other external modus send tool. Im getting respnse in this way. So here we can't say this is the problem with remote device or any configuration issue.
I would guess you didn't send the same frame then :) if you turn on libmodbus' debug, you can see the bytes sent and received printed out. You can compare that with what your other tool has done.
I have send the same request(:010300190001E3) using libmodbus dll from my client code. I have used some external tool to monitor that particular port, I'm getting response i.e. :0103020903 and status is always success. But in the libmodbus dll client code I'm getting always return value -1. That means device sending response. But my libmodbus dll is unable to handle this response. Correct me if I'm wrong. If something I can look into the dll code, pls let me know.
Hi guys,
I have a similar problem in Modbus Ascii. In short, modbus_connect
works correctly, but a subsequent call to modbus_write_bit
yields -1.
The debug mode told that the library have received the confirmation incorrectly. After looking into the error, I have found that the problem originate from _modbus_receive_msg
in modbus.c
.
_modbus_receive_msg
somehow reads a wrong massage from a serial port (and sometime incomplete)
An external tool confirms that a device sends back right confirmation.
A quick workaround for this would be to change
while (length_to_read != 0) { rc = ctx->backend->select(ctx, &rset, p_tv, length_to_read); if (rc == -1) {
in modbus.c line 386 to
while (length_to_read != 0) { rc = ctx->backend->select(ctx, &rset, p_tv, 1); if (rc == -1) {
I don't know how or why this works and the previous one doesn't. The error only happened in windows. Maybe something about windows' API?
@Ashis-Github where did you get modbus_ascii function from, i have been trying it here and i couldn't get anything. Can you help me out here. Thank you!
@Ashis-Github @Moinelly I would like to know, where there modbus_ascii function, the latest libmodbus, I did not find.
Hi guys,
I have a similar problem in Modbus Ascii too in 2022! I think the library in Windows have received the confirmation incorrectly indeed.
The library uses win32_ser_select
to receive a msg from a serial port and win32_ser_read
to read the msg from win32_ser.buf
. win32_ser_select
may receive some bytes according to length_to_read
in modbus.c
and _modbus_ascii_recv
(calls win32_ser_read
)read character by character to convert each character into byte, but when reading character from the win32_ser.buf
, memcpy starts with the same source address(win32_ser.buf[0]
) every time(in modbus-serial.c
, line 111). That means if win32_ser_select
receives data ':01', _modbus_ascii_recv
may convert it to ':::' wrongly. That's the problem.
@KorlaMarch 's quick workaround works since win32_ser_select
always receives one character now. Another way to avoid this problem is to add a pointer to struct win32_ser
to save the position every time the libarary calls win32_ser_read
. I have no idea which is better...
Add pos
in modbus-serial-private.h
struct win32_ser {
/* File handle */
HANDLE fd;
/* Receive buffer */
uint8_t buf[PY_BUF_SIZE];
/* Received chars */
DWORD n_bytes;
/* win32_ser_read position */
uint8_t* pos;
};
change pos
in win32_ser_read
int win32_ser_read(struct win32_ser *ws, uint8_t *p_msg,
unsigned int max_len)
{
unsigned int n = ws->n_bytes;
if (max_len < n) {
n = max_len;
}
if (ws->pos - ws->buf > PY_BUF_SIZE || ws->pos -ws->buf < -PY_BUF_SIZE) {
assert(0);
ws->pos = ws->buf;
}
if (n > 0) {
memcpy(p_msg, ws->pos, n);
}
ws->n_bytes -= n;
ws->pos += n;
return n;
}
reset pos
when receiving new message
if (ReadFile(ws->fd, &ws->buf, max_len, &ws->n_bytes, NULL)) {
/* Check if some bytes available */
if (ws->n_bytes > 0) {
/* Some bytes read */
ws->pos = ws->buf;
return 1;
} else {
/* Just timed out */
return 0;
}
} else {