Getting a DC Motor to Run at Different Speeds

The most common way to Control Speed Of Dc Motor is pulse width modulation. You switch the voltage on and off rapidly and the motor averages it out. A 50% duty cycle means roughly half the rated speed, assuming the motor has enough torque to keep moving during the off periods. It sounds simple and it mostly is, but there are enough gotchas that people waste days debugging something that should have taken an afternoon. You need a microcontroller, a MOSFET or an H-bridge driver, and a power supply that can handle the motor's current draw. Connect the motor between the driver outputs and drive the enable pin with a PWM signal from your controller. Frequency matters more than people admit. Too low and the motor stutters and runs hot. Too high and your MOSFET spends more time in the linear region switching, which generates heat and wastes power. I usually run between 15 and 25 kHz for small to medium motors. That keeps things quiet and efficient without stressing the switch. The duty cycle controls average voltage, but it doesn't control speed directly. Speed depends on the load too. A stepper or a fan will respond differently than a conveyor belt motor under heavy load. I learned this the hard way when I was building a CNC spindle controller and assumed 60% PWM would give me a consistent RPM across all cutting loads. It didn't. The spindle slowed down under load because the average voltage dropped below what was needed to overcome the mechanical resistance. Adding a closed-loop PID controller with an encoder fixed it, but that was after I'd already torn apart three different driver boards trying to figure out why the speed was inconsistent.

Voltage Variation as a Simpler Alternative

If you don't need precise speed regulation and the motor doesn't draw much current, you can just vary the supply voltage with a potentiometer or a linear regulator. This works fine for small fans and toy motors. It won't work for anything that needs to maintain speed under varying load because the motor's back EMF changes with speed and there's nothing correcting for it. Linear regulators also dump excess power as heat, which means a 12V motor running at 6V through a linear regulator is burning half your power. Switching regulators solve that problem but add cost and complexity. Most of the time you also need to reverse the motor, which means an H-bridge. The L298N is popular but it's a beast of a component with high saturation voltage. You lose almost 2 volts across it, which matters a lot at low voltages. I switched to the TB6612FNG or better yet discrete MOSFETs on a custom board. The discrete approach gives you far better efficiency and less heat. The L298N is fine for prototyping when you don't know what you're doing yet. That's not an insult, it's just practical. Buy the module, learn how everything connects, then move to something better when you actually need the performance. One thing nobody warns you about with H-bridges is shoot-through. If both high and low side MOSFETs on the same leg turn on even briefly during switching, you create a direct short from supply to ground. Good driver ICs handle this with built-in dead time. If you're building your own discrete H-bridge, you need to add dead time in your firmware or use a driver IC like the DRV8833 that manages this internally. I once fried two MOSFETs in a project because I was toggling the GPIO pins directly without any dead time. Took about three milliseconds of scope time to see the overlap, and another hour to source replacements.

Encoder Feedback and Closed Loop Control

Open loop PWM speed control is fine for applications where speed variation isn't critical. If you need consistent RPM regardless of load, you need an encoder. Incremental encoders are cheap and give you enough resolution for most hobby and light industrial work. Mount it on the motor shaft or the output shaft depending on whether you have gearing. Read the pulses with your microcontroller's timer input capture and calculate speed from the pulse frequency. Then run a PID loop. The proportional term reacts to current error, the integral term eliminates steady state error, and the derivative term dampens oscillations. Tuning this is where people struggle. Start with P only and increase until you get some response. Add D to smooth out the response. Add I last and in small increments because integral windup will make your motor hunt for speed. I usually tune by watching the response on an oscilloscope rather than guessing. Setpoint step tests show you exactly what's happening. A well-tuned encoder loop on a 12V motor with a DRV8833 driver and a 100 CPR encoder holds speed within about 2% across a wide load range. That's good enough for most applications.

Get the Full Details

Electrical Revolution: Speed Control of DC Motor by Solid State Devices
Electrical Revolution: Speed Control of DC Motor by Solid State Devices

When PWM and Encoders Aren't Enough

For high power applications above about 50 watts, or where you need very precise speed control over a wide range, you should look at dedicated motor controller ICs or even BLDC controllers if you're willing to swap the motor type. Brushed DC motors are simple but they have limits. The brushes wear out, sparking creates EMI, and commutation isn't smooth. If your application runs continuously or needs long life, a brushless motor with an ESC might actually be cheaper in the long run even though the initial complexity is higher. Another limitation of DC motor speed control that people forget is thermal management. The motor itself heats up under load and resistance increases with temperature. That means your speed will drift as the motor warms up even with perfect PID control if your duty cycle ceiling is too low. I had a project where a DC motor controlling a camera pan axis would drift after about ten minutes of continuous operation. The solution wasn't better code, it was reducing the gear ratio so the motor ran cooler and had more headroom. Sometimes the hardware fix is simpler than chasing the software.

Practical Wiring Notes

Keep your motor power lines separate from your logic supply. A single point ground is fine for small setups but larger motors will inject noise into your MCU through the ground path. Use a capacitor across the motor terminals, something like 100nF ceramic in parallel with 10uF electrolytic, to suppress the brush noise. Without it your ADC readings will be garbage and your encoder counts will jump randomly. I also add a freewheeling diode across the motor if your driver doesn't have built-in flyback protection. Most modern driver ICs include it but cheap modules sometimes skip it to save a few cents. If you're sourcing components, check the datasheets for switching frequency ranges and current ratings at your actual operating voltage. Manufacturers test at ideal conditions and real boards run hotter. Derate everything by about 20% and you'll have a system that doesn't fail after a few weeks of operation.