I have three ODrive 3.6’s linked together in a CAN bus and haven’t been able to get any movement out of the motors through the bus. All ODrives work as expected through USB, and I’ve set the IDs of all axes to be unique (0 – 5). There is a 120 ohm resistor on both ends of the bus.
I’m using this USB-to-CAN adapter, set to the “slcan” mode. The following code works to print the heartbeat of all connected ODrives:
import can
bus = can.interface.Bus(interface='slcan', channel='COM12', bitrate=250000)
# Listen for 10 messages
for _ in range(10):
msg = bus.recv()
print(f"Received message: {msg}")
bus.shutdown()
And I can use the dbc database to decode the messages:
import can
import cantools
db = cantools.database.load_file("ODrive_CAN.dbc")
bus = can.interface.Bus(interface='slcan', channel='COM12', bitrate=250000)
# Listen for 10 messages
for _ in range(10):
msg = bus.recv()
print(f"Received message: {msg}")
decoded_msg = db.decode_message(msg.arbitration_id, msg.data)
print(f"Decoded message: {decoded_msg}")
print()
bus.shutdown()
But whenever I try to send anything to the ODrives, nothing happens… Here’s an example of what I’ve been trying:
import can
import cantools
db = cantools.database.load_file("ODrive_CAN.dbc")
bus = can.interface.Bus(interface='slcan', channel='COM12', bitrate=250000)
axisID = 0x5 # I have tried all values from 0x0 to 0x9 to no avail
print("\nRequesting AXIS_STATE_FULL_CALIBRATION_SEQUENCE (0x03) on axisID: " + str(axisID))
msg = db.get_message_by_name('Axis5_Set_Axis_State')
data = msg.encode({'Axis_Requested_State': 0x03})
msg = can.Message(arbitration_id=msg.frame_id | axisID << 5, is_extended_id=False, data=data)
# msg = can.Message(arbitration_id=axisID << 5 | 0x07, data=[3, 0, 0, 0, 0, 0, 0, 0], dlc=8, is_extended_id=False) # Neither of these have worked
print(db.decode_message('Axis5_Set_Axis_State', msg.data))
print(msg)
try:
bus.send(msg)
print("Message sent on {}".format(bus.channel_info))
except can.CanError:
print("Message NOT sent! Please verify can0 is working first")
print("Waiting for calibration to finish...")
bus.shutdown()
I have been able to get correct data back from the ODrives (via. the heartbeat messages) such as current state (I change it with USB, then check it with CAN), position, etc. but it seems like nothing I send is being received. At least, nothing physical is indicating reception of my messages.
I have tried everything I can think of from both the can_example and can_dbc_example examples (as well as the docs), but nothing has worked.
I am very new to CAN and I’ve tried to include all relevant information; I apologise if anything is missing.
Does anyone have any ideas of what I could try to move forward?
Thanks in advance!