stlehmann / pyads

Python wrapper for TwinCAT ADS
MIT License
254 stars 94 forks source link

Read by name returns c_long, read structure by name returns int #251

Closed gegiarmo closed 3 years ago

gegiarmo commented 3 years ago

I'm writing a program to copy over a data buffer from TwinCAT 3, to do data logging. I have a structure defined in TwinCAT, and I have a duplicate of that struct defined in python. When I read an individual value from that structure, from TwinCAT, I get a c_type with the correct value. When I read the struct as a whole, python turns that same value into an INT, which gives the wrong value. When looking at the binary equivalents, the INT is packing a bunch of 0s at the end of what would be the ctype, causing it to store the wrong value. Note that I have the type set as DINT in both TwinCAT and in my python struct. Snippet below. The value of the variable, iGHEIVR203_maxPS, is 50, as defined on the PLC.

stFIFObuffer = (

Pressure Limits

('iGHEIVR202_maxPS', pyads.PLCTYPE_DINT,1),
('iGHEIVR203_maxPS', pyads.PLCTYPE_DINT,1),
('iLOXIVR202_maxPS', pyads.PLCTYPE_DINT,1),
('iLOXIVR204_maxPS', pyads.PLCTYPE_DINT,1),
('iGNIVR202_maxPS', pyads.PLCTYPE_DINT,1),
('iGNIVR203_maxPS', pyads.PLCTYPE_DINT,1),

Main Vehicle Power

('bMVB', pyads.PLCTYPE_BOOL,1)

)

connect to plc and open connection

plc = pyads.Connection('127.0.0.1.1.1', pyads.PORT_TC3PLC1) plc.open()

write int value by name

plc.write_by_name("MAIN.stBuffer.bGHEIVR202", 0)

i = plc.read_by_name("MAIN.stBuffer.iGHEIVR203_maxPS",PLCTYPE_DINT,1)

stBuffer = plc.read_structure_by_name("MAIN.stBuffer",stFIFObuffer,1,pyads.size_of_structure(stFIFObuffer))

print(i) print(stBuffer) print(stBuffer['iGHEIVR203_maxPS'])

print(type(i)) print(type(stBuffer['iGHEIVR203_maxPS']))

gegiarmo commented 3 years ago

Solved. Needed {attribute ‘pack_mode’ := ‘1’} on the PLC side as stated in the read_structure_by_name description.