# Controlling brushed motor speed with variable load with a PWM

I am considering driving a brushed motor driver with an H-bridge and PWM. I'd like to roughly control the motor speed regardless of the motor's load (envision a small robot climbing/descending hills).

Since I know that if you power a brushed motor with a constant-voltage power supply, it will always rotate at about the same speed, with the current drawn reflecting the load (conversely, drive it with a constant-current power supply, and the motor speed and voltage will vary according to load).

Knowing the above, it seems simple to get feedback via an A/D to read the voltage being applied to the motor and have software tweak the PWM, to keep the voltage on the motor set according to the speed demanded.

I would need an LC in the circuit, because I would not be able to read the voltage that's got PWM noise on it.

Does the above make sense?

• Your question isn't worded correctly. So please edit it so others can search it in the future. What you're actually trying to say is that motor speed is proportional to Back EMF (BEMF). You want a way to measure the BEMF so that you can adjust the PWM so that the BEMF is kept constant, thereby maintaining a constant motor speed. But how do you do that when the BEMF is the voltage measured across the motor terminals, but you are also applying a drive voltage to the motor terminals at the same time? If the motor was coasting you could measure the BEMF, but it's not coasting. Jan 28, 2020 at 0:43
• @DKNguyen That's not what he's trying to say, but perhaps it's what he should be asking... Jan 28, 2020 at 0:47
• @BruceAbbott Heh, perhaps. Anyways, what he is literally saying is wrong and doesn't work. What he is literally saying is that he wants to turn his PWM motor driver into a voltage regulator for the motor to maintain constant speed under load, except it won't do that. It will just ensure his motor has a constant voltage applied to it as the battery voltage changes. But what I told presented is the closest real thing to his idea that will work. Jan 28, 2020 at 0:49
• BTW if you just want to compensate for supply voltage variations then measure that and adjust the PWM ratio to suit. Jan 28, 2020 at 1:31
• Yes, I am suggesting a sloppy voltage regulator. No, I was not talking BEMF. This is a real KIS project. Jan 29, 2020 at 23:50

Your idea is wrong and won't work. But there is a very similar idea that will work.

"a brushed motor with a constant-voltage power supply, it will always rotate at about the same speed" No. If you load it a lot, it will slow down a lot.

Your idea is to basically monitor the average voltage across the motor terminals and adjust the PWM so that a constant average voltage is applied to the motor in order to maintain constant speed with torque (this would also require monitoring the battery voltage as well). But this won't maintain constant speed with torque. It will just maintain an ratio between battery voltage and average voltage applied to the motor as the battery voltage decreases as it is drained. Also, if this is your goal it's easier to just to measure the battery voltage directly and adjust the PWM accordingly. No need to measure the messy voltage across motor terminals. But motor speed will still change as torque changes.

What you really want is to measure the motor's back-EMF (BEMF) and adjust the PWM to keep the BEMF constant. The BEMF is the voltage a motor generates when it is coasting. In other words, this is the voltage the motor generates when it is being back driven and acting as a generator. But now the question is, how do you measure the voltage across the motor while it is coasting coasting if you are driving it with a PWM waveform so it is not coasting?

Well, first, you do not want to continuously being sampling the motor terminal voltage in an uncontrolled manner while PWM is happening because the drive voltage (when the switches are closed and sending current through the motor) are mixed in with the BEMF voltage (when the switches are open and current is not going through the motor)

If you want to sample the BEMF while PWMing the motor you need to do the sampling when you know both HI side switches are open so that the motor isn't being driven, but you want one LO side switch to be closed so that you are measuring with respect to GND.

Your MCU may allow your PWM timer to trigger ADC samples so you can sample it directly and ignoring it when the motor current is not being forced through the motor and ignore it at all other times. Might need some RC filtering but not something like an LC.

If you can't do this, there are less elegant work arounds like having the PWM signal drive interrupts that cause the ADC to take a sample. At worst, you could directly feed the PWM signal from an output pin directly back into an interrupt pin.

• .. Since I'm using hw pwm, I could just disable it, measure the voltage, adjust the pwm when I turn the pwm back on. Even if only at 200ms rate, that likely will get me in the ballpark. Jan 30, 2020 at 0:09
• @TomCumming That would be very crude but it could work. If you have HW PWM though you are probably able to produce interrupts from it, or even trigger the ADC off of it. Jan 30, 2020 at 0:11

Since I know that if you power a brushed motor with a constant-voltage power supply, it will always rotate at about the same speed,

About the same speed, but not the same. In fact as you load the motor more its speed drops linearly, all the way to zero at stall. This is caused by the motor's internal resistances (brushes, armature windings etc.) that reduce the effective driving voltage. Any other series resistances in the circuit (eg. battery internal resistance, controller switching device and flyback diode resistances) will have a similar effect.

There are several ways you can compensate for this effect. One is to measure back-emf during the PWM 'off' period and control it in a feedback loop, as suggested by DKNguyen. A variation on this is to use an optical or Hall-effect sensor which measures speed directly.

Another way is to measure current, and increase PWM proportionally to produce a 'negative resistance' that cancels out the positive resistances in the circuit. The resistance cannot be completely cancelled because if the total goes negative the speed will become unstable, but it can greatly reduce speed variation without needing fancy back-emf measurement and a full PID loop. This method is often used in cassette tape player and turntable motors.

• How do you select your reference current and duty cycle for the negative resistance method? Jan 28, 2020 at 3:06
• When driving a brush DC motor with overly-negative resistance, motor speed actually increases when you apply a mechanical load. Very weird. I'd have thought stability would be an issue too, but it seems well-behaved. It is a type of feed-forward method vs. a feed-back method. It does work very well. Jan 28, 2020 at 3:19
• @glen_geek It depends on the load. Normally a stable operating point will be reached where the rising load rpm/torque curve crosses the falling motor rpm/torque curve, but with negative resistance the motor curve also goes up so the two curves may barely or never cross and then the operating point is unstable. But even if it is 'stable' (ie. doesn't oscillate or latch up at full speed) it is more sensitive to load variations - the opposite of what you want. To make matters worse the motor resistance itself isn't very stable. Jan 28, 2020 at 7:59
• I'm getting the drift that there's not much easier than using BEMF. Measuring the current would require a low-value resistor in series, I'd still need the LC, etc. Jan 30, 2020 at 0:00
• With BEMF, I could reduce my parts count, but triggering the adc when it's not pwm'ing is a problem. Jan 30, 2020 at 0:01

In summary, my original idea (using a crude constant-voltage power supply) will not work due to resistance in the circuit and motor.

Using BEMF could actually reduce part count (one goal that I originally should have stated), and would actually work.

Thank you DKNguyen, and Bruce Abbott for your thoughtful and thorough responses.