ODrive Documentation

High performance motor control

View the Project on GitHub madcowswe/ODrive

Help improve these docs: submit edits using the link in the top right.

If you need help, please search or ask the ODrive Community.

Getting Started

Table of contents

Hardware Requirements

You will need:

Wiring up the ODrive

Make sure you have a good mechanical connection between the encoder and the motor, slip can cause disasterous oscillations or runaway.

All non-power I/O is 3.3V output and 5V tolerant on input, on ODrive v3.3 and newer.

  1. Wire up the motor phases into the 3-phase screw terminals, and the power resistor to the AUX terminal. Wire up the power source to the DC terminal, make sure to pay attention to the polarity. Do not apply power just yet.

  2. Wire up the encoder(s) to J4. The A,B phases are required, and the Z (index pulse) is optional. The A,B and Z lines have 3.3k pull up resistors, for use with open-drain encoder outputs. For single ended push-pull signals with weak drive current (<4mA), you may want to desolder the pull-ups.

Image of ODrive all hooked up

Downloading and Installing Tools

Most instructions in this guide refer to a utility called odrivetool, so you should install that first.


  1. Install Python 3. We recommend the Anaconda distribution because it packs a lot of useful scientific tools, however you can also install the standalone python.
    • Anaconda: Download the installer from here. Execute the downloaded file and follow the instructions.
    • Standalone Python: Download the installer from here. Execute the downloaded file and follow the instructions.
    • If you have Python 2 installed alongside Python 3, replace pip by C:\Users\YOUR_USERNAME\AppData\Local\Programs\Python\Python36-32\Scripts\pip. If you have trouble with this step then refer to this walkthrough.
  2. Launch the command prompt.
    • Anaconda: In the start menu, type Anaconda Prompt Enter
    • Standalone Python: In the start menu, type cmd Enter
  3. Install the ODrive tools by typing pip install odrive Enter
  4. Plug in a USB cable into the microUSB connector on ODrive, and connect it to your PC.
  5. Use the Zadig utility to set ODrive driver to libusb-win32.
    • Check ‘List All Devices’ from the options menu, and select ‘ODrive 3.x Native Interface (Interface 2)’. With that selected in the device list choose ‘libusb-win32’ from the target driver list and then press the large ‘install driver’ button.


We are going to run the following commands for installation in Terminal.

  1. If you don’t already have it, install homebrew:
    /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  2. Install python:
    brew install python
  3. If you get the error: Error: python 2.7.14_2 is already installed, then upgrade to Python 3 by running:
    brew upgrade python
  4. The odrive tools uses libusb to communicate to the ODrive:
    brew install libusb
  5. Now that you have Python 3 and all the package managers, run:
    pip3 install odrive


  1. Permission Errors: Just run the previous command in sudo
    sudo pip3 install odrive
  2. Dependency Errors: If the installer doesn’t complete and you get a dependency error (Ex. “No module…” or “module_name not found”)
    sudo pip3 install module_name

    Try step 5 again


  1. Install Python 3.
  2. Install the ODrive tools by opening a terminal and typing pip install odrive Enter
  3. Linux: set up USB permissions
     echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="0d[0-9][0-9]", MODE="0666"' | sudo tee /etc/udev/rules.d/50-odrive.rules
     sudo udevadm control --reload-rules
     sudo udevadm trigger # until you reboot you may need to do this everytime you reset the ODrive

Start odrivetool

ODrive v3.5 and later: Your board should come preflashed with firmware. If you run into problems, follow the instructions here on the DFU procedure before you continue.
ODrive v3.4 and earlier: Your board does not come preflashed with any firmware. Follow the instructions here on the STP Link procedure before you continue.

To launch the main interactive ODrive tool, type odrivetool Enter. Connect your ODrive and wait for the tool to find it. Now you can for instance type odrv0.vbus_voltage Enter to inpect the boards main supply voltage. It should look something like this:

ODrive control utility v0.4.0
Please connect your ODrive.
Type help() for help.

Connected to ODrive 306A396A3235 as odrv0
In [1]: odrv0.vbus_voltage
Out[1]: 11.97055721282959

The tool you’re looking at is a fully capable Python command prompt, so you can type any valid python code.

You can read more about the odrivetool here.

Configure M0

Read this section carefully, else you risk breaking something.
There is a separate guide specifically for hoverboard motors.

1. Set the limits:

Wait, how do I set these?

In the previous step we started odrivetool. In there, you can assign variables directly by name.

For instance, to set the current limit of M0 to 10A you would type: odrv0.axis0.motor.config.current_lim = 10 Enter

2. Set other hardware parameters:

3. Save configuration.

You can save all .config parameters to persistent memory such that the ODrive remembers them between power cycles.

Position control of M0

Let’s get motor 0 up and running. The procedure for motor 1 is exactly the same, so feel free to replace read “axis1” wherever it says “axis0”.

  1. Type odrv0.axis0.requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE Enter. After about 2 seconds should hear a beep. Then the motor will turn slowly in one direction for a few seconds, then back in the other direction.
What’s the point of this?

This procedure first measures your motor’s electrical properties (namely phase resistance and phase inductance) and then the offset between the motor’s electrical phase and the encoder position.

The startup procedure is demonstrated here.

Note: the rotor must be allowed to rotate without any biased load during startup. That means mass and weak friction loads are fine, but gravity or spring loads are not okay. Also note that in the video, the motors spin after initalisation, but in the current software the default behaviour is not like that.

Help, something isn’t working!

Check the encoder wiring and that the encoder is firmly connected to the motor. Check the value of hex(odrv0.axis0.error) and then refer to the error code documentation for details.

Once you have understood the error and fixed its cause, you may clear the error state (odrv0.axis0.error = 0 Enter) and retry. You may also need to clear the error state of other subcomponents (e.g. odrv0.axis0.motor.error).

  1. Type odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL Enter. From now on the ODrive will try to hold the motor’s position. If you try to turn it by hand, it will fight you gently. That is unless you bump up odrv0.axis0.motor.config.current_lim, in which case it will fight you more fiercely.
  2. Send the motor a new position setpoint. odrv0.axis0.controller.pos_setpoint = 10000 Enter. The units are in encoder counts.

Other control modes

The ODrive also supports velocity control and current (torque) control.

What’s next?

You can now:

If you have any issues or any questions please get in touch. The ODrive Community warmly welcomes you.