🔌

Arduino Advanced

A microcontroller pin can't drive a DC motor directly — too much current and dangerous back-EMF. Learn to use an L298N H-bridge driver: set direction with IN1/IN2, control speed with PWM on ENA, read a potentiometer to vary speed, and report telemetry over Serial.

5 lessons 8 tasks
Lessons Arduino Lab Quiz Certificate

📚 Lessons

1 Why you can't drive a motor from a pin

An Arduino Uno pin can source or sink only about 40 mA — enough for an LED, but a small DC motor draws hundreds of milliamps at stall. Connecting a motor directly would instantly damage the microcontroller.

There is a second hazard: back-EMF. When the magnetic field inside a spinning motor collapses, it generates a voltage spike in the opposite direction. Without protection that spike can reach tens of volts and destroy the driver or the Arduino.

The solution is a dedicated motor driver IC. The L298N is the classic choice for teaching: it contains two full H-bridges rated for up to 2 A per channel and 46 V, with built-in protection diodes that absorb back-EMF spikes. The Arduino only controls logic pins on the L298N; the heavy current comes from a separate motor supply.

  • IN1 / IN2 — logic inputs that set the motor direction.
  • ENA — enable pin; a PWM signal here controls speed (duty cycle = fraction of maximum speed).
  • OUT1 / OUT2 — output terminals that actually connect to the motor leads.
  • 12 V — motor supply input (can be 6–46 V for the L298N; we use a 9 V battery in the simulator).
  • GNDcommon ground: must be shared between the L298N, the motor supply, and the Arduino. Without a common GND the logic voltage reference is undefined and nothing works.

2 Wiring the L298N: IN1, IN2, ENA and common GND

The circuit has three voltage domains that must share one GND rail:

  1. Arduino (5 V logic) — drives IN1, IN2, ENA with its digital/PWM pins.
  2. Motor supply (e.g. 9 V battery) — provides the current the motor needs; its (+) goes to the L298N's 12 V terminal.
  3. Motor — connected between OUT1 and OUT2; it sees whatever voltage the H-bridge switches.

Pin assignments used throughout this course:

  • Pin 7 → IN1 — direction bit A. Set HIGH for forward, LOW for reverse.
  • Pin 8 → IN2 — direction bit B. Opposite of IN1 to spin; both HIGH or both LOW = brake/coast.
  • Pin 9 → ENA — enable / speed. This is a PWM-capable pin (~9). analogWrite(9, 0..255) sets speed from 0 % to 100 %.
  • OUT1 → motor terminal A — one motor lead.
  • OUT2 → motor terminal B — the other motor lead.
  • 9 V battery (+) → L298N 12 V — motor power supply.
  • Battery (–), L298N GND, and Arduino GND — all tied together as the common GND.

The motor direction truth table: IN1=HIGH, IN2=LOW → forward; IN1=LOW, IN2=HIGH → reverse; both LOW or both HIGH → stop/brake.

// Forward at full speed for 2 s, then stop.
void setup() {
  pinMode(7, OUTPUT);   // IN1 — direction bit A
  pinMode(8, OUTPUT);   // IN2 — direction bit B
  pinMode(9, OUTPUT);   // ENA — enable / speed (PWM ~9)
}

void loop() {
  // Forward: IN1=HIGH, IN2=LOW
  digitalWrite(7, HIGH);
  digitalWrite(8, LOW);
  analogWrite(9, 200);  // ~78 % speed
  delay(2000);

  // Stop: both direction pins LOW
  digitalWrite(7, LOW);
  digitalWrite(8, LOW);
  analogWrite(9, 0);
  delay(1000);
}

3 Reversing direction

To reverse the motor, simply swap IN1 and IN2: set IN1 LOW and IN2 HIGH. The H-bridge internally reconnects OUT1 and OUT2 so current flows through the motor in the opposite direction.

Always pause briefly (or set ENA to 0) when switching direction. A hard reversal at full speed creates a large current surge and stresses both the motor and the driver. A short delay() lets the motor coast to a stop before the new direction is applied.

Truth table recap:

IN1IN2Result
HIGHLOWForward
LOWHIGHReverse
LOWLOWCoast (free-spin)
HIGHHIGHBrake (short-circuit brake)
void setup() {
  pinMode(7, OUTPUT);  // IN1
  pinMode(8, OUTPUT);  // IN2
  pinMode(9, OUTPUT);  // ENA (PWM)
}

void loop() {
  // Forward
  digitalWrite(7, HIGH);
  digitalWrite(8, LOW);
  analogWrite(9, 200);
  delay(2000);

  // Coast briefly before reversing
  analogWrite(9, 0);
  delay(300);

  // Reverse
  digitalWrite(7, LOW);
  digitalWrite(8, HIGH);
  analogWrite(9, 200);
  delay(2000);

  // Coast
  analogWrite(9, 0);
  delay(300);
}

4 PWM speed control from a potentiometer

ENA is a PWM input: the L298N enables the output for the fraction of time the pin is HIGH. analogWrite(9, 0) = motor stopped; analogWrite(9, 255) = full speed. Any value in between gives proportional speed.

A potentiometer on A0 makes the speed knob interactive:

  • Wiper (w) → A0 — the variable voltage (0–5 V).
  • Left leg (a) → 5 V — the top of the divider.
  • Right leg (b) → GND — the bottom of the divider.

analogRead(A0) returns 0–1023. map(raw, 0, 1023, 0, 255) converts it to the 0–255 PWM range. The motor direction stays forward (IN1=HIGH, IN2=LOW) while the pot adjusts the speed.

void setup() {
  pinMode(7, OUTPUT);   // IN1
  pinMode(8, OUTPUT);   // IN2
  pinMode(9, OUTPUT);   // ENA (PWM ~9)
  // Forward direction — fixed
  digitalWrite(7, HIGH);
  digitalWrite(8, LOW);
}

void loop() {
  int raw   = analogRead(A0);              // 0 – 1023
  int speed = map(raw, 0, 1023, 0, 255);  // scale to PWM
  analogWrite(9, speed);
  delay(20);
}

5 Serial telemetry — reporting speed and direction

Serial telemetry means sending data from the Arduino to a host computer (or Serial Monitor) while the program runs. It is invaluable for debugging motor control: you can watch the real speed value and confirm the direction logic is working.

Serial.begin(9600) in setup() starts the UART at 9600 baud. Then Serial.print() and Serial.println() in loop() send text. println appends a newline so each reading appears on its own line in the Serial Monitor.

A complete motor sketch with telemetry:

  1. Read the pot on A0 → raw value 0–1023.
  2. Map to PWM speed 0–255.
  3. Read a direction button on pin 2 (INPUT_PULLUP, pressed = LOW).
  4. Set IN1/IN2 accordingly and write speed to ENA.
  5. Print "speed: X dir: forward/reverse" each cycle.

The 100 ms delay keeps the Serial output readable and limits the motor update rate, which is fine for a demonstration.

void setup() {
  Serial.begin(9600);
  pinMode(2, INPUT_PULLUP); // direction button
  pinMode(7, OUTPUT);       // IN1
  pinMode(8, OUTPUT);       // IN2
  pinMode(9, OUTPUT);       // ENA (PWM)
}

void loop() {
  int raw   = analogRead(A0);
  int speed = map(raw, 0, 1023, 0, 255);

  bool forward = (digitalRead(2) == HIGH); // unpressed = forward
  digitalWrite(7, forward ? HIGH : LOW);
  digitalWrite(8, forward ? LOW  : HIGH);
  analogWrite(9, speed);

  Serial.print("speed: ");
  Serial.print(speed);
  Serial.print("  dir: ");
  Serial.println(forward ? "forward" : "reverse");
  delay(100);
}

🔌 Arduino Lab — simulated Uno R3

write a sketch, press Upload & Run, and watch the simulated board react — LEDs glow, motors spin, the serial monitor prints. Pass every challenge to earn your certificate.

Wire the L298N H-bridge to your Arduino and motor. Pin 7 → IN1 (direction A), pin 8 → IN2 (direction B), pin 9 → ENA (PWM speed). OUT1 and OUT2 drive the motor. A potentiometer on A0 (wiper) with legs to 5V and GND gives you a speed knob. All GNDs are tied together.

📝 Tasks

8 tasks across 3 pages — multiple-choice and fill-in (type the answer). Score 70% or higher to earn your certificate.

🎓 Certificate of Completion

🔒 Pass the quiz above (70%+) to unlock your downloadable certificate.