0 - 100% PWM Duty cycle Input help

I’m after 0-100% duty cycle PWM around 10khz frequency, I see there has been talking of this feature and had been started over a year ago but was using interrupts and only good for up to 500hz. I’m using a Kflop CNC controller from dyno motion which outputs 10khz PWM, can be adjusted lower but not recommended. Ideally, an Enable pin would be on the cards also but not important at this moment. I would also like to use this with PLCs using PWM/PTO also, so this would be a great feature to have.

I have been going through the code, but don’t understand all the structure and the use with Free RTOS etc I have pulled in the configuration of the stm32f405 into STM32 Cube MX to see the current timers used and setting on the GPIO pins. I have been reading how to use input capture on the timer channels to read PWM but have no idea where to start to add this into the Odrive code and what resources are available etc I see the step/dir can read up to 50khz so i’m sure 10khz for PWM shouldn’t be to much. If anyone is currently working on this or can point me in the right direction would be awesome.

I have just come across this

Is there any reason this has not been included or is there problems? What would be required to merge this in devel or something so some test can be done. I will add this myself and compile it and see what I run into. I would suspect this is still limited to 500hz or can the frequency be increased? Since I’m only using one axis would this leave enough to use 10khz.

Hey Matt, looks like you commented on the PR, we’re working on it :slight_smile:

1 Like

@Wetmelon yes I did and happy to do any testing etc good progress :slight_smile:

Just a quick question that I can’t quite get my head around. If the Odrive is in closed-loop velocity mode being controlled by PID to maintain the velocity and I have another closed-loop PID from CNC controller outputting PWM to the Odrive controlling velocity to maintain a position or drive to a position will this cause issues as they fight each other and can the velocity input be adjusted at such a rate? Or is there a plain open-loop velocity control mode that can be used in this type of situation?

1 Like

Or is there a plain open-loop velocity control mode that can be used in this type of situation?

I’m not sure what exactly you’re envisioning that could be, but not really :wink:

ODrive has:

  • Position control mode
  • Velocity control mode
  • Current Control mode (aka torque)

If your CNC is making velocity commands, it expects the drive to obey that speed exactly. The CNC will then close the loop on position. That should work very well. If the drive is too twitchy, you can remove the “D” component of the CNC’s PID (which is velocity gain). Optionally, you can also remove the I component of the CNC PID, which would put you right back at the equivalent of ODrive’s control structure, which is a P - PI - PI cascade.

1 Like

Thanks for clearing that up @Wetmelon so it basically comes down to tuning both PID loops to work well with each other. The Kflop CNC controller I use does not use D but PI as does the Odrive. I have used cheap BLDC speed controllers that were okay at higher speeds but hopeless at slow speeds and could not maintain motion profile exactly because they had ramp up and deceleration times that could not be adjusted to 0, they were just plain open loop with PWM input. Once the PWM input is implemented and working I will do some bench testing with the CNC controller and report back with my findings if anyone else is interested in doing something similar.

1 Like

Oh, yeah, those ramp rates are a pain in the ass. We used a crappy brushless DC controller for a controls project in school and most of the non-linearity was the cheap ESC. ODrive doesn’t have that problem :wink:

1 Like

That’s what exactly got my attention and the FOC control for lower speeds. I did some mucking around with a VESC and FOC until there drv8302 chip stuffed out to find out the have hardware fault with FOC on there 4.12 hardware. Odrive is way more feature rich for these types of applications, the only good thing about the VESC was the GUI tool which speed setup and testing a lot. I think it would be awesome to have a version of Odrive up to 600V so industrial servo motors can also be utilized ( even though it defeats the purpose of the Odrive ) Just gives so many opportunities for larger motors and retro fitting old machines etc.

I have been working on my own hardware version which is single axis and has 24vdc boost converter, dual channel optocouplers which can be set as input or output. Jumpers for selecting encoder or hals with correct filtering and bypassing. Once I have it all working correctly I will put up for anyone interested ( there are a few issues with capacitor location for the DRV8301 ) I can put it up if you are interested yourself, it’s done with KiCad.

Oh, man. I just came back after many months to see if the Odrive is useable for me yet and apparently not.

I have the industry standards:

PWM + direction but @ 19.2KHz
Anti-phase PWM where 50% duty cycle = zero command but also @ 19.2KHz
+/-10v analog

It sure would be nice for a version of Odrive that was a drive and not a motion controller.



@Tinine I have got PWM working using my branch here. It’s only set up for a single-axis as I have designed my own hardware for Industrial use. Unfortunately, I don’t think 20khz would work, I’m wanting to use 10khz. I have been doing some testing with 1khz and 2.5khz and it is working. Here is a link to my branch and also JPWheels branch

Here are the commands I used to get it working, remember to reboot and put into closed loop

PWM 0-100% Control
1: odrv0.config.gpio3_pwm_mapping.pwm_type = 1 // Set PWM to 0-100% | RC PWM Input = 0
2: odrv0.config.gpio3_pwm_mapping.min = 0
3: odrv0.config.gpio3_pwm_mapping.max = 500000
4: odrv0.config.gpio3_pwm_mapping.endpoint = odrv0.axis0.controller._remote_attributes[‘input_vel’]
5: odrv0.config.gpio3_pwm_mapping.gpio_direction_pin = 4
6: odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL
7: odrv0.config.gpio3_pwm_mapping.endpoint = None // Only use to Disable PWM control
8: odrv0.save_configuration()
9: odrv0.reboot()

1 Like

Hi @Matt303,
I’m hoping to interface my Odrive to a PWM+Dir controller and this appears to be my best hope at the moment, other than creating an Arduino interface board to translate from PWM+Dir to RC PWM. Which I may do in the short term but isn’t a long term solution.

My controller has PWM frequency settings from 4 to 20KHz, is that likely to be OK with your firmware?

Being a total noob to ODrive firmware development I’ve spent a few hours trying to set up and IDE on my PC and to be hones I’m totally lost, most of the instructions either don’t make sense to me (thats my fault) or result in errors in the IDE terminal.

As a last resort, is there a precompiled firmware available for a v3.6 56v Odirve? If not do you know of a good YouTube tutorial for noobs on how to get setup, and to compile an Odrive firmware?

Any thoughts would be much appreciated.

All the Best
Barry M

Driving PM motors/generators in open loop is VERY inefficient. Basically you inject some current and “cross your fingers” for the rotor to spin. A lot of current is “wasted” energy in Id because there is no information about the electrical angle of the shaft being fed back to the drive. Moreover you need to apply a lot of current in order to guarantee that the rotor is going to follow the rotating field.

I think that this is what happens when the drive is trying to calibrate the sensors. It generates a rotating field and observe that the encoder is spinning, but there is no feedback on the velocity control. This also happens when the drives is searching for the Z pulse of an encoder. Some drive are running I/f until they find the Z pulse then switch to closed loop mode.

This kind of open loop control is acceptable when running asynchronous motors with a constant load, or with the understanding that the motor speed is going to vary with the load, but I have never seen one asynchronous motor running on 48V. This is probably why the odrive team isn’t really working on a open loop control mode.

You have the wrong understanding of what is trying to be achieved here, we are talking about inputting a PWM frequency into the GPIO pins in order to control the velocity of the motor. ( some older CNC controllers used PWM and closed the loop at the CNC controller ) In my case, I’m using Dynomotion Kflop CNC controller and that’s also reading the same encoder signal from the motor the Odrive is using for commutation

1 Like

Sorry I don’t have a precompiled version for the v3.6 56v. I think best option is for you to fork the original version and my version from GitHub and compare them and make the changes needed for the PWM only ( note there are other changes just for my hardware )

There is a few tutorials on how to setup IDE for the Odrive on YouTube and also in the Odrive Documentation. If you are going down this track I would recommend getting an ST-Link V2 for programming the microcontroller directly incase you brick it with bad code etc through DFU and also you can use the ST-Link for live debugging.

The other major difference is my hardware uses one axis and I have disabled the second in code and microcontroller configuration to allow more resources for the PWM. I have used it up to 10khz, I had no need to go above that.

1 Like

Thank you very much for your work, but could you please give us the actual firmware in HEX or BIN file for Odrive 3.6 56v?
I can’t build your firmware VS code keeps getting an error.