Introduction: 4 Servo Motors Controlled With a Toggle Switch

For a personal project, I needed four servo motors to react to a simple toggle switch. Nothing fancy, just a clean on/off trigger that brings the motors to life. In this tutorial, I’ll show you how I wired everything together using an Arduino Uno, and how you can adapt the same setup for your own installation or experiment.

Supplies

  1. Arduino Uno (or compatible clone)
  2. Breadboard
  3. MB102 Breadboard Power Supply Module (3.3V / 5V)
  4. 4× MS24 20kg High-Torque Servo Motors
  5. Toggle Switch (I’m using the Gardner Bender brand)
  6. Jumper Wires
  7. Soldering Iron
  8. Tape or Heat-Shrink Tubing

Note:

I chose 20kg high-torque servos because I planned to enclose the motors in metal junction boxes, which require more resistance than typical micro servos. That said, this setup and wiring will work with most standard servos, as long as your power supply can meet their requirements.

Shopping Links:

  1. MS24 20kg Servo Motors on Amazon
  2. Arduino Starter Kit
  3. Gardner Bender Toggle Switch

Step 1: Switch Wiring

To get started, you’ll need to connect the toggle switch to your Arduino and breadboard. This usually means extending the two switch terminals with jumper wires—unless you’re using a solderable breadboard.

In this project, the toggle switch is the main input that controls the servo motors. It provides a simple, reliable ON/OFF signal for the Arduino:

  1. Switch OFF → The circuit is open. The input pin is not connected to ground, so the Arduino reads HIGH (thanks to the internal pull-up resistor). The servos stay still.
  2. Switch ON → The circuit is closed. The input pin is connected to GND, so the Arduino reads LOW, triggering the servo movement sequence you programmed.

In short, the toggle switch becomes a physical controller that turns your servo choreography ON and OFF.

Tips for wiring:

  1. During prototyping, you can strip the end of a jumper wire, twist it around the switch terminal, and secure it with tape. Quick and easy for testing.
  2. For a more permanent setup, solder the wires to the switch terminals and cover the joint with heat-shrink tubing for durability.

Step 2: The Electric Circuit

WIRE IT UP!

In this setup, one wire of the toggle switch (it doesn’t matter which) is connected to a digital input pin on the Arduino, and the other wire goes to ground (GND). Essentially, you’re turning a physical action of flipping the switch into an electrical signal the Arduino can read.

Wiring:

  1. One terminal → GND on the Arduino (or breadboard)
  2. Other terminal → Digital input pin (e.g., pin 2)

With the pin set to INPUT_PULLUP in the code, you don’t need any extra resistors—the switch simply pulls the pin to ground when flipped.

For this project, I’m using the 5V external power supply that came with my Arduino starter kit. It’s strong enough to handle the pre-programmed motion of the servos.

Power considerations:

  1. If you plan to add more than 4–6 servos, or
  2. Use high-torque servos in continuous motion (more than 3 at once),

…then it’s a good idea to upgrade to a larger power supply. High-torque servos perform more reliably when powered closer to their rated voltage range.

Once your circuit is working consistently on the breadboard, you can move everything to a solderable board for a more permanent and stable setup.

Step 3: Arduino Code

For the code, I decided to make a simple choreography of the servos. The sequance is programmed and activated when switched on. The servos should stop moving when the toggle is off.

You can copy and paste the code below into the Arduino IDE and upload it to your board. Make sure your servos are connected to pins 5, 9, 10 and 11, and one of the toggle switch wires is on pin 2 whereas the other in the negative lane of the breadboard.


#include <Servo.h>


// ----------------- SERVOS -----------------

Servo servo9; // pin 9

Servo servo11; // pin 11

Servo servo5; // pin 5

Servo servo10; // pin 10


// ----------------- SWITCH -----------------

const int switchPin = 2;

int lastSwitchState = HIGH;

int switchState = HIGH;

unsigned long lastDebounceTime = 0;

const unsigned long debounceDelay = 30;


// Sequence control

bool sequenceRunning = false;


// ----------------- SETTINGS -----------------

const int stepDelayMin = 15; // ms per step (high-torque safe)

const int stepDelayMax = 35;

const int stepSize = 2; // degrees per step


void setup() {

Serial.begin(9600);

pinMode(switchPin, INPUT_PULLUP);


// Attach servos

servo9.attach(9);

servo11.attach(11);

servo5.attach(5);

servo10.attach(10);


stopAllServos();

Serial.println("High-torque choreography ready");

}


void loop() {

readSwitch();


if (switchState == HIGH) {

stopAllServos();

sequenceRunning = false;

return;

}


if (!sequenceRunning) {

sequenceRunning = true;

runChoreography();

}

}


// ----------------- CHOREOGRAPHY FUNCTION -----------------

void runChoreography() {

// --- Basic domino forward ---

runServo(servo9, 50, 230, random(1,2));

runServo(servo11, 30, 150, random(1,2));

runServo(servo5, 70, 220, random(1,2));

runServo(servo10, 40, 180, random(1,2));


// --- Random unexpected motions ---

if (random(0, 2)) runServo(servo11, 60, 140, random(1,2)); // skip or repeat

if (random(0, 2)) runServo(servo5, 80, 200, random(1,2));


// --- “Conversation”: first and last move together ---

runTwoServos(servo9, servo10, 60, 200, random(1,2));


// --- “Conversation”: middle two move together ---

runTwoServos(servo11, servo5, 40, 180, random(1,2));


// --- Reverse domino (back to start) ---

runServo(servo10, 40, 180, random(1,2));

runServo(servo5, 70, 220, random(1,2));

runServo(servo11, 30, 150, random(1,2));

runServo(servo9, 50, 230, random(1,2));


sequenceRunning = false;

}


// ----------------- SINGLE SERVO ACTION -----------------

void runServo(Servo &servo, int startAngle, int endAngle, int repeats) {

for (int r = 0; r < repeats; r++) {

for (int pos = startAngle; pos <= endAngle; pos += stepSize) {

servo.write(pos);

delay(random(stepDelayMin, stepDelayMax));

readSwitch();

if (switchState == HIGH) return;

}

for (int pos = endAngle; pos >= startAngle; pos -= stepSize) {

servo.write(pos);

delay(random(stepDelayMin, stepDelayMax));

readSwitch();

if (switchState == HIGH) return;

}

}

}


// ----------------- TWO SERVOS TOGETHER -----------------

void runTwoServos(Servo &s1, Servo &s2, int startAngle, int endAngle, int repeats) {

for (int r = 0; r < repeats; r++) {

for (int pos = startAngle; pos <= endAngle; pos += stepSize) {

s1.write(pos);

s2.write(pos);

delay(random(stepDelayMin, stepDelayMax));

readSwitch();

if (switchState == HIGH) return;

}

for (int pos = endAngle; pos >= startAngle; pos -= stepSize) {

s1.write(pos);

s2.write(pos);

delay(random(stepDelayMin, stepDelayMax));

readSwitch();

if (switchState == HIGH) return;

}

}

}


// ----------------- HELPERS -----------------

void stopAllServos() {

servo9.write(90);

servo11.write(90);

servo5.write(90);

servo10.write(90);

}


// Debounced switch read

void readSwitch() {

int reading = digitalRead(switchPin);


if (reading != lastSwitchState) lastDebounceTime = millis();


if (millis() - lastDebounceTime > debounceDelay) switchState = reading;


lastSwitchState = reading;

}