I am trying to control the velocity of an ATV320-motor with CANopen. I have come up with the following piece of code:
import canopen
import logging
import time
import threading
logging.basicConfig(level=logging.CRITICAL)
network = canopen.Network()
network.connect(bustype='pcan', channel='PCAN_USBBUS1', bitrate=125_000)
ATV = 'atv'
keep_reading = True
keep_posting = True
current_vel_value = 0
target_vel_value = 1000
nodes = {}
atv_node = canopen.BaseNode402(32, 'ATV320_eds/SEATV320_010305E.eds')
nodes[ATV] = network.add_node(atv_node)
def process_tpdo_1():
global current_vel_value
while keep_reading:
atv_node.tpdo[1].wait_for_reception()
current_vel_value = atv_node.tpdo[1][1].phys
print("\tTPDO[1][1].phys:" + str(current_vel_value))
def process_rpdo_1():
global target_vel_value
while target_vel_value > 600:
print(f"Setting velocity to {target_vel_value}")
atv_node.rpdo[1][1].phys = target_vel_value
network.sync.transmit()
target_vel_value -= 100
time.sleep(1)
atv_node.rpdo[1].stop()
tpdo_1_thread = threading.Thread(target=process_tpdo_1, args=())
rpdo_1_thread = threading.Thread(target=process_rpdo_1, args=())
print("SETTING NMT TO OPERATIONAL")
atv_node.nmt.state = 'OPERATIONAL'
print("SETTING NODE STATE TO 'SWITCHED ON'")
atv_node.state = 'SWITCHED ON'
atv_node.rpdo.read()
atv_node.tpdo.read()
tpdo_1_thread.start()
atv_node.rpdo[1][1].phys = target_vel_value
atv_node.trans_type = 1
atv_node.rpdo[1].start(100)
atv_node.state = 'OPERATION ENABLED'
tolerance = 10
while current_vel_value < target_vel_value - tolerance:
time.sleep(0.2)
rpdo_1_thread.start()
rpdo_1_thread.join()
try:
atv_node.state = 'SWITCHED ON'
except RuntimeError as e:
print(e)
while current_vel_value > 0:
time.sleep(0.2)
keep_reading = False
The code itself works as intended. The Motor starts ramping to the expected target velocity. But when my rpdo_1_thread
starts applying the new values, the motor does not change its control effort and i do not understand why. Here is the relevant part of the output when setting the logger to DEBUG
:
DEBUG:canopen.variable:Value of Control Effort (0x6044:0) is 1000
TPDO[1][1].phys:1000
DEBUG:canopen.variable:Writing Target Velocity (0x6042:0) = 600
DEBUG:canopen.pdo.base:Updating Target Velocity to b'5802' in RxPDO1_node32
DEBUG:can.pcan:Data: bytearray(b'')
DEBUG:can.pcan:Type: <class 'bytearray'>
Setting velocity to 600
DEBUG:canopen.variable:Value of Control Effort (0x6044:0) is 1000
TPDO[1][1].phys:1000
DEBUG:canopen.variable:Writing Target Velocity (0x6042:0) = 500
DEBUG:canopen.pdo.base:Updating Target Velocity to b'f401' in RxPDO1_node32
DEBUG:can.pcan:Data: bytearray(b'')
DEBUG:can.pcan:Type: <class 'bytearray'>
Setting velocity to 500
DEBUG:canopen.variable:Value of Control Effort (0x6044:0) is 1000
I tried rpdo[1].transmit()
, which sends the correct velocity on the bus, but the motors power state changes to SWITCH_ON_DISABLED
(the motor switches to freewheel stop). Then, i have to enable the motor again by sending OPERATION_ENABLED
. Yet i want to continuously update values instead of stopping the motor for every update.
Any help is greatly appreciated.