Error reading DWord type device

34 views
Skip to first unread message

Александр Поздняков

unread,
Dec 24, 2018, 5:34:30 AM12/24/18
to libmodbus

Hi! I'm trying to read data from high-speed counter HC202 (DWord, see the screenshot below) inside Delta AS228T PLC using libmodbus TCP:


uint16_t test_data[10];
modbus_read_registers
(mb, 64715, 1, test_data);

But it returns "Invalid data" error. Reading Word or Bit type devices works fine, but it fails with DWord type. Would you please explain to me how to make it work?


scr_01.png

Hans Carlsson

unread,
Dec 24, 2018, 11:07:43 AM12/24/18
to libmodbus
Hi,

Does it perhaps work with uneven adress?

Mvh
Hans

Chuck Watson

unread,
Dec 24, 2018, 11:22:32 AM12/24/18
to libm...@googlegroups.com

Try adjusting your address up or down one number and see if that works.

 

Look up zero based addressing verses one based addressing.

--
Vous recevez ce message, car vous êtes abonné au groupe Google Groupes "libmodbus".
Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le concernant, envoyez un e-mail à l'adresse libmodbus+...@googlegroups.com.
Pour obtenir davantage d'options, consultez la page https://groups.google.com/d/optout.

image001.png

Александр Поздняков

unread,
Dec 24, 2018, 11:31:19 AM12/24/18
to libmodbus
No, it doesn't work with addresses 64512-64768 either - tried to change it but no success.

понедельник, 24 декабря 2018 г., 19:07:43 UTC+3 пользователь Hans Carlsson написал:

Александр Поздняков

unread,
Dec 24, 2018, 11:34:14 AM12/24/18
to libmodbus
No, unfortunately this doesn't solve the problem - still get "Invalid data".

понедельник, 24 декабря 2018 г., 19:22:32 UTC+3 пользователь Chuck Watson написал:

Rakesh Patel

unread,
Dec 24, 2018, 11:42:56 AM12/24/18
to libm...@googlegroups.com
I think it will read only 16bits data only...

See the below link



--

Chuck Watson

unread,
Dec 24, 2018, 11:44:52 AM12/24/18
to libm...@googlegroups.com

I just noticed that your statement is not correct.

 

modbus_read_registers(mb, 64715, 1, test_data);

 

Change the 1 to 2. This is the number of 16 bit registers. For a DWord, you need to read at least two 16 bit registers.

 

From: libm...@googlegroups.com <libm...@googlegroups.com> On Behalf Of ????????? ?????????
Sent: Monday, December 24, 2018 5:34 AM
To: libmodbus <libm...@googlegroups.com>
Subject: Error reading DWord type device

 

Hi! I'm trying to read data from high-speed counter HC202 (DWord, see the screenshot below) inside Delta AS228T PLC using libmodbus TCP:

--

image001.png

Alexander

unread,
Dec 24, 2018, 11:50:53 AM12/24/18
to libmodbus
No, this also doesn't work :(

понедельник, 24 декабря 2018 г., 19:44:52 UTC+3 пользователь Chuck Watson написал:

Alexander

unread,
Dec 24, 2018, 11:56:17 AM12/24/18
to libmodbus
Yeah, I think you're right... But maybe there is a code workaround? By the way, it's possible to move data into two Word (16-bit) registers inside PLC and read these two registers through libmodbus TCP - only this works.

понедельник, 24 декабря 2018 г., 19:42:56 UTC+3 пользователь Rakesh Patel написал:

Rakesh Patel

unread,
Dec 24, 2018, 11:59:32 AM12/24/18
to libm...@googlegroups.com
Don't you read two times. With two addresses as per below.. and combined these two words


modbus_read_registers(mb, 64715, 1, test_data)
modbus_read_registers(mb, 64716, 1, test_data)

Alexander

unread,
Dec 24, 2018, 12:06:52 PM12/24/18
to libmodbus
Tried this but test_data is empty, because modbus_read_registers fails every time and returns "Invalid data" error. Still no luck :(

понедельник, 24 декабря 2018 г., 19:59:32 UTC+3 пользователь Rakesh Patel написал:

ZipperSnake

unread,
Dec 27, 2018, 3:24:41 PM12/27/18
to libm...@googlegroups.com
Try with another slave then, just to rule out the possibility that the PLC can't handle it.
I have used Modsim32 alot. It runs on your PC. There are demos at http://www.win-tech.com/html/demos.htm
But I don't know what limitations there are in the demo version.
GL

Chuck Watson

unread,
Dec 27, 2018, 3:42:20 PM12/27/18
to libm...@googlegroups.com

The other thing to try is to use Kepware software for testing. It runs for free in demo mode for an hour and is simple to use. If I am having problems with a device, using Kepware is the first test I do.

 

With Kepware, you can:

  1. Quickly try several combinations of COMM settings to figure out what works.
  2. Try different data types and byte orders to format/translate the data to your expected value.
  3. Verifies that the device actually does work and communicates.
  4. Verifies cabling as well.

Alexander

unread,
Dec 28, 2018, 1:29:31 AM12/28/18
to libmodbus
Tried with modpoll (https://www.modbusdriver.com/modpoll.html) - works fine only with "Daniel/Enron single 32-bit word" mode. Is there such an opportunity in libmodbus?

четверг, 27 декабря 2018 г., 23:24:41 UTC+3 пользователь Hans Carlsson написал:

Alexander

unread,
Dec 28, 2018, 1:32:49 AM12/28/18
to libmodbus
The command line is: 
modpoll -m tcp -t4:int -e -r 64715 -c 1 -1 192.168.0.2

четверг, 27 декабря 2018 г., 23:24:41 UTC+3 пользователь Hans Carlsson написал:
Try with another slave then, just to rule out the possibility that the PLC can't handle it.

Alexander

unread,
Dec 28, 2018, 1:34:56 AM12/28/18
to libmodbus
Looks like the problem is in "Daniel/Enron single 32-bit word" mode. Is there such an opportunity in libmodbus?

четверг, 27 декабря 2018 г., 23:42:20 UTC+3 пользователь Chuck Watson написал:

Alexander

unread,
Dec 28, 2018, 2:22:17 AM12/28/18
to libmodbus
I think libmodbus library needs some changes as described here in the last post: https://control.com/thread/963527780#963527780

Patrick Boettcher

unread,
Dec 28, 2018, 3:08:36 AM12/28/18
to Alexander, libm...@googlegroups.com
Hi Alex,
In this email thread at some point there was a table showing modbus
address bigger than what fits in 16bit (>65535). How do you think that
should work, knowing that modbus address (with libmodbus) are limited?

Are the values you are reading to be interpreted as floats?

Is your client/master a little endian (x86, (most) arms)?

Could you (again?) sent some examples of what

modbus_set_debug(ctx, TRUE);
uint16_t buf[2];
int ret = modbus_read_registers(ctx, addr, 2, buf);
printf("%#x %#x (%d)\n", buf[0], buf[1], ret);

shows? And what you would expect (as done with other software
clients/master?)

Could you make an issue on github for easier referencing?

Thansk,
--
Patrick.



Alexander

unread,
Dec 28, 2018, 4:32:34 AM12/28/18
to libmodbus
Helo Patrick,

The thing is simplier than it seemed to be: I just forced libmodbus to work fine with the following code:
uint16_t test_data[2];
num = modbus_read_registers(mb, 64714, 1, test_data);
Form1->Caption = (long)test_data[0] << 16 | test_data[1];
However, I had to remove the following lines from modbus.c and reassemble the library:
1135. rc = check_confirmation(ctx, req, rsp, rc);
1136.        if (rc == -1)
1137.            return -1;
I'm not so an advanced programmer and specialist, but Enron-Daniels mode implies big-endian format and it can be seen from: test_data[0] << 16 | test_data[1] (need to swap high and low parts), however another registers (Word type) are little-endian. And libmodbus cant't take more data than requested - that's the point. In my case I read one register but I would actually get 2 registers returned (one 32 bit value) instead of the usual one 16 bit register.

Shame on me, but I have never used Github and don't know how to use it - need some time to learn. What is the proper way to deal with my suggested changes (rather than jsut deleting part of code)?


пятница, 28 декабря 2018 г., 11:08:36 UTC+3 пользователь Patrick Boettcher написал:

Patrick Boettcher

unread,
Dec 28, 2018, 5:00:12 AM12/28/18
to Alexander, libm...@googlegroups.com
On Fri, 28 Dec 2018 01:32:34 -0800 (PST)
Alexander <wayneen...@yandex.ru> wrote:

> Helo Patrick,
>
> The thing is simplier than it seemed to be: I just forced libmodbus
> to work fine with the following code:
> uint16_t test_data[2];
> num = modbus_read_registers(mb, 64714, 1, test_data);
> Form1->Caption = (long)test_data[0] << 16 | test_data[1];
> However, I had to remove the following lines from modbus.c and
> reassemble the library:
> 1135. rc = check_confirmation(ctx, req, rsp, rc);
> 1136. if (rc == -1)
> 1137. return -1;


check_confirmation should not return -1. We should
look inside check_confirmation() to see which part is wrong. Maybe the
CRC is wrong.

> I'm not so an advanced programmer and specialist, but Enron-Daniels
> mode implies big-endian format and it can be seen from:
> test_data[*0*] << 16 | test_data[*1*] (need to swap high and low
> parts), however another registers (Word type) are little-endian.

It should not be that, because libmodbus does not analyze the structure
of the data, it's just bytes.

> And
> libmodbus cant't take more data than requested - that's the point. In
> my case I read one register but I would actually get 2 registers
> returned (one 32 bit value) instead of the usual one 16 bit register.

Ah ok. So your device returns 4 bytes when doing a read_registers() for
one (normally 2 bytes) register?

And you are saying that depends on the address? The same device can
return 2 bytes for a register access when using other addresses?

We could add an option which will make it ignore the actual length.
This is risky as the buffer could easily overflow. Maybe we would a new
read_register-method which takes a uint32_t *-buffer.

If you make a github issue I will suggest this there.

> Shame on me, but I have never used Github and don't know how to use
> it - need some time to learn. What is the proper way to deal with my
> suggested changes (rather than jsut deleting part of code)?

You can use google-mailing lists, so you can use github, it's much
easier:

Just go here https://github.com/stephane/libmodbus/issues create an
account and report an issue.

best regards,
--
Patrick.

Alexander

unread,
Dec 28, 2018, 6:24:27 AM12/28/18
to libmodbus
Done! Not really, I mean that reading DWord register (32 bit) as a usual 16 bit register leads to 4 bytes return instead of 2 bytes as libmodbus expects. If you look at the registers map in the first post again, you'll see that only HC device have DWord type while others are Word (16 bit) type devices which work with libmodbus like a charm. So I think that new method with uint32_t support would be exactly what is needed.

пятница, 28 декабря 2018 г., 13:00:12 UTC+3 пользователь Patrick Boettcher написал:
Reply all
Reply to author
Forward
0 new messages