伺服馬達是一種可精確控制角度的馬達,常用於機器人、遙控車等各種領域,以SG90為例,接腳配置如下:
- 棕色:接地(GND)
- 紅色:電源(VCC,通常接 5V )
- 橙色:信號線(Signal)
伺服馬達一般透過 PWM 信號控制定位的角度,脈波寬度通常在 500μs 到 2400μs 之間,對應 0 到 180 度的定位角度。






基本範例:
#include <ESP32Servo.h> // 引用ESP32Servo函式庫
Servo MyServo; // 建立SERVO物件
int servoPin = 15; // 伺服馬達信號接腳
void setup() {
MyServo.attach(servoPin, 500, 2400); // 初始化伺服馬達,// SG90:500us~2400us
}
void loop() {
MyServo.write(0); // 定位到 0 度
delay(1000);
MyServo.write(45); // 定位到 45 度
delay(1000);
MyServo.write(90); // 定位到 90 度
delay(1000);
MyServo.write(135); // 定位到 135 度
delay(1000);
MyServo.write(180); // 定位到 180 度
delay(1000);
MyServo.write(135); // 定位到 135 度
delay(1000);
MyServo.write(90); // 定位到 90 度
delay(1000);
MyServo.write(45); // 定位到 45 度
delay(1000);
MyServo.write(0); // 定位到 0 度
delay(1000);
}
由監看視窗輸入角度範例:
//---------------------------------------------------------------------------------
#include <ESP32Servo.h> // 引用ESP32Servo函式庫
Servo MyServo; // 建立SERVO物件
int servoPin = 15; // 伺服馬達信號接腳
int angle = 0; // 伺服馬達定位角度(0~180),初始值為0
//---------------------------------------------------------------------------------
int input = 0; // 串列埠輸入值
//---------------------------------------------------------------------------------
void setup() {
//--------------------------------------------------------------
Serial.begin(9600); // 啟動串列埠監看視窗
//--------------------------------------------------------------
MyServo.attach(servoPin, 500, 2400); // 初始化伺服馬達,// SG90:500us~2400us
MyServo.write(angle); // 移動到定位角度
//--------------------------------------------------------------
}
void loop() {
//----------------------------------------------------------
//串列埠監看視窗輸入
//----------------------------------------------------------
if (Serial.available()) //若串列埠有輸入資料,則執行下列程式區塊
{
input = readNumber();
if (input >= 0 && input <= 180)
{
angle = input;
MyServo.write(angle); // 移動到定位角度
}
else
{
//若輸入字串無效(其他)
Serial.println("Unknown range.");
Serial.println("Please enter an angle(0~180):"); // 輸入提示
}
}
}
// 讀取一個整數
int readNumber()
{
while (!Serial.available()); // 等待串列埠輸入
String input = Serial.readStringUntil('\n'); //讀取一行的輸入資料,直到換行符號為止(按下enter鍵)
input.trim(); //去除輸入字串前後的空白字元
Serial.println(input); //印出輸入字串
return input.toInt(); //轉換為整數
}
由監看視窗輸入角度,並在LCD上顯示結果範例:
//---------------------------------------------------------------------------------
#include <LiquidCrystal_I2C.h> // 引用LiquidCrystal_I2C函式庫
LiquidCrystal_I2C lcd(0x27, 16, 2); // 建立LiquidCrystal_I2C物件,名稱為lcd
//---------------------------------------------------------------------------------
#include <ESP32Servo.h> // 引用ESP32Servo函式庫
Servo MyServo; // 建立SERVO物件
int angle = 0; // 伺服馬達定位角度(0~180),初始值為0
//---------------------------------------------------------------------------------
int input = 0; // 串列埠輸入值
//---------------------------------------------------------------------------------
void setup() {
//--------------------------------------------------------------
Serial.begin(9600); // 啟動串列埠監看視窗
//--------------------------------------------------------------
MyServo.attach(15,500,2400); // SG90:500us~2400us
MyServo.write(angle); // 移動到定位角度
//--------------------------------------------------------------
lcd.init(); // 初始化lcd
lcd.backlight(); // 開啟背光
lcd.setCursor(0,0); // 定位在(0,0)
lcd.print("Angle:"); // 印出文字"Angle:"
print_angle(); // 在LCD上顯示定位角度
//--------------------------------------------------------------
}
void loop() {
//----------------------------------------------------------
//串列埠監看視窗輸入
//----------------------------------------------------------
if (Serial.available()) //若串列埠有輸入資料,則執行下列程式區塊
{
input = readNumber();
if (input >= 0 && input <= 180)
{
angle = input;
MyServo.write(angle); // 移動到定位角度
print_angle(); // 在LCD上顯示定位角度
}
else
{
//若輸入字串無效(其他)
Serial.println("Unknown range.");
Serial.println("Please enter an angle(0~180):"); // 輸入提示
}
}
}
// 讀取一個整數
int readNumber()
{
while (!Serial.available()); // 等待串列埠輸入
String input = Serial.readStringUntil('\n'); //讀取一行的輸入資料,直到換行符號為止(按下enter鍵)
input.trim(); //去除輸入字串前後的空白字元
Serial.println(input); //印出輸入字串
return input.toInt(); //轉換為整數
}
void print_angle() // 印出伺服馬達定位角度
{
lcd.setCursor(6,0);
lcd.print(" ");
if(angle>=0 && angle<10)
{
lcd.setCursor(8,0);
}
if(angle>=10 && angle<100)
{
lcd.setCursor(7,0);
}
if(angle>=100 && angle<=180)
{
lcd.setCursor(6,0);
}
lcd.print(angle);
}
作業練習:請用ESP32改寫下列題目。
01-控制科實作試題一、試題說明:
1.本試題使用ESP32微控制器、1602 I2C LCD顯示器、SG90伺服馬達及外接按鈕開關,由按鈕開關控制伺服馬達的啟動、停止及改變旋轉方向,由LCD顯示器呈現受控狀態。參考接線如附件電路圖。
2.ESP32 微控制器可自行決定欲使用的I/O接腳、電源接線等位置。
3.1602 I2C LCD顯示器隨操作狀態的不同,即時更新受控資訊。
4.SG90伺服馬達在0 ~ 180度之間的定位角度,做順時針或逆時針方向的往復循環。
5.外接按鈕開關請在自備的麵包板上完成接線,可自行決定使用外部或者內部Pull up、Pull Down電阻等驅動方式。
6.硬體供電方式:可自行決定使用電腦USB供電或使用外接直流電源供應器供電,以能正常完成本試題的動作要求為主。
7.本試題可使用相關函式庫(如:LiquidCrystal I2C、ESP32Servo等)。
二、動作要求:
1.ESP32微控制器開機啟動後或按下主板的Reset按鈕後,回復到初始狀態:
(1)伺服馬達狀態:停止。
(2)定位角度:0度。
(3)旋轉方向:順時針。
2.按鈕開關短按:每按一下,伺服馬達改變運轉或停止狀態一次,不改變當下位置及旋轉方向。
3.按鈕開關長按:每按一下(1秒以上),伺服馬達改變旋轉方向一次,不改變當下位置及運轉或停止狀態。
4.伺服馬達運轉時,每0.3秒移動定位角度5度,在0 ~ 180度之間做順時針或逆時針方向往復循環。(0°→5°→10°→……→175°→180°→175°→……→10°→5°→0°)
5.1602 I2C LCD顯示器隨操作狀態不同,在相對應的區塊上即時更新(平滑不停頓)顯示資訊:
(1)伺服馬達狀態:停止顯示Stop、運轉顯示Running。
(2)定位角度:正確顯示當下所在的位置,在0 ~ 180度之間。
(3)旋轉方向:順時針顯示C.W.、逆時針顯示C.C.W.。

成果影片: