Closed lancel0 closed 10 years ago
Thank for your research and comment lance!!
I don't think it matters much how you read out data. As long as you get the correct amount of bytes!!
BUT. looked up some official documentation
INT is a 16 bit value. A signed integer with a value range of -32768 to 32767
INT (Integer) 16 Decimal number signed -32768 to 32767 a then using u_int would not work or will give you wrong values if the value is actually negative.
cheers
Stephan.
Thanks for looking over my research Stephen.
I missed the call to bytearray at the end of the db_read function which ensures the returned data is converted to a sequence of bytes. It also explains why making the same read using area_read was failing when trying to read a REAL.
result = client.db_read(200, 16, 4)
log.debug(str(type(result)))
for x in result:
log.debug(str(x))
bytes = ''.join([chr(x) for x in result])
real_num = struct.unpack('>f', bytes)
log.debug(real_num)
result = client.read_area(S7AreaDB, 200, 16, 4)
log.debug(str(type(result)))
for x in result:
log.debug(str(x))
bytes = ''.join([chr(x) for x in result])
real_num = struct.unpack('>f', bytes)
log.debug(real_num)
would give the following result
DEBUG:snap7.client:db_read, db_number:200, start:16, size:4
DEBUG:root:<type 'bytearray'>
DEBUG:root:70
DEBUG:root:119
DEBUG:root:128
DEBUG:root:0
DEBUG:root:(15840.0,)
DEBUG:root:reading area: 132 dbnumber: 200 start: 16: amount 4: wordlen: 2
DEBUG:root:<class 'snap7.client.c_byte_Array_4'>
DEBUG:root:70
DEBUG:root:119
DEBUG:root:-128
DEBUG:root:0
Traceback (most recent call last):
File "/home/llambert/Projects/python-snap7_clean/example/test.py", line 28, in <module>
bytes = ''.join([chr(x) for x in result])
ValueError: chr() arg not in range(256)
Regarding the mapping from Step7 types (wordlen) to ctypes I was using the Siemens documentation here:
http://www.automation.siemens.com/doconweb/pdf/SINUMERIK_SINAMICS_10_2012_E/S7P.pdf?p=1
On page 589 is a table of the elementary data types and their valid values.
I've only used read_db myself when interacting with a PLC. A fix for this problem should be trivial!
I have only tried to read data blocks from an actual PLC, I was using the read_area function only because I was exploring the library.
Disregard my commit on this one, I just saw that stephen created a pull request with a fix.
so if i understand correctly this issue can be closed?
I think this was fixed in this pull request :
ok, then I close this bug report. Please reopen if the problem is not solved.
guys, hi. I just saw your ld pots. I wonder is there any way to read symbol names from the s7400-s71500 CPU via snap7 on raspberry pi3
The db_read and read_area functions use a fixed return type which is a sequence of c_int8. This is done via the wordlen_to_ctypes map.
And then in the function
data is passed by reference to the library to be populated with data from the PLC
The size parameter is then used to determine how many c_int8 units to read.
It might be better to use c_uint8 as the data type so that a sequence of bytes is returned instead of signed integers. I think that the two functions are basically reading a series of bytes from a specific area starting at a given offset so returning something that is analogous to bytes instead of signed integers seems to better match the purpose.
I am not sure if the right thing to do is to modify each function that should return a sequence of bytes or to modify the wordlen_to_ctypes map so that S7WLByte points to c_uint8. Also would it then make sense that S7WLWord and S7WLDWord be changed to point at unsigned types? I haven't read through much of the library so I don't know what all of the use cases for wordlen_to_ctypes are.
Also it appears that in the Snap7 library that WordLen is not the actual word length but used an indicator of the S7 Data Type that is being read or written.
Here is an example from the Snap7 library where it converts to a WordLen value to a the size in bytes for that data type
found in s7_micro_client.cpp
Here is a modified version of read_area I have been using test against a S7-319 CPU reading REALs and INTs.
and here is how I am using it