ESP32でLEDやリレーなどを制御するとき、
「GPIOから何mAまで流していいのか?」
と迷うことがあります。
例えばLEDなら、GPIOへ抵抗を接続して直接点灯させる回路をよく見かけます。
では、
10mAなら大丈夫なのか。
20mAならどうなのか。
40mAまで流せるのか。
そしてリレーやモーターもGPIOから直接動かしてよいのか。
今回はESP32-C5を例に、GPIOの出力電流と、実際の回路設計でどう考えるべきかを整理します。
「最大何mA?」だけで考えない
ESP32-C5-WROOM-1のデータシートには、GPIO出力について電流と出力電圧の関係が記載されています。
最も強いDrive設定では、High側について、
40mAをSourceした条件で、VOHが2.64V以上
という特性が示されています。
Low側では、
28mAをSinkした条件で、VOLが0.495V
という特性があります。
ここで注意したいのが、
40mAという数字だけを取り出さないこと
です。
GPIOは理想的な3.3V電源ではありません。
流す電流が大きくなれば、High出力の電圧は低下します。
同じようにLow側へ大きな電流を流せば、出力電圧は0Vから上昇します。
つまり、
「GPIOから何mA取り出せるか」と「回路として何mA流す設計にするか」は別の話
です。
Drive Strengthも設定できる
ESP32-C5のGPIOにはDrive Capabilityの設定があります。
ESP-IDFでは、
gpio_set_drive_capability()
を使ってGPIO PadのDrive Capabilityを変更できます。
ただし、Drive Strengthを強く設定したからといって、
外部負荷へ大電流を供給するための電源出力になるわけではありません。
Drive Strengthはデジタル信号を駆動する能力の設定です。
LEDをより明るくするために最大設定へする、リレーを動かすために最大設定へする、といった使い方を基本に考えるものではありません。
LEDなら直接駆動できる場合がある
LED程度の小さな負荷なら、GPIOから直接駆動できる場合があります。
例えば、
3.3V GPIO
↓
電流制限抵抗
↓
LED
↓
GND
という構成です。
重要なのは、必ず電流制限抵抗を入れることです。
LEDの順方向電圧を2.0V、GPIO出力を3.3V、抵抗を330Ωと仮定すると、
(3.3V - 2.0V) / 330Ω
なので、理想的には約4mAです。
実際にはGPIOの出力特性やLEDのVfによって変わりますが、この程度ならインジケータLEDとして十分な場合も多いでしょう。
「GPIOから20mA取れるから20mA流す」
ではなく、
必要な明るさを得られる範囲で電流を小さくする
方が扱いやすい設計です。
サンプルコード
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#define LED_GPIO GPIO_NUM_10
static const char *TAG = "GPIO_CURRENT";
void app_main(void)
{
gpio_config_t io_conf = {
.pin_bit_mask = (1ULL << LED_GPIO),
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE
};
ESP_ERROR_CHECK(gpio_config(&io_conf));
ESP_LOGI(TAG, "GPIO LED test start");
while (1)
{
gpio_set_level(LED_GPIO, 1);
ESP_LOGI(TAG, "LED ON");
vTaskDelay(pdMS_TO_TICKS(500));
gpio_set_level(LED_GPIO, 0);
ESP_LOGI(TAG, "LED OFF");
vTaskDelay(pdMS_TO_TICKS(500));
}
}
今回はGPIOを出力に設定し、LEDを500ms周期でON/OFFする簡単なコードを使用します。
このコード自体が電流を制限するわけではありません。
LED電流は外付け抵抗で制限します。
例えばGPIO10にLEDと電流制限抵抗を接続した場合を想定します。
以下が今回使用するサンプルコード全文です。
のサンプルではGPIO10をOutputとして使用しています。
ここで、
gpio_set_level()で1を出したから3.3V・何mAという電源が保証される、
という考え方はしません。
接続する負荷によってGPIOの電圧・電流条件は変化します。
GPIOをOutputに設定する
サンプルコードでは、次の部分でGPIO10を出力として設定しています。
gpio_config_t io_conf = {
.pin_bit_mask = (1ULL << LED_GPIO),
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE
};
ESP_ERROR_CHECK(gpio_config(&io_conf));
ここではGPIOをOutputとして設定しているだけです。
接続する負荷の電流までESP-IDFが管理してくれるわけではありません。
例えばGPIOに低い抵抗値を接続すれば、GPIOはその負荷を駆動しようとします。
そのため回路側で、
- 負荷に必要な電流
- GPIOの出力特性
- 電流制限抵抗
- 外部ドライバが必要か
を判断します。
GPIOのON/OFFは信号として考える
LEDのON/OFFは次の部分で行っています。
gpio_set_level(LED_GPIO, 1);
ESP_LOGI(TAG, "LED ON");
vTaskDelay(pdMS_TO_TICKS(500));
gpio_set_level(LED_GPIO, 0);
ESP_LOGI(TAG, "LED OFF");
ここで考えておきたいのが、
GPIOは基本的に「電力を供給する端子」ではなく「信号を出力する端子」として扱う
という考え方です。
LEDのように数mA程度で目的を達成できる負荷なら直接駆動できることがあります。
しかし負荷電流が大きくなってくると、
GPIO
↓
トランジスタ / MOSFET
↓
負荷
という構成にします。
GPIOはトランジスタやMOSFETへON/OFFの指示を出し、実際の負荷電流は外部電源から供給します。
リレーをGPIOから直接駆動しない
例えばコイル電流が50mA必要なリレーがあったとします。
「GPIOは40mA程度まで出せるらしいから、少しだけ足りない」
という問題ではありません。
そもそもGPIOへリレーコイルを直接接続する設計を避けます。
一般的には、
ESP32 GPIO
↓
抵抗
↓
トランジスタ / MOSFET
↓
リレーコイル
↓
電源
とします。
さらにリレーコイルのような誘導性負荷では、OFF時に発生する逆起電力への対策も必要です。
GPIOの電流能力だけを見て、
「数字上流せそうだから接続する」
という判断をしないことが重要です。
モーターも直接駆動しない
DCモーターなどはさらに明確です。
起動時には定常運転時より大きな電流が流れることがあります。
またモーターは誘導性負荷であり、ノイズ源にもなります。
そのためESP32のGPIOから直接駆動するのではなく、
- MOSFET
- Motor Driver IC
- H-Bridge
などを使用します。
ESP32の役割は、
モーターへ電力を供給することではなく、Driverへ制御信号を送ること
です。
MOSFETなら何でもよいわけではない
GPIOからMOSFETを駆動する場合も注意が必要です。
ESP32-C5のGPIOは3.3V系です。
そのためMOSFETを選定するときは、
VGS = 3.3V付近で十分にONできるか
を確認します。
MOSFETのデータシートに記載されたThreshold Voltageだけを見て、
「VGS(th)が2Vだから3.3Vで使える」
と判断するのは危険です。
VGS(th)は、一般にMOSFETが大電流を十分低いON抵抗で流せることを保証する値ではありません。
実際に使用するGate VoltageでのRDS(on)などを確認します。
複数GPIOならさらに注意する
もう一つ忘れやすいのが、
GPIOを1本だけ使用する場合と、多数を同時使用する場合は同じではない
ということです。
例えば、
「1pinである程度流せる」
という情報だけを見て、
多数のGPIOすべてへ同じ電流を流してよいとは限りません。
実際の設計ではGPIO単体だけでなく、デバイス全体の電源条件、同時駆動するI/O数、発熱、電圧降下なども考える必要があります。
そのため、
1pinの最大値 × GPIO本数
という計算だけで設計するのは避けます。
SourceとSinkの違い
GPIOから電流を扱うときは、SourceとSinkを分けて考えます。
SourceはGPIOから外部へ電流を流す状態です。
例えば、
ESP32 GPIO → 抵抗 → LED → GND
という回路でGPIOをHIGHにすると、GPIOからLEDへ電流が流れます。
一方、Sinkは外部からGPIOへ電流を流し込む状態です。
例えば、
3.3V → 抵抗 → LED → ESP32 GPIO
としてGPIOをLOWにすると、GPIO側へ電流が流れます。
同じLEDを点灯させる場合でも、GPIOが担う役割は異なります。
SourceとSinkで特性は同じではない
ESP32-C5のデータシートでは、High出力側とLow出力側で別々にDC特性が示されています。
そのため、
「GPIOは何mAまで流せるか」
を一つの数字だけで表現するのは適切ではありません。
High出力時にはVOHがどこまで維持されるか。
Low出力時にはVOLがどこまで上昇するか。
このように、出力電圧と電流の関係で考えます。
回路側が3.3V近いHighを必要としているのに、大きな電流をSourceした結果としてGPIO電圧が大きく低下すれば、論理信号としても問題になる可能性があります。
Drive Capabilityとは?
ESP32-C5ではGPIOのDrive Capabilityを設定できます。
ESP-IDFではgpio_set_drive_capability()を使用します。
Drive Capabilityは、GPIO出力の駆動能力を変更するための設定です。
ただし、
Drive Capabilityを最大にすれば、大電流負荷を直接駆動できる
という意味ではありません。
Drive Strengthを強くすると、配線容量などに対して信号をより強く駆動できます。
一方で、立ち上がり・立ち下がりが速くなることで、基板条件によってはリンギングやEMIなどの影響も考慮する必要があります。
つまり、
必要以上に強く設定することが常に正解ではありません。
LEDを複数同時に点灯する場合
1個のLEDを数mAで点灯する回路なら問題がなくても、LEDを多数同時にGPIOから駆動する場合は話が変わります。
例えば10個のLEDへそれぞれ5mA流すと、
合計では50mAです。
ここで、
「1GPIOあたり5mAだから問題ない」
だけで判断してはいけません。
確認したいのは、
- 同時にONするGPIO数
- デバイス全体の電源条件
- GPIOのSource/Sink状態
- 3.3V電源への負荷
- 発熱
- GPIO電圧の変化
などです。
多数のLEDを点灯する場合は、LED Driver ICやトランジスタアレイを使った方が合理的なこともあります。
GPIOの最大値を合計しない
特に避けたいのが、
1pinの数字 × GPIO本数
という考え方です。
例えば、
40mA × 10pin = 400mA
だからESP32から400mA取り出せる、
という計算にはなりません。
GPIO単体の出力特性と、デバイス全体の電源・内部回路の制約は別に考える必要があります。
多数のGPIOから比較的大きな電流を同時に取る設計は避け、外部ドライバを使う方が安全です。
MOSFETを使う判断
負荷電流がGPIO直接駆動には大きい場合、MOSFETを使う方法があります。
基本構成は、
ESP32 GPIO
↓
Gate抵抗
↓
MOSFET Gate
そして負荷側は、
電源
↓
負荷
↓
MOSFET
↓
GND
です。
この場合、GPIOはMOSFETのGateを制御するだけなので、負荷電流そのものはGPIOへ流れません。
例えば、
- リレー
- ソレノイド
- 小型DCモーター
- LED Strip
- ヒーター制御信号
などでは、このような構成が有効です。
Logic Level MOSFETを選ぶ
ESP32-C5は3.3V GPIOです。
そのためMOSFETを選定するときは、
VGS = 2.5Vや3.3V付近でRDS(on)が規定されているもの
を選ぶと判断しやすくなります。
注意したいのがVGS(th)です。
VGS(th)はMOSFETが十分低いON抵抗になるGate電圧ではありません。
一般に、非常に小さなDrain電流が流れ始める条件として規定されています。
したがって、
VGS(th) = 1.5V
だから、
3.3V GPIOなら完全にONできる、
とは判断しません。
実際に使用するGate電圧でのRDS(on)を確認します。
Gate抵抗は何のため?
MOSFET GateはDC的にはほとんど電流を消費しません。
ただしGateには容量があります。
ON/OFF時にはこの容量を充放電するため、一時的にGPIOから電流が流れます。
そこでGPIOとMOSFET Gateの間に、数十Ω〜数百Ω程度の抵抗を入れることがあります。
目的は、
- Gate充放電電流のピークを抑える
- リンギングを抑える
- GPIOへの負担を軽減する
- スイッチング速度を調整する
などです。
最適値はMOSFET、周波数、負荷条件によって変わります。
Gate Pull-downも検討する
MOSFETをLow Side Switchとして使用する場合、
ESP32がReset中、
起動途中、
GPIOがHi-Zの期間、
などにGateが浮く可能性があります。
そこで、
Gate → GND
へPull-down抵抗を設け、ESP32が制御していない状態ではMOSFETをOFFへ保つ設計がよく使われます。
例えば10kΩ〜100kΩ程度を検討します。
重要なのは抵抗値そのものより、
起動時に負荷が勝手にONしない構成にすること
です。
リレーやモーターでは逆起電力対策も必要
リレーコイルやDCモーターのような誘導性負荷では、電流を急に遮断すると大きな電圧が発生します。
そのため、
- Flyback Diode
- TVS
- Snubber
などを負荷条件に応じて検討します。
MOSFETを使えばGPIOから大電流を切り離せますが、
MOSFETを追加しただけで回路が完成するわけではありません。
負荷の性質も考える必要があります。
トランジスタを使う場合
小型リレーなどでは、NPNトランジスタを使うこともできます。
ESP32 GPIO
↓
Base抵抗
↓
NPN transistor
↓
Relay
という構成です。
この場合はMOSFETとは異なり、Base電流を流す必要があります。
そのため、
- 必要なCollector電流
- トランジスタの増幅率
- Base電流
- GPIOから流す電流
- Base抵抗
を設計します。
負荷電流が大きくなるほど、MOSFETの方が扱いやすい場合も多いです。
「直接駆動するか」の判断基準
実際の設計では、私は次のように考えると整理しやすいと思います。
数mA程度の表示LED
→ GPIO直接駆動を検討できる
外部ICのDigital Input
→ 基本的にGPIOから直接接続できる
ただし電圧レベルや入力条件を確認
トランジスタ/MOSFET Gate
→ GPIOで制御可能
Gate条件・抵抗・起動時状態を確認
数十mA以上必要な負荷
→ 外部Driverを検討
誘導性負荷
→ Driver+逆起電力対策
モーターや大電力負荷
→ 専用DriverやMOSFET回路を使用
このように、GPIOの限界値から逆算するより、
負荷の種類から駆動方法を決める
方が設計しやすくなります。
GPIOが壊れる前に起こること
GPIOに過大な負荷を接続した場合、
いきなり完全故障するとは限りません。
その前に、
- High電圧が下がる
- Low電圧が上がる
- 通信が不安定になる
- GPIO出力が期待通りにならない
- ESP32全体の電源が不安定になる
- Resetが発生する
といった症状として現れる可能性があります。
つまり、
動いているから安全とは限りません。
長時間運転や温度条件、複数GPIO同時動作なども含めて確認します。
GPIOトラブルの切り分け
GPIOに接続した負荷が正常に動かない場合は、次の順番で確認すると整理しやすくなります。
1. GPIO単体の電圧を確認する
負荷を外した状態でHIGH/LOWが正常か確認します。
2. 負荷接続後の電圧を見る
負荷を接続した瞬間にHigh電圧が大きく下がっていないか確認します。
3. 負荷電流を確認する
必要な電流が想定通りか確認します。
4. 外部Driverを入れて確認する
Driver経由で正常になるなら、GPIO直接駆動が原因候補になります。
5. 電源全体を見る
負荷切替によって3.3V自体が低下していないか確認します。
GPIOを使うときの設計チェック
最後に、実際の回路設計で確認したいポイントをまとめます。
- GPIOは信号出力として使う
- データシートの電流値だけを見ない
- Source/Sinkを区別する
- VOH/VOL条件を見る
- LEDは必要最小限の電流で使う
- 数十mA級の負荷は直接駆動しない
- モーターやリレーは外部Driverを使用する
- MOSFETは3.3VでのRDS(on)を確認する
- 誘導性負荷には逆起電力対策を入れる
- 多数GPIOの同時駆動にも注意する
- 起動時のGPIO状態も確認する
まとめ
ESP32-C5のGPIOには数十mAクラスの出力特性が記載されています。
しかし、それは、
「その電流を積極的に取り出して負荷を駆動するための電源端子」
という意味ではありません。
GPIOは基本的に、
外部回路へHIGH/LOWを伝える信号端子
として考えます。
小電流のLEDなどは直接駆動できる場合がありますが、
- リレー
- モーター
- ソレノイド
- 大電流LED
などはMOSFETやトランジスタ、専用Driverを使用します。
そして重要なのは、
最大何mA流せるかではなく、必要な機能をどれだけ余裕を持って実現できるか
です。
データシートの最大付近を目標にするのではなく、GPIOに必要以上の負担をかけない回路を作る。
その方が、長時間安定して動作する製品へつながります。
技術は、経験から価値になる。
DLROW Design | 現場エンジニア