How to use FSOdrive base on Odrive 3.14 ?

  • Pre-words
  • Set up tools
  • Tools calibration
  • Programming operation
    • Motor set up
    • PPM set up
  • FSOdrive collection diagram



This ’s example to show you how to do programming for FSOdrive in Windows PC,  seek more operation instruction of IOS and Linux from here:

Set up tools:

If you’re first time to use Odrive or FSOdrive, need to do following preparation work:

-Set up programming tool , you need to download Anaconda

-Download a driver:

After you set up above two items in you PC, lets’ go to next step.

Search Anaconda Prompt in the start menu in your PC and open it, and type  pip install odrive in Anaconda Prompt and start to install the debugging tool after returning.

Power on the FSODrive , there should be a connection response on the PC, then open Zadig, click List All Devices in the option, find ODrive 3.4 Native Interface (Interface2), make sure the driver is libusb-win32, if not, click the button below (Replace Driver) to change to libusb-win32.

Then go back to Anaconda Prompt , type odrivetool , if the connection is successful, then it will show an Odrive serial no.

Odrive is connected successfully

Now let’s move to the main programming process:

Motor set up

We’re going to set up motor 0 firstly, then set up motor 1

1. Check how many magnetic poles that your motors are, then type the no. Eg. 7 pairs poles motor that we used ,so we input below code.

odrv0.axis0.motor.config.pole_pairs = 7

2. Set up the motors max calibration voltage 

odrv0.axis0.motor.config.resistance_calib_max_voltage = 4

3.Set up the max stall current  

 odrv0.axis0.motor.config.requested_current_range = 25

4. Save your setting


5. Reboot  (After each time reboot, it will notes: Reconnected to Odrive xxxxxx(serial no)as odrv0)


everytime after reboot, it will look like this. 

6. Set the encoder to hall mode (instead of incremental).Due to the example motor hall cable has 6 status and 7 pair of magnet poles, so the CRP = 6 * 7 = 42

odrv0.axis0.encoder.config.mode = ENCODER_MODE_HALL

odrv0.axis0.encoder.config.cpr = 42

7. Set the encoder bandwidth, usually big bigger than the CRP.

odrv0.axis0.encoder.config.bandwidth = 100

8. Set the current control bandwidth. This value is the same with the encoder bandwidth value.

odrv0.axis0.motor.config.current_control_bandwidth = 100

9. Due to set up by velocity mode, so set the position control value as 0

odrv0.axis0.controller.config.pos_gain = 0

10. Set up the P and I of PID , it’s tuned by different motor effect.

odrv0.axis0.controller.config.vel_gain = 0.02

odrv0.axis0.controller.config.vel_integrator_gain = 0.1

11. Set up the max limitation of velocity, unit is count/s

odrv0.axis0.controller.config.vel_limit = 1000

12. Set up the velocity for control mode.

odrv0.axis0.controller.config.control_mode = CTRL_MODE_VELOCITY_CONTROL

13. Save all , and reboot.



14. Activate the motors , input following order, it will sound “Bi”,if no such sound, then resetting all your code.

odrv0.axis0.requested_state = AXIS_STATE_MOTOR_CALIBRATION

15. Read the motor data. If the data error shows 0x0000, then indicates the motor detection is ok.


16. Input following order to save the detection result.

odrv0.axis0.motor.config.pre_calibrated = True

17.Input following order to test the hall sensor , the motor will spin towards, and then spin backwards. After calibration , dont do any change ,just save it.

odrv0.axis0.requested_state = AXIS_STATE_ENCODER_OFFSET_CALIBRATION

18.After test, then you can check the encoder status by input this order. If the error value is 0x0000,then the test is ok


19. Input this order to save the check result. 

odrv0.axis0.encoder.config.pre_calibrated = True

20. After setting up the motor 1, just input order to save setting and reboot it. Then we finish the setting for Motor1

odrv0.axis1.motor.config.pole_pairs = 7

odrv0.axis1.motor.config.resistance_calib_max_voltage = 4

odrv0.axis1.motor.config.requested_current_range = 25



// (don't copy it , the order nees time to run reboot process)

odrv0.axis1.encoder.config.mode = ENCODER_MODE_HALL

odrv0.axis1.encoder.config.cpr = 42

odrv0.axis1.encoder.config.bandwidth = 100

odrv0.axis1.motor.config.current_control_bandwidth = 100

odrv0.axis1.controller.config.pos_gain = 0

odrv0.axis1.controller.config.vel_gain = 0.02

odrv0.axis1.controller.config.vel_integrator_gain = 0.1

odrv0.axis1.controller.config.vel_limit = 1000

odrv0.axis1.controller.config.control_mode = CTRL_MODE_VELOCITY_CONTROL



// (don't copy // , the order nees time to run reboot process)

odrv0.axis1.requested_state = AXIS_STATE_MOTOR_CALIBRATION




odrv0.axis1.motor.config.pre_calibrated = True

odrv0.axis1.requested_state = AXIS_STATE_ENCODER_OFFSET_CALIBRATION




odrv0.axis1.encoder.config.pre_calibrated = True




PWM set up:

Now we’ve finished Motor setting, If you want to control by PWM, then refer to following table, while I use GPIO4 to control motor 0,use GPIO3 to control motor 1.

1. Set up the output mini and max value for GPIO4

odrv0.config.gpio4_pwm_mapping.min = -200

odrv0.config.gpio4_pwm_mapping.max = 200

2. Use GPI04 mapping to control motor 0

odrv0.config.gpio4_pwm_mapping.endpoint = odrv0.axis0.controller._remote_attributes['vel_setpoint']

3. Set up the output mini and max value for GPIO3

odrv0.config.gpio3_pwm_mapping.min = -200

odrv0.config.gpio3_pwm_mapping.max = 200

4. Use GPI03 mapping to control motor 0

odrv0.config.gpio3_pwm_mapping.endpoint = odrv0.axis1.controller._remote_attributes['vel_setpoint']

5. Save and reboot



6. Input order odrv0.axis1.controller.vel_setpoint  to check the throttle location, you can adjust the throttle location by tuning the value of mapping.max and mapping.min , after it gets in the best effect, then you can use it.

7. Set motor0 as closed loop control, after set up, you can test by remote 

odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL



8. Set motor1 as closed loop control,after set up, you can test by remote 

odrv0.axis1.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL



9. Set the motor close loop control after start up

odrv0.axis0.config.startup_closed_loop_control = True

odrv0.axis1.config.startup_closed_loop_control = True



10. Push the throttle, if the two motors run in opposite direction, then exchange the max value and mini value in any one of GPIO 4 or GPIO3.

 Eg.  exchanged the max value from 200 to -200, exchanged the min value from -200 to 200

odrv0.config.gpio4_pwm_mapping.min = 200

odrv0.config.gpio4_pwm_mapping.max = -200



11.  When the throttle in the middle location, if the motor is still spinning, then change I of PID value to 0

odrv0.axis0.controller.config.vel_integrator_gain = 0

odrv0.axis1.controller.config.vel_integrator_gain = 0



12. If you want to improve to higher ERPM, then improve the GPIO mapping value. Eg, change the motor 0 ERPM to 800

odrv0.config.gpio4_pwm_mapping.min = 800

odrv0.config.gpio4_pwm_mapping.max = -800




FSOdrive connection diagram:

FSOdrive Cable connection diagram

Leave a comment