Closed bolp70 closed 1 year ago
Hi @bolp70,
take a look at issue #30, I guess reading through this will get you a bit further. The TMCM-1617 and TMCM-3213 discussed there also implement the CiA 402 device profile.
Hi bnjmnp, thank you for your help. This is the program I am using. In fact, I do not understand the principle of Rx.PDO and Tx.PDO well. How to switch from TxPD1 and RxPD1 (0x1600 0x1A00) to TxPD2 and RxPD2 (0x1601 0x1A01)? I attach you the modified program, the XML of the engine, and the config recover it with -map
By giving a speed and in operation mode 2, the motor runs but I don't think it uses the PDO.
Le lun. 3 mai 2021 à 22:48, bnjmnp @.***> a écrit :
Hi @bolp70 https://github.com/bolp70,
take a look at issue #30 https://github.com/bnjmnp/pysoem/issues/30, I guess reading through this will get you a bit further. The TMCM-1617 and TMCM-3213 discussed there also implement the CiA 402 device profile.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/bnjmnp/pysoem/issues/33#issuecomment-831524179, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQJ7TTIDDLD3YEK2Z2LHTETTL4D2PANCNFSM44AH4ODQ .
Sorry I didn't get you attachment. You can attach files if you answer directly on GitHub (at issue https://github.com/bnjmnp/pysoem/issues/33).
The TMCM-1617 from my example has only RxPD1 and TxPD1, so the PDO selection object 0x1C12 and 0x1C13 is fixed (to 0x1600 and 0x1A00).
It seems that you can select other PDO configurations, thus you can write for example 0x1601 into subindex 1 of object 0x1C12. In one of the examples you can see how to do this for a Beckhoff device: https://github.com/bnjmnp/pysoem/blob/7dbc6c2aec9f26c7cff911c3aeef0fc73f6c71cc/examples/minimal_example.py#L31
There I set 0x1C12 to 0. With that I don't have any RxPDO as I don't want to send any commands to the device in this example.
Note: It is really the best to update 0x1C12/0x1C13 in these setup-functions.
In your code you could try something like this:
map_1c12_bytes = struct.pack('BxH', 1, 0x1601)
slave.sdo_write(0x1c12, 0, map_1c12_bytes, True)
map_1c13_bytes = struct.pack('BxH', 1, 0x1A01)
slave.sdo_write(0x1c13, 0, map_1c13_bytes, True)
These SDO-writes update subindex 0 and subindex 1 at the same time.
Hi @bolp70,
were you able to solve this?
Hi bnjmnp, I went on a trip I will come back to June I will keep you posted.
Le sam. 29 mai 2021 à 16:00, bnjmnp @.***> a écrit :
Hi @bolp70 https://github.com/bolp70,
were you able to solve this?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/bnjmnp/pysoem/issues/33#issuecomment-850838341, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQJ7TTNTL67XQYIO6Y6DB4LTQDXPXANCNFSM44AH4ODQ .
hi bnjmnp I tried with your code, it works. As you can see I am using PDO RTx 2. It seems to me that we can use several PDOs at the same time?
map_1c13_bytes = struct.pack('BxH', 1, 0x1A00) slave.sdo_write(0x1c13, 0, map_1c13_bytes, True) to map_1c13_bytes = struct.pack('BxH', 1, 0x1A01) slave.sdo_write(0x1c13, 1, map_1c13_bytes, True)
if i do this, how does it work for class InputPdo and class OutputPdo ?
class InputPdo(ctypes.Structure):
_pack_ = 1
_fields_ = [
# PDO_0 0x1A00
#('Position_actual_value', ctypes.c_int32),
#('digital_input', ctypes.c_uint32),
#('statusword', ctypes.c_uint16),
# PDO_0 0x1A01
('Position_actual_value', ctypes.c_int32),
('velocity_actual_consigne', ctypes.c_int32),
('couple_actual_consigne', ctypes.c_int16),
('statusword', ctypes.c_uint16),
]
class OutputPdo(ctypes.Structure):
_pack_ = 1
_fields_ = [
# PDO_0 0x1600
#('Axe_target_position', ctypes.c_int32),
#('digital_output', ctypes.c_uint32),
#('controlword', ctypes.c_uint16),
# PDO_0 0x1601
('Axe_target_velocity', ctypes.c_int32),
('controlword', ctypes.c_uint16),
]
def convert_input_data(data):
return InputPdo.from_buffer_copy(data)
class BasicExample:
ZERRO_DRIVER_ID = 0x5a65726f #id du fabricant
axes = 0x00029252 #id des moteur
EL1259_PRODUCT_CODE = 0x04eb3052
def __init__(self, ifname):
self._ifname = "enp3s0"
self._pd_thread_stop_event = threading.Event()
self._ch_thread_stop_event = threading.Event()
self._actual_wkc = 0
self._master = pysoem.Master()
self._master.in_op = False
self._master.do_check_state = False
SlaveSet = namedtuple('SlaveSet', 'name product_code config_func')
self._expected_slave_layout = {0: SlaveSet('Axe1', self.axes, self.axes_setup),
1: SlaveSet('Axe2', self.axes, self.axes_setup),
2: SlaveSet('Axe3', self.axes, self.axes_setup),
3: SlaveSet('Axe4', self.axes, self.axes_setup),
4: SlaveSet('Axe5', self.axes, self.axes_setup),
5: SlaveSet('Axe6', self.axes, self.axes_setup)}
#2: SlaveSet('EL1259', self.EL1259_PRODUCT_CODE, self.axes_setup)
def axes_setup(self, slave_pos):
slave = self._master.slaves[slave_pos]
map_1c12_bytes = struct.pack('BxH', 1, 0x1601)
slave.sdo_write(0x1c12, 0, map_1c12_bytes, True)
map_1c13_bytes = struct.pack('BxH', 1, 0x1A01)
slave.sdo_write(0x1c13, 0, map_1c13_bytes, True)
thank you for your help
Hi @bolp70 ,
I'm not 100% sure what you like to do. But if you want to select 0x1A00 and 0x1A01 in 0x1C13 you need to do it this way:
map_1c13_bytes = struct.pack('BxHH', 1, 0x1A00, 0x1A01)
slave.sdo_write(0x1c13, 0, map_1c13_bytes, True)
It is just one write to 0x1c13. Note it is now 'BxHH' instead of 'BxH'.
I don't know how your ESI looks but from your input you could do something like this (for the InputPdo
):
class InputPdo(ctypes.Structure):
_pack_ = 1
_fields_ = [
# PDO_0 0x1A00
('Position_actual_value_DUMMY', ctypes.c_int32),
('digital_input', ctypes.c_uint32),
('statusword_DUMMY', ctypes.c_uint16),
# PDO_0 0x1A01
('Position_actual_value', ctypes.c_int32),
('velocity_actual_consigne', ctypes.c_int32),
('couple_actual_consigne', ctypes.c_int16),
('statusword', ctypes.c_uint16),
]
Problem here is that you have names twice, but you could give each a unique name like I did above (notice the statusword_DUMMY).
Second option would be nested "Structures".
class InputPdo0x1A00(ctypes.Structure)
_pack_ = 1
_fields_ = [
# PDO_0 0x1A00
('Position_actual_value', ctypes.c_int32),
('digital_input', ctypes.c_uint32),
('statusword', ctypes.c_uint16),
]
class InputPdo0x1A01(ctypes.Structure)
_pack_ = 1
_fields_ = [
# PDO_0 0x1A01
('Position_actual_value', ctypes.c_int32),
('velocity_actual_consigne', ctypes.c_int32),
('couple_actual_consigne', ctypes.c_int16),
('statusword', ctypes.c_uint16),
]
class InputPdo(ctypes.Structure):
_pack_ = 1
_fields_ = [
('pdo_0', InputPdo0x1A00),
('pdo_1', InputPdo0x1A01),
]
And access the elements like this:
input = InputPdo.from_buffer_copy(slave.input)
print(input.pdo_0.Position_actual_value)
print(input.pdo_1.velocity_actual_consigne)
But I did not test this.
Hi @bolp70, did you had any success with the project you were working on here? I would be happy to hear.
Closed due to inactivity of the OP.
Hi, i am using your library to communicate with a CIA 402 type engine. I can communicate with, retrieve the encoder value. But impossible to make it turn. I think we should use processdata but I don't quite understand the principle.
Do you have an example of an engine or a bit of time to help me?