PWM center interval?

For my project I need to control both motors using the PWM outputs of my RC reciever.
I set everything up and it works, except the motors don’t brake when I have the stick in the middle position.

Here is my setup code:

odrv0.config.gpio3_pwm_mapping.min = -350000
odrv0.config.gpio3_pwm_mapping.max = 350000
odrv0.config.gpio3_pwm_mapping.endpoint = odrv0.axis0.controller._remote_attributes['vel_setpoint']

odrv0.config.gpio4_pwm_mapping.min = -350000
odrv0.config.gpio4_pwm_mapping.max = 350000
odrv0.config.gpio4_pwm_mapping.endpoint = odrv0.axis0.controller._remote_attributes['vel_setpoint']

The promlem I encouter is that vel_setpoint never gets 0.0, it floats always around [-1000, 1000], because my reciever doesnt produce a perfect 1500ns in middle position!

Is it possible to have an interval e.g. 1450ns-1550ns, where vel_setpoint gets set to 0.0?
Or can I do something similar to get the motors to brake at 0-position?

I don’t know if that is possible, but I think it’s possible to change the firmware to have this functionality if the current one doesn’t have it.

When I have time I will look into it and post some updates

Sounds great, thank you!

So I had time and I tried to program something. It’s untested, but I think it works. Here is what I did:

First of all, I added a new variable in the board_config that lets you set a limiter.

struct PWMMappingLimiter_t {
    float min = 0;
    float value = 0;
    float max = 0;
PWMMappingLimiter_t pwm_mappings_limiter[GPIO_COUNT];

Adding it to board_config has the effect that the values get saved by calling odrvX.save_configuration().

The pwm_mappings_limiter variable gives you the option to set a minimal and a maximal pwm boundary (in %) and a limiting value (also in %) where the received pwm value will be limited to when the original pwm value lies between the minimal and maximal boundary. The code for clarity:

 if (fraction > board_config.pwm_mappings_limiter[gpio_num - 1].min && fraction < board_config.pwm_mappings_limiter[gpio_num - 1].max)
        fraction = board_config.pwm_mappings_limiter[gpio_num - 1].value;

Where fraction is the original pwm value in percentage.
Those values are normally changed in the following commands:





So in your situation something that might work is the following:

odrvX.config.gpio3_pwm_mapping_limiter.min = 0.47
odrvX.config.gpio3_pwm_mapping_limiter.max = 0.53
odrvX.config.gpio3_pwm_mapping_limiter.value = 0.5

odrvX.config.gpio4_pwm_mapping_limiter.min = 0.47
odrvX.config.gpio4_pwm_mapping_limiter.max = 0.53
odrvX.config.gpio4_pwm_mapping_limiter.value = 0.5

If the pwm then changes in [0.47; 0.53], then the pwm value will be limited to 0.5 and as a result will set the vel_setpoint to 0.

You can see the source code here:
In ODrive/Firmware you will find two precompiled pwminterval_xxV.hex files, one for the 48V version and one for the 24V version, both ODrive V3.5.

Hopefully it works!


I finally found the time to test your code.
Thank you for the time you spent writing it!
The code works really well, its easy and fast, however I found some issues/improvements:

  1. If fraction jumps out of the limiter.min/limiter.max intervall, there is no smooth transition - the motor makes a jump to a certain speed. The effect is especially strong if you have a big limiter intervall.

  2. The limiter.value parameter schould not set the fraction, but the direct value it outputs to e.g. to vel_setpoint with odrv0.config.gpio3_pwm_mapping.endpoint = odrv0.axis0.controller._remote_attributes['vel_setpoint'], when the pwm signal is inside the limiter interval. For my example this would be zero.
    Otherwise, when you have an asymmetrical mapping.min/mapping.max interval, its hard to hit exactly 0 on the output, just by setting the fraction inbetween.

I would really appreciate it if you find the time to adjust the code!
Thank you in advance :slight_smile:

Hi, I’m having the same issue. I can’t find the pwm_mapping_limiter. Is it available only in the custom firmware? Could we have this baked into the standard firmware please? Thank you.

Most remote controls will not be able to return to exactly the middle due to mechanical tolerances as well as a whole range of reason. This function would be very helpful for an integrated odrive solution.

What I did was program a curve in the remote, so it emits “0” (or 1500, if you want), from 3% before untill 3% after the midpoint, thus creating a deadband zone. Works pretty well.

unfortunately I’m using one of the cheaper RC that isn’t programmable. So now the motor will rotate slowly whenever the RC is in the centre position.

I solved this issue with a custom firmware, where I also implemented my suggested improvements.
I am on holiday right now, but I will upload the files later this week!

thank you so much! which version of the firmware was your custom firmware based off?

Hi, my custom firmware was based of an old version, back than i did not even use git.
I recreated my edits with the newest firmware version in a new fork:

I can make you a .hex file for your ODrive version if you want.
But currently the firmware is untested, because I have some other trouble with my ODrive not calibrating (even with unmodified firmware)
I will report back when I tested the new firmware and write a little documentation on how to use the gpioN_pwm_mapping_zero feature.

EDIT: I marked all edits in the code with felhub - tracker so you can easily find what I canged.


thank you so very much. I was down the past week with a terrible sickness. A hex file would be deeply appreciated. I’m using the v3.6 24v board.

is there any Odrive admin/dev I can tag to make this a part of the official firmware? I can’t imagine why this isn’t part of it!

dear friend, could you make a firmware with the usual PWM + - or PWM + Dir? I am not a programmer, but if you can help I will be very grateful!!