Open TudorMorosanu opened 1 year ago
I have also tried lowering my baud rate in a desperate attempt to make things work but with no success
You should look at the info collected by the operating system regarding the SocketCAN network device. From the top of my head, something like this:
ip -details -statistics link show can0
Look out for the error counts. On my Pi setup, I had to increase the txqueuelen
(sometimes shown as qlen
) parameter from 10 to something like 1000.
Are you using the same USB adapter from Peak or some other CAN adapter / shield on the Pi?
I am using the same Peak device for both the laptop and the Raspberry. The output of the command says that there are 0 errors. However, on RX there are about 2000-3000 dropped (packages, I assume). I have tried setting up a bigger txqueuelen, but this did not seem to work(I made sure to make it execute on boot, so it is always 10000). I have managed to make the motors execute their tasks correctly over 20 times, then when I run the program again I get the SDO response errror message. Yesterday I have thought that the problem had been solved after I used the setup_402_state_machine() method, since everything worked smoothly after that. Today however, when I powered up the devices and ran the exact same code as yesterday I got the same error. I am not sure what might be causing it since it seems to happen in any given circumstance, I haven't been able to identify a pattern or something to help me locate the source of the problem, I am putting my code here(only the part that uses SDO messages, since this is where I get all my errors)
import canopen
from canopen.profiles.p402 import BaseNode402
import time
def setup_node(target_node, mode_of_op):
# time.sleep(0.01)
target_node.nmt.state = 'PRE-OPERATIONAL'
# time.sleep(0.01)
target_node.sdo[0x6060].raw = mode_of_op
# time.sleep(0.01)
target_node.sdo['ControlWord'].raw = 6
# time.sleep(0.01)
target_node.sdo['ControlWord'].raw = 7
# time.sleep(0.01)
target_node.sdo['ControlWord'].raw = 15
# time.sleep(0.01)
def setup_indexes(target_node):
target_node.nmt.state = 'PRE-OPERATIONAL'
# time.sleep(0.01)
target_node.sdo[0x1600][0].raw = 4
# time.sleep(0.1)
target_node.sdo[0x1601][0].raw = 4
# time.sleep(0.1)
target_node.sdo[0x1602][0].raw = 4
# time.sleep(0.1)
target_node.sdo[0x1603][0].raw = 4
# time.sleep(0.1)
target_node.sdo[0x1A00][0].raw = 4
# time.sleep(0.1)
target_node.sdo[0x1A01][0].raw = 4
# time.sleep(0.1)
target_node.sdo[0x1A02][0].raw = 4
# time.sleep(0.1)
target_node.sdo[0x1A03][0].raw = 4
# target_node.nmt.state = 'OPERATIONAL'
def setup_device_pos(target_node):
# time.sleep(0.01)
target_node.nmt.state = 'PRE-OPERATIONAL'
# time.sleep(0.01)
# target_node.sdo[0x1600][0].raw = 4
# # time.sleep(0.1)
# target_node.sdo[0x1601][0].raw = 4
# # time.sleep(0.1)
# target_node.sdo[0x1602][0].raw = 4
# # time.sleep(0.1)
# target_node.sdo[0x1603][0].raw = 4
# # time.sleep(0.1)
#
# target_node.sdo[0x1A00][0].raw = 4
# # time.sleep(0.1)
# target_node.sdo[0x1A01][0].raw = 4
# # time.sleep(0.1)
# target_node.sdo[0x1A02][0].raw = 4
# # time.sleep(0.1)
# target_node.sdo[0x1A03][0].raw = 4
# time.sleep(0.1)
target_node.tpdo.read()
# time.sleep(0.1)
target_node.rpdo.read()
# time.sleep(0.1)
target_node.tpdo[1].clear()
# time.sleep(0.1)
target_node.tpdo[2].clear()
target_node.tpdo[3].clear()
# time.sleep(0.1)
target_node.rpdo[1].clear()
target_node.rpdo[2].clear()
# time.sleep(0.1)
target_node.rpdo[3].clear()
# time.sleep(0.1)
target_node.rpdo[1].add_variable('ControlWord')
target_node.rpdo[1].add_variable('Mode of operation')
target_node.rpdo[2].add_variable('target position')
# time.sleep(0.1)
target_node.rpdo[2].add_variable('Profile velocity')
# time.sleep(0.1)
target_node.rpdo[3].add_variable('Profile acceleration')
# time.sleep(0.1)
target_node.rpdo[3].add_variable('Profile deceleration')
# time.sleep(0.1)
target_node.tpdo[1].add_variable('StatusWord')
target_node.tpdo[1].add_variable('Mode of operation display')
# target_node.tpdo[1].add_callback(print_sw)
print(target_node.tpdo_values)
target_node.rpdo[1].event_timer = 0
# time.sleep(0.1)
target_node.rpdo[1].trans_type = 1
# time.sleep(0.1)
target_node.rpdo[2].event_timer = 0
# time.sleep(0.1)
target_node.rpdo[2].trans_type = 1
# time.sleep(0.1)
target_node.rpdo[3].event_timer = 0
# time.sleep(0.1)
target_node.rpdo[3].trans_type = 1
# time.sleep(0.1)
target_node.tpdo[1].event_timer = 0
target_node.tpdo[1].trans_type = 1
target_node.rpdo[2].enabled = True
# time.sleep(0.1)
target_node.rpdo[3].enabled = True
time.sleep(0.1)
time.sleep(0.1)
target_node.rpdo.save()
target_node.tpdo.save()
target_node.nmt.state = `'OPERATIONAL'`
def set_position(target_node, pos, BT):
# target_node.nmt.state = 'OPERATIONAL'
# target_node.sdo[0x6060].raw = 1
# time.sleep(0.01)
target_node.rpdo[1]['ControlWord'].raw = 15
target_node.rpdo[1]['Mode of operation'].raw = 1
target_node.rpdo[1].transmit()
target_node.rpdo[2]['target position'].raw = pos
target_node.rpdo[2]['Profile velocity'].raw = 4000
target_node.rpdo[3]['Profile acceleration'].raw = 155
target_node.rpdo[3]['Profile deceleration'].raw = 155
target_node.rpdo[1]['ControlWord'].raw = BT
target_node.rpdo[2].transmit()
target_node.rpdo[3].transmit()
target_node.rpdo[1].transmit()
# target_node.sdo['ControlWord'].raw = 31
# target_node.sdo.wait_for_reception(0.1)
# time.sleep(0.01)
# target_node.rpdo[1].start(0.1)
# target_node.rpdo[2].start(0.1)
# target_node.rpdo[3].start(0.1)
# time.sleep(0.1)
def set_velocity(target_node, velocity, BT):
time.sleep(0.01)
target_node.rpdo[2]['Target velocity'].raw = velocity
target_node.rpdo[3]['Profile acceleration'].raw = 255
target_node.rpdo[3]['Profile deceleration'].raw = 255
target_node.rpdo[1]['ControlWord'].raw = BT
target_node.rpdo[2].transmit()
target_node.rpdo[3].transmit()
target_node.rpdo[1].transmit()
STATE1 = 1063
STATE2 = 4135
STATE3 = 5159
if __name__ == '__main__':
node = BaseNode402(1, '/opt/eds_lichuan.eds')
node2 = BaseNode402(2, '/opt/eds_lichuan.eds')
node3 = BaseNode402(3, '/opt/eds_lichuan.eds')
network = canopen.Network()
# network.sync.stop()
network.add_node(node)
network.add_node(node2)
network.add_node(node3)
network.connect(channel='can0', bustype='socketcan', bitrate=1000000)
network.check()
network.sync.start(0.005)
setup_node(node, 1)
time.sleep(0.01)
setup_node(node2, 1)
time.sleep(0.01)
setup_node(node3, 1)
time.sleep(0.01)
setup_indexes(node)
setup_indexes(node2)
setup_indexes(node3)
node.setup_402_state_machine()
node2.setup_402_state_machine()
node3.setup_402_state_machine()
setup_device_pos(node)
setup_device_pos(node2)
setup_device_pos(node3)
So I've been trying to move some motors using canopen and I have managed to implement everything almost flawlessly when working from my laptop. However, I had to move the control to a RaspberryPi 4, and there I cannot complete setting up the nodes, since I get
Transfer aborted by client with code 0x05040000 Exception in thread Thread-3: Traceback (most recent call last): File "/home/pi/.virtualenvs/pythonProject/lib/python3.7/site-packages/canopen/sdo/client.py", line 67, in read_response block=True, timeout=self.RESPONSE_TIMEOUT) File "/usr/lib/python3.7/queue.py", line 178, in get raise Empty _queue.Empty
During handling of the above exception, another exception occurred:
Traceback (most recent call last): File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner self.run() File "/usr/lib/python3.7/threading.py", line 865, in run self._target(*self._args, **self._kwargs) File "/home/pi/PycharmProjects/python server/CANopen_module.py", line 256, in CANmove setup_node(node, 1) File "/home/pi/PycharmProjects/python server/CANopen_module.py", line 19, in setup_node target_node.sdo['ControlWord'].raw = 15 File "/home/pi/.virtualenvs/pythonProject/lib/python3.7/site-packages/canopen/variable.py", line 89, in raw self.data = self.od.encode_raw(value) File "/home/pi/.virtualenvs/pythonProject/lib/python3.7/site-packages/canopen/variable.py", line 41, in data self.set_data(data) File "/home/pi/.virtualenvs/pythonProject/lib/python3.7/site-packages/canopen/sdo/base.py", line 132, in set_data self.sdo_node.download(self.od.index, self.od.subindex, data, force_segment) File "/home/pi/.virtualenvs/pythonProject/lib/python3.7/site-packages/canopen/sdo/client.py", line 161, in download fp.close() File "/home/pi/.virtualenvs/pythonProject/lib/python3.7/site-packages/canopen/sdo/client.py", line 389, in write response = self.sdo_client.request_response(request) File "/home/pi/.virtualenvs/pythonProject/lib/python3.7/site-packages/canopen/sdo/client.py", line 85, in request_response return self.read_response() File "/home/pi/.virtualenvs/pythonProject/lib/python3.7/site-packages/canopen/sdo/client.py", line 69, in read_response raise SdoCommunicationError("No SDO response received") canopen.sdo.exceptions.SdoCommunicationError: No SDO response received
The curious thing is that I've managed to run the code successfully on the RPi4 about 3 or 4 times. After that, without changing anything I started getting this error on different lines almost every time and I cannot understand what is happening. Please help! The code is exactly the same as the one I used on the laptop. I am using a PEAK IPEH-002021 as my CAN module.