How to use Arduino to control a motor?

2025-10-11 15:27:41

Using an Arduino to control motors is one of the most common and beginner-friendly projects. Arduino is often better suited for motor control than a Raspberry Pi for simple applications because it's designed for real-time I/O and can handle the electrical noise from motors more robustly.

How to use Arduino to control a motor?

Here’s a practical Arduino playbook for the most common motor types—pick yours, wire it safely, then drop in the sample code.

Power & safety (read first)

  • Do not power motors from the Arduino 5V pin. Use a separate supply sized for the motor’s stall current; tie grounds together (motor supply GND ↔ Arduino GND).

  • Arduino pins source only a few mA—they drive a driver, not the motor.

  • Add a flyback diode across DC motors/solenoids (stripe to +V) unless your driver has them built-in.

  • Keep high-current wires short; add bulk caps near drivers (e.g., 100–470 µF + 0.1 µF).


1) Brushed DC motor

A) One direction (simple, cheap): N-MOSFET + diode

Parts: Logic-level N-MOSFET (e.g., IRLZ44N/IRLZ34N/AOZ128x), 1N5819/1N4007 diode, 100 Ω gate resistor, 10 kΩ gate pulldown.

Wiring (low-side switch):

  • Motor + → external supply +

  • Motor − → MOSFET D

  • MOSFET S → GND

  • Arduino PWM pin (e.g., D9) → 100 Ω → MOSFET G; 10 kΩ G→GND

  • Diode across motor (stripe to +)

Code (speed control with PWM):

 
const int pwmPin = 9;  // PWM-capable
void setup() { pinMode(pwmPin, OUTPUT); }
void loop() {
  analogWrite(pwmPin, 200); // 0..255 (≈78% duty)
  delay(2000);
  analogWrite(pwmPin, 0);   // stop
  delay(1000);
}

(Default PWM is ~490 Hz on most pins; ~980 Hz on 5/6. Audible whine is normal at low kHz.)

B) Both directions: H-bridge (TB6612FNG/DRV8833 preferred)

Wiring (one channel): PWMA → D5, AIN1 → D7, AIN2 → D6, STBY → D8 (HIGH), motor across A01/A02, VM to motor supply, VCC to 5 V, GND common.

Code:

 

const int STBY=8, AIN1=7, AIN2=6, PWMA=5; // PWM pin
void setup(){ pinMode(STBY,OUTPUT); pinMode(AIN1,OUTPUT); pinMode(AIN2,OUTPUT); pinMode(PWMA,OUTPUT);
              digitalWrite(STBY, HIGH); }

void drive(int spd){ // spd -255..255
  if (spd >= 0) { digitalWrite(AIN1,HIGH); digitalWrite(AIN2,LOW);  analogWrite(PWMA, spd); }
  else          { digitalWrite(AIN1,LOW);  digitalWrite(AIN2,HIGH); analogWrite(PWMA, -spd); }
}
void brake(){ digitalWrite(AIN1,HIGH); digitalWrite(AIN2,HIGH); analogWrite(PWMA,0); }

void loop(){
  drive(200); delay(1500);
  brake();    delay(400);
  drive(-180);delay(1500);
  drive(0);   delay(800);
}


2) Hobby servo (SG90, MG996R, etc.)

  • Provide 5–6 V from a separate supply; connect GNDs together.

  • Signal wire goes to any digital pin (Servo library handles timing).

Code (position control):

 
#include <Servo.h>
Servo s;
void setup(){ s.attach(9); }
void loop(){
  s.write(0);   delay(800);
  s.write(90);  delay(800);
  s.write(180); delay(800);
}

3) Stepper motor

A) Bipolar stepper + A4988/DRV8825/TMC (STEP/DIR)

Basics: Set current limit (Vref), choose microstep mode (MS1–MS3), add 100–220 µF near VMOT.

Wiring: STEP → D2, DIR → D3, EN → D4 (LOW=enable). Coils to A1/A2/B1/B2, VMOT to motor supply, GND common.

Code:

 
const int STEP=2, DIR=3, EN=4;
void setup(){
  pinMode(STEP,OUTPUT); pinMode(DIR,OUTPUT); pinMode(EN,OUTPUT);
  digitalWrite(EN, LOW);
}
void stepN(long n, bool dir){
  digitalWrite(DIR, dir);
  for (long i=0;i<n;i++){
    digitalWrite(STEP, HIGH); delayMicroseconds(800);
    digitalWrite(STEP, LOW);  delayMicroseconds(800);
  }
}
void loop(){
  stepN(200, true);  delay(500);   // ≈1 rev @ 200 steps/rev (no microstepping)
  stepN(200, false); delay(500);
}

Tip: For smooth moves, use acceleration profiles (e.g., AccelStepper library).

B) 28BYJ-48 + ULN2003 (unipolar)

Use the built-in Stepper library or AccelStepper’s FULL4WIRE. Connect IN1..IN4 to four Arduino pins.


4) BLDC via ESC (RC motors/fans)

ESCs accept servo-style pulses (≈1000–2000 µs). Many need an arming sequence.

Code:

 
#include <Servo.h>
Servo esc;
void setup(){
  esc.attach(9);
  esc.writeMicroseconds(1000); // arm at min throttle
  delay(2000);
}
void loop(){
  esc.writeMicroseconds(1500); // mid throttle
  delay(2000);
  esc.writeMicroseconds(1100); // slow
  delay(2000);
}

Common pitfalls (and fixes)

  • Motor won’t spin / resets Arduino: separate motor supply, add bulk cap, confirm common ground.

  • Driver overheating: check current limit (steppers), add heatsink/airflow, ensure proper VMOT voltage.

  • Noisy sensors / random behavior: twist motor leads, keep power/logic grounds star-connected, route motor wires away from signal lines, add snubbers/ferrites if needed.

  • Servo jitter: dedicated 5–6 V rail with enough current; avoid long, thin wires.


Quick parts cheat sheet

  • DC one-way: IRLZ44N + 1N5819 + 100 Ω gate + 10 k pulldown

  • DC two-way: TB6612FNG (efficient) or DRV8833

  • Stepper: A4988/DRV8825/TMC2209 + AccelStepper

  • Servo/ESC control: Servo.h (use external 5–6 V supply)

Harendra Kumar
Harendra Kumar
Harendra Kumar holds a Ph.D. in Electrical Engineering with a specialization in power electronics. His academic expertise and years of experience allow him to break down complex concepts into clear, actionable information for his audience. Through his work, he aims to bridge the gap between advanced technology and its real-world applications. Harendra is an accomplished writer who specializes in creating high-quality, long-form technical articles on power electronics for B2B electronics platforms. His content combines deep technical knowledge with practical insights, making it a valuable resource for professionals in the electronics industry.