Summer fan: four buttons and an L293D (pins 9 and 10), on an Arduino Uno
A DC motor on an L293D with 1A on pin 10 and 2A on pin 9, and four buttons on pins 4 to 7: three speeds and off, chosen with analogWrite. The whole build, an Arduino Uno and 6 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.
Teaching? Assign it to your class in one click.
Intermediate About 20 minutes to build and run. Runs in your browser. Free, and no account needed.
The parts retail for about $35. On Mokxi they're free.
What you'll learn
- Driving a motor through an H-bridge chip
- PWM speed control with analogWrite
- Reading buttons with INPUT_PULLUP
- Looping over arrays of pins and values
- Difficulty: Intermediate
- Time: About 20 minutes
- Board: Arduino Uno R3
- Parts: 8
How it works
Four pushbuttons choose how fast a small motor spins. A pin on the Uno cannot run a motor by itself, so an L293D driver does it. Each output of the chip copies its input, with the motor's current behind it.
Pin 9 is held LOW and pin 10 gets PWM from analogWrite. With one input LOW and the other pulsed, the motor turns, and the duty sets the speed.
The buttons are on pins 4, 5, 6 and 7. Each connects its pin to ground when pressed, and the sketch uses the internal pull-ups. Pin 4 is off, 5 is slow, 6 is medium and 7 is fast.
Parts list
8 parts, plus the jumper wires. They retail for about $35; on Mokxi they're free.
- 1 × Arduino Uno R3In Starter Kit, Claw Machine Kit, Vending Machine Kit.
- 1 × Full-size breadboard
- 1 × Motor driver, L293DIn Claw Machine Kit.
- 1 × DC motor
- 4 × PushbuttonIn Starter Kit, Christmas Lights Kit, Logic Lab Kit.
Kits that can build it
These 8 starter kits have every part in the circuit. Each kit's page lists what else it can build.
Wiring table
Every connection, pin by pin, read from the circuit itself. Each row joins the pin on the left to the pin on the right, by a jumper wire or a breadboard strip.
| Part and pin | Connects to |
|---|---|
| Motor driver, L293D pin IN1 | Arduino Uno R3 pin 10 |
| Motor driver, L293D pin IN2 | Arduino Uno R3 pin 9 |
| Pushbutton (1) pin 1a | Arduino Uno R3 pin 7 |
| Pushbutton (2) pin 1a | Arduino Uno R3 pin 6 |
| Pushbutton (3) pin 1a | Arduino Uno R3 pin 5 |
| Pushbutton (4) pin 1a | Arduino Uno R3 pin 4 |
| Motor driver, L293D pin EN12 | Arduino Uno R3 pin 5V |
| Motor driver, L293D pin VS | Arduino Uno R3 pin 5V |
| Motor driver, L293D pin VSS | Arduino Uno R3 pin 5V |
| Motor driver, L293D pin GND1 | Arduino Uno R3 pin GND |
| Pushbutton (1) pin 2a | Arduino Uno R3 pin GND |
| Pushbutton (2) pin 2a | Arduino Uno R3 pin GND |
| Pushbutton (3) pin 2a | Arduino Uno R3 pin GND |
| Pushbutton (4) pin 2a | Arduino Uno R3 pin GND |
| DC motor pin 1 | Motor driver, L293D pin OUT1 |
| DC motor pin 2 | Motor driver, L293D pin OUT2 |
The code
The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.
// A summer fan: four buttons pick the speed of a motor on an L293D.
//
// L293D 1,2EN -> 5V VCC1 (16) and VCC2 (8) -> 5V GND -> GND
// L293D 1A -> pin 10 2A -> pin 9 1Y and 2Y -> the motor's two leads
// buttons on pins 4, 5, 6 and 7, each to GND (internal pull-ups)
//
// A board pin cannot run a motor, so the L293D does it: each Y output copies
// its A input, with the motor's own current behind it. One input HIGH and the
// other LOW turns the motor; both LOW stops it. analogWrite on 1A, with 2A
// held LOW, chooses how fast.
//
// Press a button: pin 4 is off, 5 slow, 6 medium and 7 fast.
const int MOTOR_1A = 10;
const int MOTOR_2A = 9;
const int BUTTONS[4] = {4, 5, 6, 7};
const int SPEEDS[4] = {0, 120, 180, 255};
const char *NAMES[4] = {"off", "slow", "medium", "fast"};
void setup() {
pinMode(MOTOR_1A, OUTPUT);
pinMode(MOTOR_2A, OUTPUT);
digitalWrite(MOTOR_2A, LOW);
for (int i = 0; i < 4; i++) pinMode(BUTTONS[i], INPUT_PULLUP);
Serial.begin(9600);
Serial.println("Mokxi Uno: fan buttons on 4 (off), 5, 6 and 7 (fast)");
}
void loop() {
for (int i = 0; i < 4; i++) {
if (digitalRead(BUTTONS[i]) == LOW) {
analogWrite(MOTOR_1A, SPEEDS[i]);
Serial.print("fan: ");
Serial.println(NAMES[i]);
delay(200);
}
}
}
Code walkthrough
The key functions of the sketch, and what each one does.
setup sketch.ino
Makes the two motor pins outputs and holds MOTOR_2A LOW so the motor can only run one way. It turns each pin in BUTTONS into an INPUT_PULLUP input, which reads HIGH until pressed. Then it opens serial at 9600 baud.
void setup() {
pinMode(MOTOR_1A, OUTPUT);
pinMode(MOTOR_2A, OUTPUT);
digitalWrite(MOTOR_2A, LOW);
for (int i = 0; i < 4; i++) pinMode(BUTTONS[i], INPUT_PULLUP);
Serial.begin(9600);
Serial.println("Mokxi Uno: fan buttons on 4 (off), 5, 6 and 7 (fast)");
}loop sketch.ino
Checks each button. A LOW reading means pressed, so it calls analogWrite on MOTOR_1A with the matching value from SPEEDS: 0, 120, 180 or 255. It prints the name and waits 200 ms. The motor keeps its speed until another button is pressed.
void loop() {
for (int i = 0; i < 4; i++) {
if (digitalRead(BUTTONS[i]) == LOW) {
analogWrite(MOTOR_1A, SPEEDS[i]);
Serial.print("fan: ");
Serial.println(NAMES[i]);
delay(200);
}
}
}Troubleshooting
The usual mistakes with this circuit, and the fix for each.
- Nothing happens when I press a button This project
Each button's other leg must go to GND. With the internal pull-up, pressing joins the pin to ground. - The motor does not turn This project
Check that the L293D enable pin (1,2EN) and both supply pins are on 5 V, and that its ground is joined to the Uno's. - The motor is weak or does not turn, and the chip gets hot. Motor driver
The L293D gives about 600 mA per channel and drops about 1.4 V per side. Use a motor that fits, and for bigger motors pick another driver. - Nothing moves even though the inputs are right. Motor driver
Power both supply pins: VCC1 (pin 16) at 5 V for logic and VCC2 (pin 8) for the motor. Tie the enable pin high, and join all grounds. - The motor does not spin, or the pin gets hot or the board resets when it is wired straight to a GPIO pin. DC motor
A pin gives about 20 mA and a motor needs far more. Drive it through a transistor or motor driver, with its own supply and a shared ground. - The transistor or pin is damaged by spikes when the motor stops. DC motor
Put a flyback diode across the motor, cathode to the positive side. A motor is a coil and kicks back voltage when switched off. Add a 0.1 uF capacitor across the motor terminals to cut noise. - The input reads random HIGH and LOW when the button is not pressed. Pushbutton
A floating pin picks up noise. Add a 10 k pull-down or pull-up resistor, or use INPUT_PULLUP and wire the button between the pin and GND. Then pressed reads LOW. - The button seems always pressed, or never changes. Pushbutton
A 4-leg tactile switch has legs joined in pairs. Place it across the breadboard center gap so the pairs sit on different rows. Wired along one side, the legs are already connected.
Change it and keep it
Open it in the editor, change the circuit or the code, and keep your version in a free account.