Pass CAN-bus data to UART

I have a setup where I will share the torque between multiple ODrives (10 actually…). The master will run in position mode and get posision commands from a canbus network. The slaves cannot be on the canbus network, so I thought I could use the UART to pass the torque of the master to the slaves using the normal ASCII-protocol. In order to connect 10 ODrives in parallel I will convert the UART to RS485.

Is there an easy way to directly pass a string to the UART interface? I’ve been looking into the code but I get lost all the time…

Why can’t they be on CAN bus? :thinking:

Well, to be honest they are connected to the CANbus where they are sending replies, not the commands. The reason for this is that I sometimes need 2 (and more) masters for position/velocity control (XY-table), and some number of slaves to each master for load sharing. If I could utilize the UART I could make the system general, where a dip switch selects if the drive is master/slave. If master, the torque is sent to the uart, regardless of how many connected slaves.

So there is an arbirtrary number of UART busses where the torque is shared, and always just one canbus where the master gets its setpoint and all drives share the torque, vel, pos etc.

I work in a laboratory where we never have fixed setup. The ODrives and canbus setup is changed all the time, they are just picked from a shelf and placed where needed without any modification to the code.

1 Like

There is no reason why both masters can’t send the position update command. They might get collisions (because it’s the same message ID). That may or may not affect you (since CAN automatically retries on error) if it does cause problems, you could change the protocol slightly, and make them listen for updates on more than one node-ID. The first “master” sends the messages as the first ID, and the second sends as the other.
So you make the IDs unique by addressing the master nodes instead of the slaves.
CAN has no concept of master/slave. Only functionally-unique message IDs.

I suppose you’d want the DIP switch to put a drive into position mode and make it send out a torque setpoint command to the others? And in the other position, it’s in torque mode and listens as normal for torque commands.

I cannot do that, because with this setup the master has a specific range of IDs (and ODrive units) to pass the torque to. I need the ODrive system to be generic, where each drive can be master (the one who gets the position command) and pass its torque to which ever “slave” drive we use without thinking about which ID the slave reads from. By separating the torque sharing to multiple UART busses, we achieve a generic setup where noone belongs to noone.

What i need is to send a custom UART buffer from my CAN object. I will of course send the commands in the ODrive ASCII format, so i dont have to do anything on the receiver side. Ex: “c 0 10”

So it wouldn’t be sufficient that when in position mode (i.e. configured as “master”), you send a torque command as a special ID that all drives respond to if they are in torque mode? Then the DIP switch just selects master (position mode) or slave (torque mode)?

Because you have different groups of master/slave drives?
You could have another set of switches for group ID?

Yes, that’s why.

Anyway, I finally figured it out. I took me a “couple” of iterations and compile errors.

// Include headers needed for uart
#include <usart.h>
#include "interface_uart.h"
.. [my CAN Open code] ..
// Pass 'c' number of uint8_t to UART
uart4_stream_output_ptr->process_bytes(uart_buffer, c, nullptr);

With this I successfully write the buffer to the UART port, tested by reading with a Teensy and passing the data to the serial monitor.

I will keep it like this for now, but if there is a better way please let me know!