struct.error: unpack requires a string argument of length 4

3,815 views
Skip to first unread message

Timothy Arnold

unread,
Jan 21, 2013, 8:17:45 AM1/21/13
to pymo...@googlegroups.com
Hi Guys,

I'm trying to get a 32 bit float from PyModbus. When I "print" the result using decode_32bit_float() I get a floating point number as expected, however when I try to use the value I get the following 

Traceback (most recent call last):
  File "testing3.py", line 19, in <module>
    'float': decoder.decode_32bit_float(),
  File "/usr/lib/python2.6/site-packages/pymodbus-1.1.0-py2.6.egg/pymodbus/payload.py", line 305, in decode_32bit_float
    return unpack(fstring, handle)[0]
struct.error: unpack requires a string argument of length 4


The script is based on the decoder in message_payload.py

-----
#!/usr/bin/env python

from pymodbus.client.sync import ModbusTcpClient as ModbusClient
from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.constants import Endian


client = ModbusClient("192.168.1.100", port=502)
client.connect()
rr = client.read_holding_registers(1000, 2, unit=22)
decoder = BinaryPayloadDecoder.fromRegisters(rr.registers, endian=Endian.Little)
#print decoder.decode_32bit_float()
#  decoder.decode_32bit_float()

print decoder.decode_32bit_float()

decoded = {
        'string': decoder.decode_string(8),
        'float': decoder.decode_32bit_float(),
        '16uint': decoder.decode_16bit_uint(),
        '8int': decoder.decode_8bit_int(),
        'bits': decoder.decode_bits(),
}

print "-" * 60
print "Decoded Data"
print "-" * 60
for name, value in decoded.items():
        print ("%s\t" % name), value

client.close()

----



Thoughts?

Thanks!
Tim

Galen Collins

unread,
Jan 21, 2013, 11:21:39 AM1/21/13
to pymo...@googlegroups.com

You are trying to print a 32 bit value (4 bytes) with only 2 bytes of data.  Is your message really a float (perhaps just decode_16bit_int) or are you reading all the data you need to (4 bytes instead of 2)? 

Timothy Arnold

unread,
Jan 21, 2013, 2:26:06 PM1/21/13
to pymo...@googlegroups.com, pymo...@googlegroups.com
Hi Galen

Thanks for getting back to me!

You are trying to print a 32 bit value (4 bytes) with only 2 bytes of data.  Is your message really a float (perhaps just decode_16bit_int) or are you reading all the data you need to (4 bytes instead of 2)? 

I was under the assumption that read_holding_registers() used address + register count and each register was 16 bit so two registers would be 32 bit long?

I am off to check the modbus spec as clearly I've misunderstood.

incidentally am getting the correct data when printing decoder.decode_32bit_float() but not when trying to put it into a variable.

Thanks
Tim

Galen Collins

unread,
Jan 22, 2013, 10:59:38 AM1/22/13
to pymo...@googlegroups.com
Tim,

I'm sorry you are correct;  I didn't read your code close enough.  Your original decoding statement is working fine (and you are right that each register is 2 bytes of data thus two registers would equal 1 32 bit float).  The problem is that you have those extra decoding statements at the end of your script (that have been left in from the original script).  This is throwing because each call to decode_* will actually advance the pointer to the internal buffer so that you don't have to do that manually.  If you remove that block, then you will be good to go.

Galen

Rohan Tyagi

unread,
Nov 15, 2018, 6:07:22 AM11/15/18
to pymodbus
Hi Tim

I am also getting same issue on my side .
i am getting the correct data when printing decoder.decode_32bit_float() but not when trying to put it into a local  variable  and getting this error
(in decode 32 bit float return unpack(string, handle)[0] struct.error: unpack requires a string argument of length 4).Could you please help me out on this .
Thanks 
Regards
Rohan Tyagi 

sanju dhoomakethu

unread,
Nov 15, 2018, 10:25:36 AM11/15/18
to pymodbus
You can access the decoded data only once, that is precisely the reason why the first decoder statement works in the print but fails the next time. Refer to the comment above for more details.
Reply all
Reply to author
Forward
0 new messages