Closed tom9672 closed 2 years ago
BTW, the 'sum of all pdo in an out data' mean the count of pdos or the byte of pdo? and how to get the sum of pdo in an in data. In the above code, Is the way of disable the tpdos and rpdos right?
I have this issue because, I have a motor, it runs well on twincat3, but the status word often changed from 4663 to 568 in while running, as a result it stops.
my whole code of this test:
from turtle import pd
import pysoem
import ctypes
import time
from JASD_PDO_conf import OutputPdo
from JASD_PDO_conf import InputPdo
modes_of_operation = {
'No mode': 0,
'Profile position mode': 1,
'Velocity mode':2,
'Profile velocity mode': 3,
'Homing mode': 6,
'Cyclic synchronous position mode': 8,
'Cyclic synchronous velocity mode': 9,
'Cyclic synchronous torque mode': 10,
}
master = pysoem.Master()
master.open('\\Device\\NPF_{267091CF-E38D-4EED-AAC8-1A0692194D59}')
master.config_init()
dev1 = master.slaves[0]
# dev2 = master.slaves[1]
# dev3 = master.slaves[2]
def convert_input_data(data):
return InputPdo.from_buffer_copy(data)
def dev1_config_func(slave_pos):
dev1.sdo_write(0x6083,0x0,bytes(ctypes.c_uint32(100000)))
dev1.sdo_write(0x6084,0x0,bytes(ctypes.c_uint32(100000)))
# dev1.sdo_write(0x6060,0x0,bytes(ctypes.c_int8(1)))
dev1.sdo_write(0x607F,0x0,bytes(ctypes.c_uint32(500000)))
dev1.sdo_write(0x6080,0x0,bytes(ctypes.c_uint32(3000)))
dev1.sdo_write(0x1601,0x0,bytes(ctypes.c_uint16(0)))
dev1.sdo_write(0x1602,0x0,bytes(ctypes.c_uint16(0)))
dev1.sdo_write(0x1603,0x0,bytes(ctypes.c_uint16(0)))
dev1.sdo_write(0x1A01,0x0,bytes(ctypes.c_uint16(0)))
dev1.sdo_write(0x1A02,0x0,bytes(ctypes.c_uint16(0)))
dev1.sdo_write(0x1A03,0x0,bytes(ctypes.c_uint16(0)))
def dev2_config_func(slave_pos):
dev2.sdo_write(0x6083,0x0,bytes(ctypes.c_uint32(100000)))
dev2.sdo_write(0x6084,0x0,bytes(ctypes.c_uint32(100000)))
# dev1.sdo_write(0x6060,0x0,bytes(ctypes.c_int8(1)))
dev2.sdo_write(0x607F,0x0,bytes(ctypes.c_uint32(500000)))
dev2.sdo_write(0x6080,0x0,bytes(ctypes.c_uint32(3000)))
dev2.sdo_write(0x1601,0x0,bytes(ctypes.c_uint16(0)))
dev2.sdo_write(0x1602,0x0,bytes(ctypes.c_uint16(0)))
dev2.sdo_write(0x1603,0x0,bytes(ctypes.c_uint16(0)))
dev2.sdo_write(0x1A01,0x0,bytes(ctypes.c_uint16(0)))
dev2.sdo_write(0x1A02,0x0,bytes(ctypes.c_uint16(0)))
dev2.sdo_write(0x1A03,0x0,bytes(ctypes.c_uint16(0)))
def dev3_config_func(slave_pos):
dev3.sdo_write(0x6083,0x0,bytes(ctypes.c_uint32(100000)))
dev3.sdo_write(0x6084,0x0,bytes(ctypes.c_uint32(100000)))
# dev1.sdo_write(0x6060,0x0,bytes(ctypes.c_int8(1)))
dev3.sdo_write(0x607F,0x0,bytes(ctypes.c_uint32(500000)))
dev3.sdo_write(0x6080,0x0,bytes(ctypes.c_uint32(3000)))
dev3.sdo_write(0x1601,0x0,bytes(ctypes.c_uint16(0)))
dev3.sdo_write(0x1602,0x0,bytes(ctypes.c_uint16(0)))
dev3.sdo_write(0x1603,0x0,bytes(ctypes.c_uint16(0)))
dev3.sdo_write(0x1A01,0x0,bytes(ctypes.c_uint16(0)))
dev3.sdo_write(0x1A02,0x0,bytes(ctypes.c_uint16(0)))
dev3.sdo_write(0x1A03,0x0,bytes(ctypes.c_uint16(0)))
dev1.config_func = dev1_config_func
# dev2.config_func = dev2_config_func
# dev3.config_func = dev3_config_func
master.config_map()
def pdo_process():
master.send_processdata()
master.receive_processdata(1_000)
time.sleep(0.01)
if master.state_check(pysoem.SAFEOP_STATE, 50_000) == pysoem.SAFEOP_STATE:
master.state = pysoem.OP_STATE
master.send_processdata()
master.receive_processdata(1_000)
master.write_state()
master.state_check(pysoem.OP_STATE, 5_000_000)
if master.state == pysoem.OP_STATE:
output_data = OutputPdo()
# init
output_data.Control_Word = 15
dev1.output = bytes(output_data)
# dev2.output = bytes(output_data)
# dev3.output = bytes(output_data)
pdo_process()
# set mode
output_data.Mode_Operation = 1
dev1.output = bytes(output_data)
# dev2.output = bytes(output_data)
# dev3.output = bytes(output_data)
pdo_process()
else:
print('failed to got to op state')
else:
print('failed to got to safeop state')
def pp_relavite(device,output_data,target_pos,speed):
device.sdo_write(0x6081,0x0, bytes(ctypes.c_uint32(speed)))
output_data.Target_Position = target_pos
device.output = bytes(output_data)
pdo_process()
output_data.Control_Word = 95
device.output = bytes(output_data)
pdo_process()
output_data.Control_Word =79
device.output = bytes(output_data)
pdo_process()
# convert_input_data(device.input).Status_word != 1591
curr_pos = convert_input_data(device.input).actual_position
while convert_input_data(device.input).actual_position not in range(curr_pos+target_pos-100,curr_pos+target_pos+100):
pdo_process()
#print(convert_input_data(device.input).Status_word)
def pp_absolute(device,output_data,target_pos,speed):
device.sdo_write(0x6081,0x0, bytes(ctypes.c_uint32(speed)))
output_data.Target_Position = target_pos
device.output = bytes(output_data)
pdo_process()
output_data.Control_Word = 31
device.output = bytes(output_data)
pdo_process()
output_data.Control_Word = 15
device.output = bytes(output_data)
pdo_process()
# convert_input_data(device.input).Status_word != 1591
while convert_input_data(device.input).actual_position not in range(target_pos-100,target_pos+100):
pdo_process()
#print(convert_input_data(device.input).Status_word)
try:
for i in range(50):
pp_relavite(dev1,output_data,100000,200000)
# pp_relavite(dev2,output_data,100000,200000)
# pp_relavite(dev3,output_data,100000,200000)
pp_absolute(dev1,output_data,0,200000)
# pp_absolute(dev2,output_data,0,200000)
# pp_absolute(dev3,output_data,0,200000)
except KeyboardInterrupt:
print('stopped')
dev1.output = bytes(len(dev1.output))
# dev2.output = bytes(len(dev2.output))
# dev3.output = bytes(len(dev2.output))
master.send_processdata()
master.receive_processdata(1_000)
master.state = pysoem.PREOP_STATE
master.write_state()
master.close()
To avoid the possible of the effect from other two motor, i commented out the code and not connected them. I tested the motor on twincat3, it seems all good, the twincat seems in scp mode. In the above code. the motor will stopped in pdo loop sometimes, the motor supplier told me maybe the pdo size too large. but it seems the pdo is not large at all. Is there something wrong with the code.
Finally, I figured it out, maybe the motor is form a very small company and its driver can't handle large pdo data. It always stopped suddenly while running... I tried to change its default 1600 and 1A00 by https://github.com/bnjmnp/pysoem/issues/50#issue-1152842201 Now the problem never happened.
Thank you so much!!! BTW, I followed the miniexample, cuz I'm not very understand the basicexample, the code looks more complex. I'd like to know can the basicexample make the devices run better? if so, i will try more effort to learn it.
Hi @bnjmnp , config_map(): return IO map size (sum of all PDO in an out data). Does that mean it returns the count of pdo mapping? but it returns me the same number, after i sdo_write to 1601-1603 and 1A01-1A03, cuz i only need to use 1600 and 1A00. I do the sdo_write in the config_func
I know write pdos need to be done in pre op state. so i also tried to do
the return of master.config_map() is always 144, and the send_overlap_processdata() is always 172. My purpose is to reduce the pdo data in every send and receive process. Do you have any suggestions