The ODrive can be controlled over various ports and protocols. If you’re comfortable with embedded systems development, you can also run custom code directly on the ODrive. For that refer to the developer documentation.
|GPIO1||UART TX||Axis0 Step||Analog input, PWM input|
|GPIO2||UART RX||Axis0 Dir||Analog input, PWM input|
|GPIO3||Axis1 Step (+)||Analog input, PWM input|
|GPIO4||Axis1 Dir (+)||Analog input, PWM input|
|GPIO5||Analog input (*)|
|GPIO7 (*)||Axis1 Step (*)|
|GPIO8 (*)||Axis1 Dir (*)|
(+) on ODrive v3.4 and earlier
(*) ODrive v3.5 and later
For predictable results, try to have only one feature enabled for any one pin. When changing pin assignments you must:
When the encoder mode is set to hall feedback, the pinout on the encoder port is as follows:
|Label on ODrive||Hall feedback|
This protocol is what the ODrive Tool uses to talk to the ODrive. If you have a choice, this is the recommended protocol for all applications. The native protocol runs on USB and can also be configured to run on UART.
The ODrive Tool you installed as part of the Getting Started guide comes with a library that you can use to easily control the ODrive from Python.
Assuming you already installed the odrive library (
pip install odrive), the simplest program to control the ODrive is this:
import odrive odrv0 = odrive.find_any() print(str(odrv0.vbus_voltage))
For a more comprehensive example, see tools/odrive_demo.py.
We don’t have an official library for you just yet. Check the community, there might be someone working on it. If you want to write a library yourself, refer to the native protocol specification. You are of course welcome to contribute it back.
This is a simpler alternative to the native protocol if you don’t need all its bells and whistles. Before you use this, be sure that you’re ok with its limitations. The ASCII protocol is enabled by default on UART and can also be enabled on USB alongside with the native protocol.
For more details, see the ASCII protocol specification.
There is an Arduino library that gives some expamples on how to use the ASCII protocol to communicate with the ODrive. Check it out here.
This is the simplest possible way of controlling the ODrive. It is also the most primitive and fragile one. So don’t use it unless you must interoperate with other hardware that you don’t control.
To enable step/dir mode for the GPIO, set
<axis>.config.enable_step_dir to true for each axis that you wish to use this on.
Axis 0 step/dir pins conflicts with UART, and the UART takes priority. So to be able to use step/dir on Axis 0, you must also set
odrv0.config.enable_uart = False. See the pin function priorities for more detail. Don’t forget to save configuration and reboot.
There is also a config variable called
<axis>.config.counts_per_step, which specifies how many encoder counts a “step” corresponds to. It can be any floating point value.
The maximum step rate is pending tests, but it should handle at least 50kHz. If you want to test it, please be aware that the failure mode on too high step rates is expected to be that the motors shuts down and coasts.
Please be aware that there is no enable line right now, and the step/direction interface is enabled by default, and remains active as long as the ODrive is in position control mode. To get the ODrive to go into position control mode at bootup, see how to configure the startup procedure.
You can control the ODrive directly from an hobby RC receiver.
Some GPIO pins can be used for PWM input, if they are not allocated to other functions. For example, you must disable the UART to use GPIO 1,2. See the pin function priorities for more detail.
Any of the numerical parameters that are writable from the ODrive Tool can be hooked up to a PWM input. As an example, we’ll configure GPIO4 to control the angle of axis 0. We want the axis to move within a range of -1500 to 1500 encoder counts.
odrv0.axis0.controller.pos_setpoint. If you need help with this follow the getting started guide.
In : odrv0.config.gpio4_pwm_mapping.min = -1500 In : odrv0.config.gpio4_pwm_mapping.max = 1500 In : odrv0.config.gpio4_pwm_mapping.endpoint = odrv0.axis0.controller._remote_attributes['pos_setpoint']
Note: you can disable the input by setting
odrv0.config.gpio4_pwm_mapping.endpoint = None
In : odrv0.save_configuration() In : odrv0.reboot()
Be sure to setup the Failsafe feature on your RC Receiver so that if connection is lost between the remote and the receiver, the receiver outputs 0 for the velocity setpoint of both axes (or whatever is safest for your configuration). Also note that if the receiver turns off (loss of power, etc) or if the signal from the receiver to the ODrive is lost (wire comes unplugged, etc), the ODrive will continue the last commanded velocity setpoint. There is currently no timeout function in the ODrive for PWM inputs.
Note: when you use an existing library you don’t have to deal with the specifics described in this section.
This section assumes that you are familiar with the general USB architecture, in particular with terms like “configuration”, “interface” and “endpoint”.
On USB the ODrive provides a single configuration which is a composite device consisting of a CDC device (virtual COM port) and a vendor specific device.
A composite device is a device where interfaces are grouped by interface association descriptors. For such devices, the host OS loads an intermediate driver, so that each of the interface groups can be treated like a separate device and have its own host-side driver attached.
On the ODrive, the following interface groups are present:
0x82: CDC commands
0x01: CDC data OUT
0x81: CDC data IN
0x03: data OUT
0x83: data IN
The endpoint pairs
0x01, 0x81 and
0x03, 0x83 behave exactly identical, only their descriptors (interface class, …) are different.
If you plan to access the USB endpoints directly it is recommended that you use interface 2. The other interfaces (the ones associated with the CDC device) are usually claimed by the CDC driver of the host OS, so their endpoints cannot be used without first detaching the CDC driver.
Baud rate: 115200 Pinout: