Relay and servo control
Move a hobby servo to any angle and switch a relay module on and off by typing commands on the bench.
Board
ESP32
3V3
GND
EN
23
VP
22
VN
TX
34
RX
35
21
32
GND
33
19
25
18
26
5
27
17
14
16
12
4
GND
0
13
2
D2
15
D3
D1
CMD
D0
5V
CLK
Wiring
| From | To board | Note |
|---|---|---|
| Servo red (power) | 5V | One micro servo is fine from USB. Bigger servos need their own 5 V supply |
| Servo brown or black (ground) | GND | Join the grounds if the servo has its own supply |
| Servo orange or yellow (signal) | GPIO 18 | 3.3 V signals work with most hobby servos |
| Relay module VCC | 5V or 3V3 | Whatever the module is made for. Check its label |
| Relay module GND | GND | |
| Relay module IN or SIG | GPIO 26 | Many blue modules switch on when IN is low: set RELAY_ACTIVE_LOW |
Tested on this board
Not run on this board yet. Treat the wiring and code as a first draft.
Firmware, Arduino sketch for ESP32 Dev Module
#include <ESP32Servo.h>
const int SERVO_PIN = 18;
const int RELAY_PIN = 26;
const bool RELAY_ACTIVE_LOW = false; // set true if your relay clicks on when IN is low
Servo servo;
String line;
void relay(bool on) {
digitalWrite(RELAY_PIN, on != RELAY_ACTIVE_LOW ? HIGH : LOW);
Serial.printf("relay %s\n", on ? "on" : "off");
}
void setup() {
Serial.begin(115200);
pinMode(RELAY_PIN, OUTPUT);
relay(false);
servo.setPeriodHertz(50);
servo.attach(SERVO_PIN, 500, 2400); // pulse range in microseconds for SG90-class servos
servo.write(90);
Serial.println("ready: type angle 0 to 180, relay on or relay off");
}
void loop() {
while (Serial.available()) {
char ch = Serial.read();
if (ch == '\r') continue;
if (ch != '\n') {
line += ch;
continue;
}
line.trim();
if (line.startsWith("angle ")) {
int angle = constrain(line.substring(6).toInt(), 0, 180);
servo.write(angle);
Serial.printf("servo %d deg\n", angle);
} else if (line == "relay on") {
relay(true);
} else if (line == "relay off") {
relay(false);
} else if (line.length() > 0) {
Serial.printf("unknown command: %s\n", line.c_str());
}
line = "";
}
}S3
3V3
GND
3V3
TX
RST
RX
4
1
5
2
6
42
7
41
15
40
16
39
17
38
18
37
8
36
3
35
46
0
9
45
10
48
11
47
12
21
13
20
14
19
5V
GND
GND
GND
Wiring
| From | To board | Note |
|---|---|---|
| Servo red (power) | 5V | One micro servo is fine from USB. Bigger servos need their own 5 V supply |
| Servo brown or black (ground) | GND | Join the grounds if the servo has its own supply |
| Servo orange or yellow (signal) | GPIO 5 | 3.3 V signals work with most hobby servos |
| Relay module VCC | 5V or 3V3 | Whatever the module is made for. Check its label |
| Relay module GND | GND | |
| Relay module IN or SIG | GPIO 6 | Many blue modules switch on when IN is low: set RELAY_ACTIVE_LOW |
Tested on this board
Not run on this board yet. Treat the wiring and code as a first draft.
Firmware, Arduino sketch for ESP32S3 Dev Module
#include <ESP32Servo.h>
const int SERVO_PIN = 5;
const int RELAY_PIN = 6;
const bool RELAY_ACTIVE_LOW = false; // set true if your relay clicks on when IN is low
Servo servo;
String line;
void relay(bool on) {
digitalWrite(RELAY_PIN, on != RELAY_ACTIVE_LOW ? HIGH : LOW);
Serial.printf("relay %s\n", on ? "on" : "off");
}
void setup() {
Serial.begin(115200);
pinMode(RELAY_PIN, OUTPUT);
relay(false);
servo.setPeriodHertz(50);
servo.attach(SERVO_PIN, 500, 2400); // pulse range in microseconds for SG90-class servos
servo.write(90);
Serial.println("ready: type angle 0 to 180, relay on or relay off");
}
void loop() {
while (Serial.available()) {
char ch = Serial.read();
if (ch == '\r') continue;
if (ch != '\n') {
line += ch;
continue;
}
line.trim();
if (line.startsWith("angle ")) {
int angle = constrain(line.substring(6).toInt(), 0, 180);
servo.write(angle);
Serial.printf("servo %d deg\n", angle);
} else if (line == "relay on") {
relay(true);
} else if (line == "relay off") {
relay(false);
} else if (line.length() > 0) {
Serial.printf("unknown command: %s\n", line.c_str());
}
line = "";
}
}C3
GND
GND
3V3
TX
3V3
RX
2
GND
3
9
GND
8
RST
GND
GND
7
0
6
1
5
10
4
GND
GND
5V
18
5V
19
GND
GND
Wiring
| From | To board | Note |
|---|---|---|
| Servo red (power) | 5V | One micro servo is fine from USB. Bigger servos need their own 5 V supply |
| Servo brown or black (ground) | GND | Join the grounds if the servo has its own supply |
| Servo orange or yellow (signal) | GPIO 4 | 3.3 V signals work with most hobby servos |
| Relay module VCC | 5V or 3V3 | Whatever the module is made for. Check its label |
| Relay module GND | GND | |
| Relay module IN or SIG | GPIO 5 | Many blue modules switch on when IN is low: set RELAY_ACTIVE_LOW |
Tested on this board
Not run on this board yet. Treat the wiring and code as a first draft.
Firmware, Arduino sketch for ESP32C3 Dev Module
#include <ESP32Servo.h>
const int SERVO_PIN = 4;
const int RELAY_PIN = 5;
const bool RELAY_ACTIVE_LOW = false; // set true if your relay clicks on when IN is low
Servo servo;
String line;
void relay(bool on) {
digitalWrite(RELAY_PIN, on != RELAY_ACTIVE_LOW ? HIGH : LOW);
Serial.printf("relay %s\n", on ? "on" : "off");
}
void setup() {
Serial.begin(115200);
pinMode(RELAY_PIN, OUTPUT);
relay(false);
servo.setPeriodHertz(50);
servo.attach(SERVO_PIN, 500, 2400); // pulse range in microseconds for SG90-class servos
servo.write(90);
Serial.println("ready: type angle 0 to 180, relay on or relay off");
}
void loop() {
while (Serial.available()) {
char ch = Serial.read();
if (ch == '\r') continue;
if (ch != '\n') {
line += ch;
continue;
}
line.trim();
if (line.startsWith("angle ")) {
int angle = constrain(line.substring(6).toInt(), 0, 180);
servo.write(angle);
Serial.printf("servo %d deg\n", angle);
} else if (line == "relay on") {
relay(true);
} else if (line == "relay off") {
relay(false);
} else if (line.length() > 0) {
Serial.printf("unknown command: %s\n", line.c_str());
}
line = "";
}
}Parts
| Quantity | Part | Where to buy |
|---|---|---|
| 1× | ESP32 dev board | Buy at Amazon |
| 1× | Micro servo, SG90 or SG92R class | Buy at Adafruit |
| 1× | Relay module, such as a 3 V-ready mini relay board | Buy at Adafruit |
| 5× | Jumper wires |
Amazon buy links may include an Associates tag, and this site may earn a commission from qualifying Amazon purchases at no extra cost to you. Adafruit links are direct.
Libraries
ESP32Servo
Load it
- In the Arduino IDE, install the esp32 board package and pick the board named above the sketch.
- Install the libraries listed above from the Library Manager.
- Paste the sketch, choose the board's port and upload. Hold BOOT if the upload stalls at Connecting.
- Close the IDE's serial monitor, then open the bench here to watch the output.
Field notes
- Type the commands into the bench's send box: angle 45, relay on, relay off. The bench sends a line ending, which ends each command.
- Relay modules carry the transistor and the flyback diode a relay coil needs. A bare relay on a GPIO pin will not switch and its coil's voltage spike can kill the pin: use a module, or add an NPN transistor and a diode across the coil.
- Many cheap blue relay modules are made for 5 V logic and switch on when IN is pulled low. Some will not switch reliably from 3.3 V; a module sold as 3 V-ready avoids the guesswork.
- Mains voltage can kill. Keep relay projects to low-voltage loads unless you are qualified to wire mains, and never leave mains terminals exposed.
- A servo that twitches or resets the board is drawing more current than USB can give. Power it separately and join the grounds.
- If a servo buzzes at the ends of its travel, narrow the 500 to 2400 µs pulse range in attach() until it stops.
Not tested yet
- Not tested on hardware yet. Compiles for every board listed with Arduino-ESP32 core 3.3.12.
Built it? Send a build report with your board and what the serial port printed. Working reports become the "Tested on this board" entries above.