《ESP32 入門》NodeMCU-32S 控制 SG90 伺服馬達(Servo)
用 ESP32 NodeMCU-32S 搭配 ESP32Servo 函式庫控制 SG90 伺服馬達。教學包含基本角度控制與可變電阻即時調整角度,附接線圖、程式碼與供電注意事項。
伺服馬達(Servo),對岸稱為舵機,常見於遙控車、機器手臂、機器人等用途。一般型式的伺服馬達可以旋轉 0~180 度,而且可以透過 PWM 訊號精準控制角度。伺服馬達款式型號非常多,本篇以最常見、最便宜的 SG90 為例來進行介紹,其他像 MG995、MG996R 等金屬齒輪款的使用方式基本相同。
認識 SG90
SG90 是一顆微型伺服馬達,體積小、價格便宜,非常適合入門學習。以下是它的基本規格:
| 項目 | 規格 |
|---|---|
| 工作電壓 | 4.8V ~ 6V |
| 旋轉角度 | 0° ~ 180° |
| 空載電流 | 約 100~200mA |
| 堵轉電流 | 約 600~700mA |
| 重量 | 約 9g |
SG90 有 3 條線,順序是固定的:
| 線色 | 功能 |
|---|---|
| 橘色(或黃色) | 訊號線(Signal) |
| 紅色 | VCC(電源正極) |
| 褐色(或黑色) | GND(電源負極) |
💡 小提醒:不同廠商的線色可能略有差異,有些 GND 是褐色、有些是黑色,訊號線有些是橘色、有些是黃色。如果不確定,請對照賣家提供的規格表。

準備材料
| 材料 | 數量 |
|---|---|
| NodeMCU-32S 開發板 | 1 |
| SG90 伺服馬達 | 1 |
| 杜邦線 / 麵包板跳線 | 若干 |
| 麵包板 | 1(選用) |



接線方式
| SG90 | NodeMCU-32S |
|---|---|
| 訊號線(橘/黃) | GPIO 26 |
| VCC(紅) | VIN(5V) |
| GND(褐/黑) | GND |

⚠️ 為什麼 VCC 接 VIN 而不是 3V3? SG90 的工作電壓是 4.8V~6V,ESP32 的 3.3V 不夠推動它。NodeMCU-32S 在 USB 供電時,VIN 腳位可以輸出約 5V,剛好在 SG90 的工作範圍內。
⚠️ 電流注意:單顆 SG90 空載運作電流約 100~200mA,但堵轉(被卡住)時可達 600~700mA。如果你要同時驅動 2 顆以上的伺服馬達,建議外接獨立的 5V 電源供電,不要全靠 ESP32 的 USB 供電,否則容易出現抖動甚至重開機的狀況。
ESP32 控制伺服馬達的方式
在 Arduino Uno 上,我們通常使用內建的 Servo.h 函式庫來控制伺服馬達,非常方便。但在 ESP32 上,原版的 Servo.h 是不能用的,因為底層的計時器架構不同。
好消息是,有一個專門為 ESP32 開發的函式庫叫 ESP32Servo,用法和原版幾乎一模一樣,只要安裝好就能無痛切換。
安裝 ESP32Servo 函式庫
在 Arduino IDE 中:
- 點選上方選單「工具」→「管理函式庫...」
- 搜尋 ESP32Servo
- 找到 ESP32Servo by Kevin Harrington,點「安裝」
安裝完成後就可以在程式中使用了。

範例一:基本角度控制
我們先來寫一個最簡單的例子:讓伺服馬達歸零(回到 0 度),停 1 秒,轉到 90 度,停 1 秒,再轉到 180 度,然後依序轉回來。
#include <ESP32Servo.h> // 載入 ESP32 專用的 Servo 函式庫
Servo myservo; // 建立 Servo 物件
void setup() {
myservo.attach(26); // 訊號線接到 GPIO 26
}
void loop() {
myservo.write(0); // 旋轉到 0 度(歸零)
delay(1000);
myservo.write(90); // 旋轉到 90 度
delay(1000);
myservo.write(180); // 旋轉到 180 度
delay(1000);
myservo.write(90); // 轉回 90 度
delay(1000);
}
上傳程式後,你會看到 SG90 的搖臂依序轉到 0°→90°→180°→90°,不斷循環。

程式核心就兩行:
myservo.attach(26);— 設定伺服馬達的訊號線接在哪個 GPIOmyservo.write(角度);— 控制旋轉角度,參數為 0~180
就這樣,真的很簡單!
範例二:搭配可變電阻即時控制角度
學會基本控制後,我們再來進階一點,用一顆可變電阻(旋鈕)來即時控制伺服馬達的角度,轉動旋鈕就能讓馬達跟著轉。
額外材料
| 材料 | 數量 |
|---|---|
| 可變電阻(10KΩ) | 1 |

接線
可變電阻有 3 支腳,中間腳接 GPIO 34(類比輸入),兩側分別接 3V3 和 GND。伺服馬達的接線不變。
| 可變電阻 | NodeMCU-32S |
|---|---|
| 左腳 | GND |
| 中間腳 | GPIO 34 |
| 右腳 | 3V3 |
程式碼
#include <ESP32Servo.h>
Servo myservo;
const int servoPin = 26; // 伺服馬達訊號線
const int potPin = 34; // 可變電阻接類比輸入
void setup() {
Serial.begin(115200);
myservo.attach(servoPin);
}
void loop() {
int potValue = analogRead(potPin); // 讀取可變電阻的值(0~4095)
int angle = map(potValue, 0, 4095, 0, 180); // 對應到 0~180 度
myservo.write(angle); // 控制伺服馬達
Serial.print("可變電阻值: ");
Serial.print(potValue);
Serial.print(" 角度: ");
Serial.println(angle);
delay(20); // 短暫延遲,讓馬達有時間反應
}
ESP32 的 ADC 解析度是 12-bit,所以 analogRead() 回傳的值是 0~4095(Arduino Uno 是 10-bit,0~1023)。我們用 map() 把 0~4095 對應到 0~180 度,就能用旋鈕即時控制角度了。打開 Serial Monitor(鮑率 115200)可以看到即時的數值變化。

ESP32 GPIO 使用注意事項
老規矩,提醒一下 ESP32 有些 GPIO 要避開:
- GPIO 0、2、12、15:Strapping Pins,影響開機模式,避免使用。
- GPIO 6~11:連接內部 SPI Flash,不能使用。
- GPIO 34、35、36、39:純輸入腳位(Input Only),不能輸出 PWM,但可以拿來接可變電阻做類比輸入。
本範例伺服馬達訊號線使用 GPIO 26(輸出),可變電阻使用 GPIO 34(輸入),都在安全範圍內。
常見問題
Q:伺服馬達一直抖動,或是一直斷? 最常見的原因是供電不足。確認 VCC 接到 VIN(5V),不是 3V3。如果同時接了其他耗電元件或多顆馬達,建議外接獨立的 5V 電源。另外,杜邦線太長或接觸不良也會造成抖動。
Q:馬達轉的角度不準? SG90 是入門級的伺服馬達,精度本來就有限。如果你發現 write(0) 時馬達沒有完全轉到底,可以用 myservo.attach(26, 500, 2400); 自訂脈衝寬度範圍來微調(預設是 544~2400 微秒)。
Q:可以用 ESP32 原版的 Servo.h 嗎? 不行,Arduino 原版的 Servo.h 不支援 ESP32 的計時器架構,編譯會失敗。請安裝 ESP32Servo 函式庫,用法幾乎一樣,改個 #include 就好。
Q:ESP32 最多能控制幾顆伺服馬達? ESP32Servo 函式庫最多可以同時控制 16 顆伺服馬達(對應 LEDC 的 16 個通道),比 Arduino Uno 的 12 顆還多。當然前提是電源要夠力。
Q:可以用 MG995 或其他伺服馬達嗎? 可以,程式完全相同。但 MG995 這類金屬齒輪馬達的堵轉電流更大(可達 1.2A 以上),一定要外接獨立電源,絕對不能只靠 ESP32 的 USB 供電。
小結
這篇我們學會了用 ESP32 NodeMCU-32S 搭配 ESP32Servo 函式庫來控制 SG90 伺服馬達。核心就是 attach() 指定腳位、write() 控制角度,跟 Arduino 的用法幾乎一樣。我們還用可變電阻做了即時角度控制的進階範例。掌握了伺服馬達,你就可以延伸做機器手臂、自動門鎖、雲台等各種有趣的專案了!



