PWM input and incremental move (how to implement?)

I need to make a system that gets the input from RC PWM (actually an Arduino and Servo library) and then control the motor in position control but incrementally.
The only documentation I found about PWM control is the following three lines:

 odrv1.config.gpio4_pwm_mapping.min = -10
odrv1.config.gpio4_pwm_mapping.max = 10
odrv1.config.gpio4_pwm_mapping.endpoint = odrv1.axis0.controller._remote_attributes['input_pos']

This works well for position control, velocity control as well as torque control. I’m sure it would work for incremental position control also but I can’t figure out the python command, mostly because of the lack of documentation (and my python skill).

The command for incremental move is
odrv0.axis0.controller.move_incremental(float, bool)
where the float is the move amount.

How do I join these two together?
If I did
odrv0.axis0.controller.move_incremental(float(odrv1.config.gpio4_pwm_mapping.endpoint), False)
it did not work (TypeError: float() argument must be a string or a number).

I think “odrv1.config.gpio4_pwm_mapping.endpoint” is not a variable at all, but what is it and how do I use it??

Hi Mihkel,

Using move_incremental as a PWM endpoint is not supported. The endpoints are internal references to variables in the ODrive firmware, but move_incremental() is a function call.

You could add this functionality, but there is probably a better way. If you want to send incremental position commands from an Arduino (not an RC transmitter), why not use UART from the Arduino or even Step/direction?

Thanks for reply.
Step/dir is incremental in its native form so that should be simple exept when you need to increment from current location not target. I think it does not even make any sense to step it from current location if you think about it (current location in constantly changing). So that is not an option really.

The Arduino used to control brushed DC with its own PID, what I’m doing is an upgrade to BLDC.
So what I also tried is to continue using the PID inside the Arduino and just output PWM for torque control. Unfortunately this gave very unstable results. Not sure why but it might be that the communication creates delay that is sufficient to send the motor flying. Do you think this is something that has been proven to work and I just need to look at my code or it has been troublesome for others as well?

What might be wrong with using external PID, PWM and torque control?
How would you use incremental move with uart?

It makes sense that there would be some instability wrapping a PID around RC PWM torque control. The nominal update rate for RC PWM is just 50Hz! You can probably tune the PID to handle it, but performance will be reduced.

The incremental move function is not supported over UART, but you can send position, velocity, and torque commands over UART. See this page for details: ASCII Protocol | ODrive. You could also setup an analog input on ODrive for velocity or torque control and use normal PWM (analogWrite() in arduino) + an RC lowpass filter. This would be much than RC PWM velocity or torque control.

Was the previous setup using a PID and outputting relative incremental position commands to the motor? Velocity control should be equivalent to that.

1 Like

As I got my setup running I’m summing up this thread, in case someone has similar issues. External PID works just fine. Eventually I ran it through UART (Arduino Odrive library) using torque control, it had better results than PWM. But my problem was actually that the Arduino (Mega) was getting too many interrupts from the encoder, I had to reduce the encoder count to 48 counts per turn to achieve my needed speed of 4250 RPM.