DC Motor Fundamentals: From Theory to Arduino Control
Understanding the working principles of DC motors and building your own speed-controlled project
Introduction
The beauty of DC motors lies in their elegant simplicity and controllability. Unlike their AC counterparts, DC motors offer straightforward speed control through simple voltage regulation, making them ideal for robotics, automation, and DIY projects. Whether you're building a line-following robot, a CNC machine, or an electric vehicle, understanding the working principle of DC motor technology is essential for success.
In this article, we'll dive deep into the construction, operation, and practical control of DC motors, complete with Arduino-based projects you can build today.
The Anatomy of a DC Motor
Stator (Stationary Part)
- Yoke/Frame: The outer magnetic circuit providing structural support and flux return path
- Field Windings: Electromagnetic coils that create the main magnetic field when energized
- Pole Shoes: Concentrate and direct magnetic flux toward the armature
- Armature Core: Laminated steel structure reducing eddy current losses
- Armature Conductors: Current-carrying windings embedded in armature slots
- Shaft: Transmits mechanical power to the external load
- Commutator: Cylindrical assembly of insulated copper segments acting as a rotary switch
- Brushes: Carbon contacts maintaining electrical connection with rotating commutator
- Interpoles: Auxiliary poles improving commutation and reducing sparking
Working Principle Explained
Fleming's Left-Hand Rule

- First finger: Points in the direction of the Magnetic field (N to S)
- Middle finger: Points in the direction of Current flow
- Thumb: Points in the direction of Motion/Force
The Rotation Mechanism
- Current Flow: DC current flows through armature windings via brushes and commutator
- Magnetic Field Interaction: The armature's magnetic field interacts with the stator's field
- Torque Generation: This interaction produces torque, turning the armature and shaft
- Commutation: As the armature rotates, the commutator reverses current direction in the coils
- Continuous Motion: This reversal maintains torque in one direction, enabling continuous rotation
Back EMF: The Self-Regulating Feature
- Increases proportionally with motor speed
- Naturally limits current flow
- Provides inherent speed regulation
- Protects the motor from drawing excessive current
Types of DC Motors
1. Series DC Motor
- Very high starting torque (4-5× rated torque)
- Speed varies significantly with load
- Field current = Armature current
2. Shunt DC Motor
- Excellent speed regulation
- Nearly constant speed under varying loads
- Independent control of field and armature current
3. Compound DC Motor
- Combines high starting torque with good speed regulation
- Cumulative compound: fields aid each other (most common)
- Differential compound: fields oppose each other
4. Permanent Magnet DC Motor (PMDC)
Characteristics:
- No field current required (higher efficiency)
- Compact and lightweight
- Linear speed-torque characteristics
- Simple speed control via armature voltage
Practical Project: Arduino-Based DC Motor Speed Control

Bill of Materials (BOM)
Arduino Uno/Nano | 1 | $10-15
L298N Motor Driver | 1 | $5-8
DC Motor (12V, 100-1000 RPM) | 1 | $5-10
12V Power Supply | 1 | $8-12
Potentiometer (10kΩ) | 1 | $1-2
Jumper Wires | As needed | $3-5
Breadboard | 1 | $3-5
Total Project Cost: ~$35-57
Circuit Connections
- Arduino D3 → IN1
- Arduino D9 → IN2
- Arduino D8 → ENA (PWM enable)
- Arduino GND → Driver GND
- Arduino 5V → Driver 5V (if using onboard regulator)
- OUT1 → Motor Terminal 1
- OUT2 → Motor Terminal 2
- 12V+ → Driver +12V input
- 12V GND → Driver GND
- Potentiometer VCC → Arduino 5V
- Potentiometer GND → Arduino GND
- Potentiometer Wiper → Arduino A0
Arduino Code
// Map potentiometer reading to motor speed range
// Center point (512) = stopped // 0-511 = reverse speed // 513-1023 = forward speed
if (potValue < 512) { // Reverse direction direction = -1; motorSpeed = map(potValue, 0, 511, 255, 0); digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH); } else if (potValue > 512) { // Forward direction direction = 1; motorSpeed = map(potValue, 513, 1023, 0, 255); digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); } else { // Dead zone - motor stopped motorSpeed = 0; digitalWrite(IN1, LOW); digitalWrite(IN2, LOW); } // Apply PWM speed control analogWrite(ENA, motorSpeed); // Print debug information Serial.print("Pot Value: "); Serial.print(potValue); Serial.print(" | Speed: "); Serial.print(motorSpeed); Serial.print(" | Direction: "); Serial.println(direction == 1 ? "Forward" : "Reverse"); // Small delay for stability delay(100); }
Understanding the Code
Advanced Applications
// PID constants (tune these for your motor) #define KP 2.0 #define KI 0.5 #define KD 1.0
float targetRPM = 1000; float currentRPM = 0; float error = 0; float integral = 0; float derivative = 0; float lastError = 0; int pwmOutput = 0;
void pidControl() { // Calculate error error = targetRPM - currentRPM; // PID calculations integral += error; derivative = error - lastError; // Calculate PWM output pwmOutput = (KP * error) + (KI * integral) + (KD * derivative); // Constrain output to valid range pwmOutput = constrain(pwmOutput, 0, 255); // Apply to motor analogWrite(ENA, pwmOutput); lastError = error; }
2. Current Limiting for Protection
#define CURRENT_SENSOR_PIN A1 #define MAX_CURRENT 2.0 // Amps
float readCurrent() { int sensorValue = analogRead(CURRENT_SENSOR_PIN); float voltage = sensorValue * (5.0 / 1023.0); return voltage / 0.1; // Assuming 0.1Ω shunt resistor }
void checkCurrentLimit() { float current = readCurrent(); if (current > MAX_CURRENT) { // Reduce speed or stop motor analogWrite(ENA, 0); Serial.println("OVERCURRENT - Motor stopped!"); } }
Real-World Applications
- Power windows and door locks
- Windshield wipers
- Seat adjustment mechanisms
- Cooling fans
- Electric vehicle propulsion
- Conveyor systems
- CNC machines and robotics
- Pump and fan control
- Textile manufacturing equipment
- Paper processing machinery
- Computer cooling fans
- Hard disk drive spindle motors
- DVD/Blu-ray players
- Printer mechanisms
- Electric toothbrushes
- Surgical robots
- Hospital bed adjustments
- Wheelchair mobility
- Infusion pumps
- Medical imaging systems
Troubleshooting Common Issues
- Check power supply voltage and current capacity
- Verify all connections are secure
- Test motor directly with battery
- Check for mechanical binding
- Inspect commutator for wear or damage
- Clean commutator with fine sandpaper
- Check brush spring tension
- Verify proper brush alignment
Motor Runs but Overheats
- Check for overloaded conditions
- Verify adequate ventilation
- Measure current draw vs. specifications
- Consider adding a heat sink or fan
- Check for loose connections
- Verify stable power supply
- Implement closed-loop control with encoder
- Add filtering capacitors across motor terminals
- Use Appropriate Gear Ratios: Match motor RPM to your application's torque requirements
- Implement Soft Start: Gradually ramp up speed to reduce mechanical stress
- Add Flyback Diodes: Protect electronics from back EMF spikes
- Use Quality Bearings: Reduce friction and improve efficiency
- Regular Maintenance: Clean commutator and replace worn brushes
Conclusion
Whether you're building a simple robot or a complex automation system, understanding DC motor fundamentals empowers you to select, control, and optimize these versatile machines for your specific needs. The Arduino-based project demonstrated here provides a solid foundation for more advanced applications incorporating feedback control, current limiting, and intelligent speed regulation.
As we move toward an increasingly electrified and automated world, the principles outlined in this article will remain essential knowledge for makers, engineers, and hobbyists alike.
Want to build a project?
Bring your design to life with the Elektor PCB Service, powered by Eurocircuits. Upload the project files and order professionally manufactured PCBs or assembled boards through a proven European production platform.
Supporting KiCad, Eagle, Gerber, and ODB++ formats, the service is suitable for everything from prototypes and validation builds to series production and volume manufacturing.
Made in Europe. Fast. Reliable. Professional.

Discussie (0 opmerking(en))