robotics

Control Two Servos With One Channel: Wiring And Code

When you're building a compact robotic system, running out of control channels or microcontroller pins happens faster than you think. Whether you're working with an RC receiver, an Arduino, or a custo

Control Two Servos With One Channel: Wiring And Code
In this story

When you're building a compact robotic system, running out of control channels or microcontroller pins happens faster than you think. Whether you're working with an RC receiver, an Arduino, or a custom embedded board, figuring out how to drive multiple actuators without adding extra control lines is a common design hurdle. If you need to command two distinct servo motors using just a single signal source, you don't always have to upgrade your entire hardware setup.

You can accomplish this through a few reliable engineering approaches, ranging from simple parallel wiring with signal inversion to microcontroller-based decoding. The right method depends entirely on whether you want your servos to mirror each other, move in opposite directions, or respond conditionally based on pulse-width thresholds. Let's break down how to achieve precise multi-servo control from a single data stream without running into power brownouts or signal conflicts.

Understanding Servo Signals and Channel Constraints

Before splitting or processing a control line, it's vital to look at how standard hobby servos interpret commands. Standard Pulse Position Modulation (PPM) or Pulse Width Modulation (PWM) for servos relies on a periodic pulse train—typically running at a 50 Hz frequency (a 20-millisecond frame).

  • Neutral Position: A 1.5-millisecond active-high pulse places a standard servo at its 90-degree center.
  • Endpoints: A 1.0-millisecond pulse drives the horn to 0 degrees, while a 2.0-millisecond pulse drives it to 180 degrees.

A standard receiver channel or microcontroller pin broadcasts this exact repeating pulse sequence to whatever is plugged into it. If you plug two servos directly into that single line using a standard Y-harness, both devices receive the exact same pulse width simultaneously. They will move in identical fashion. If your mechanical design requires independent movement, mirroring, or differential motion, you have to intercept, invert, or decode that signal.

For foundational documentation on microcontroller pulse generation and timer limits, consult the Arduino Hardware Reference. If you're building radio-controlled models, review the Model Aviation Resource Guide for standard transmitter channel mapping practices.

Method 1: Parallel Y-Harness and Signal Inversion for Mirror Motion

The easiest way to utilize a single channel for two servos is when you want dual actuation—such as dual elevator flaps on an aircraft, dual steering linkages, or synchronized bay doors.

If you connect both servos via a parallel Y-lead, they share the signal wire. However, mechanical layouts often require the two motors to turn in opposite directions. If you mount two identical servos facing each other, a single signal will make them fight each other mechanically rather than work together.

To solve this without adding a second control channel, use a PWM signal reverser inline with one of the servos. A tiny electronic signal inverter reads the incoming pulse width (for example, subtracting the pulse duration from a 3.0 ms baseline) so that when one servo receives a 2.0 ms pulse (full right), the inverted servo receives a 1.0 ms pulse (full left). Alternatively, you can use specialized servos from different manufacturers that naturally rotate in opposite directions given the same control input.

Method 2: Microcontroller-Based Channel Decoding

If you're using a microcontroller like an Arduino or an ESP32, a single incoming digital pin can be programmed to decode a stream and distribute different commands to two separate output pins. This is where you achieve true functional differentiation from one input source.

Instead of passing the raw PWM straight through, your microcontroller reads the pulse width of the incoming channel using functions like pulseIn() or an external interrupt pin. You then map that single input range into two separate output behaviors.

Practical Code Implementation

The following Arduino sketch demonstrates how to read a single input channel and split its behavior. When the incoming signal is below a specific threshold, it drives Servo A. When it crosses that threshold, it drives Servo B, or scales the output proportionally for independent responses.

#include <Servo.h>

const int inputPin = 2;   // Single incoming signal channel
const int servo1Pin = 9;  // Output to first servo
const int servo2Pin = 10; // Output to second servo

Servo servo1;
Servo servo2;

void setup() {
  pinMode(inputPin, INPUT);
  servo1.attach(servo1Pin);
  servo2.attach(servo2Pin);
}

void loop() {
  // Read the pulse width from the single channel (in microseconds)
  int pulseWidth = pulseIn(inputPin, HIGH, 25000);
  
  if (pulseWidth > 900 && pulseWidth < 2100) {
    // Example logic: split control based on stick position
    if (pulseWidth < 1500) {
      // Lower half of travel controls servo 1, centers servo 2
      int val1 = map(pulseWidth, 1000, 1500, 0, 180);
      servo1.write(val1);
      servo2.write(90); 
    } else {
      // Upper half of travel controls servo 2, holds servo 1
      int val2 = map(pulseWidth, 1500, 2000, 0, 180);
      servo1.write(180);
      servo2.write(val2);
    }
  }
  
  delay(15); // Refresh rate pacing
}

This approach allows you to multiplex a single control source. You can program sequential actions, threshold switching, or differential scaling entirely through software logic without hardware modifications.

Avoiding Power Brownouts and Current Bottlenecks

The most common failure point when running multiple actuators off limited lines isn't the data signal—it's power delivery. Each standard hobby servo can draw between 200 mA and 500 mA under normal load, and over 1 A when stalled.

🔗 Read more: this article

If you hook two servos up to a single receiver line or a microcontroller board and power them through the board's onboard 5V regulator, the voltage will sag instantly. This causes microcontroller resets, erratic jitter, and complete system lockups.

  • Use an External Power Supply: Always power your servos from a dedicated external battery pack or a robust 5V switching regulator rated for at least 2A to 3A.
  • Establish a Common Ground: Ensure the ground wire from your external power supply is firmly connected to the ground pin of your microcontroller or receiver. Without a shared ground reference, the data pulses become unreadable noise.
  • Isolate Signal Lines: Only share the signal line or split the data channel. Never route high-current motor power through logic pins.

Common Mistakes to Avoid

When implementing single-channel multi-servo setups, watch out for these frequent pitfalls:

  • Ignoring Signal Impedance: Tying too many servo signal lines together in parallel can load down weak receiver outputs, degrading the square-wave voltage levels and causing packet loss. Keep parallel splits to a maximum of two servos unless you use a buffer chip.
  • Mismatched Protocol Speeds: Standard analog servos operate at 50 Hz, but digital servos can handle much higher update frequencies. If you mix them behind a shared decoder or custom splitter, ensure your refresh rates don't exceed the tolerance of the slower analog motor.
  • Overlooking Mechanical Binding: When using inverted servos or Y-harnesses for physical linkages, always test the range of motion slowly by hand before applying full power. Hitting mechanical limits under power strips gears instantly.

Frequently Asked Questions

Can I run two different brands of servos off a single Y-harness?

Yes, provided they operate on the standard 50 Hz PWM protocol and require the same voltage. However, keep in mind that different manufacturers sometimes use slightly different internal pulse-to-angle scaling, meaning one servo might travel further than the other for the exact same input signal.

Why do my servos twitch violently when I move them together?

Jitter is almost always a symptom of insufficient current or a missing common ground. When two servos demand startup current simultaneously, the voltage drops below the operating threshold of the receiver or microcontroller, causing it to reboot continuously. Switch to an independent power supply.

Do I need a logic level converter if my controller runs on 3.3V?

Most modern servos accept a 3.3V control signal because their internal logic thresholds recognize anything above roughly 2.0V as a high state. If you experience intermittent signal loss or jitter on a 3.3V board like a Raspberry Pi Pico or ESP32, use a simple logic level shifter or a 74HCT125 buffer to clean up the 5V signal path.

SB

Written by

Samuel Baker

Samuel Baker approaches each story with intellectual curiosity and a commitment to fairness, earning the trust of readers and sources alike.

More from robotics