連載一覧
- 第1回:プロジェクト概要
- 第2回:ESP32-S3 の環境構築
- 第3回:I/O の実装(ADC / PWM / DIO)
- 第4回:通信プロトコル(JSON コマンド)
- 第4.5回:デバイス化対応
- 第5回:Python アプリの API 実装
- 第6回:デバイスとしてまとめる(設計編)
- 第7回:実装編・応用編(GUI / アプリ化 / 拡張の可能性)
はじめに
第2回では、ESP32‑S3 の開発環境を構築し、USB シリアル通信とオンボード LED の点滅まで確認しました。
今回は、ESP32‑S3 を「外部デバイスを制御できるマイコン」として使うための基礎となる I/O(入力・出力) を扱います。
ESP32‑S3 は GPIO の自由度が高く、デジタル入出力・アナログ入力・PWM出力 といった基本機能を使うことで、LED、ボタン、センサー、モーターなど幅広いデバイスを扱えるようになります。
今回扱う内容は次の3つです。
- デジタル入出力(DIO)
- アナログ入力(ADC)
- PWM 出力(LED の明るさ調整)
ESP32‑S3‑DevKitC‑1のピン配置
今回も「ESP32‑S3‑DevKitC‑1(互換品)」を使用します。
デジタル入出力(DIO)
DIO とは
GPIO ピンを HIGH / LOW の 2 値で扱う最も基本的な I/O です。
LED の ON/OFF、リレー制御、ボタン入力など、電子工作の基礎となる機能です。
図のような回路を作って、入力(タクトスイッチ)と出力(LED)を試すことができます。

ボタン(入力)を押している間LED(出力)を点灯するプログラム
// LED を接続しているピン番号
const int LED_PIN = 5;
// ボタンを接続しているピン番号(プルアップ入力)
const int BUTTON_PIN = 10;
void setup() {
// LED ピンを出力に設定
pinMode(LED_PIN, OUTPUT);
// ボタンピンを内部プルアップ付き入力に設定
// → ボタンが押されていないと HIGH、押されると LOW になる
pinMode(BUTTON_PIN, INPUT_PULLUP);
// シリアルモニタ用の通信速度を設定
Serial.begin(115200);
}
void loop() {
// ボタンの状態を読み取る(HIGH or LOW)
int state = digitalRead(BUTTON_PIN);
// ボタンが押されているとき(LOW)
if (state == LOW) {
digitalWrite(LED_PIN, HIGH); // LED を点灯
Serial.println("PRESSED"); // シリアルに「PRESSED」と表示
} else {
digitalWrite(LED_PIN, LOW); // LED を消灯
Serial.println("RELEASED"); // シリアルに「RELEASED」と表示
}
// 状態を読みやすくするための 100ms 待機
delay(100);
}
アナログ入力と PWM 出力( LED の明るさ調整)
ADC(アナログ入力)とは
ADC は アナログ信号(連続的な電圧)をデジタル値( 0〜4095 などの整数)に変換する回路です。
ESP32‑S3には、12bit( 0〜4095 )の分解能を持つ ADC が搭載されており、0〜約3.3Vの電圧を読み取り、0〜4095の整数値として取得できます。
<ADC の基本仕様>
- 分解能:12bit(0〜4095)
- 入力電圧範囲:0〜約3.3V
- analogRead(pin) で値を取得できる
PWM とは
PWM はデジタル信号の ON/OFF の比率(デューティ比)を変えることで、アナログ的な出力を実現する仕組みです。 この出力を LED の点灯に使用すると、電圧の強弱ではなく「点灯時間の割合」で明るさが変わります。
• デューティ 0% → 常にOFF(暗い)
• デューティ 50% → 半分の時間だけ点灯(中くらいの明るさ)
• デューティ 100% → 常にON(最大の明るさ)人間の目は高速の点滅を連続光として認識するため、点滅の割合を変えるだけで明るさが変わって見えるという仕組みです。
ESP32‑S3 は LEDC(LED Control) という PWM モジュールを搭載しており、
LED の明るさ調整やモーター制御に利用できます。
デジタル入出力で使用したタクトスイッチを可変抵抗に置き換えて図のように接続すると、アナログ入力とPWMを試すことができます。

可変抵抗の値に応じてLEDの明るさを調節するプログラム
// PWM 出力に使う GPIO ピン番号
const int LED_PIN = 5;
// アナログ入力に使う GPIO ピン番号(0〜4095 の ADC 値)
const int ANALOG_PIN = 10;
void setup() {
Serial.begin(115200);
// LEDC(PWM)初期化
// 第1引数: PWM を出力するピン番号
// 第2引数: PWM 周波数(Hz)
// 第3引数: 分解能(ビット数)→ 8bit なら 0〜255
//
// esp32 v3.x では ledcAttachPin() ではなく ledcAttach() を使う。
ledcAttach(LED_PIN, 5000, 8);
}
void loop() {
// アナログ入力を読み取る(0〜4095:12bit)
int sensorValue = analogRead(ANALOG_PIN);
// 読み取った値を PWM の 0〜255 に変換
// 0 → 最小デューティ
// 4095 → 最大デューティ
int pwmValue = map(sensorValue, 0, 4095, 0, 255);
// PWM 出力
// esp32 v3.x では ledcWrite() に「チャンネル番号」ではなく「ピン番号」を渡す
ledcWrite(LED_PIN, pwmValue);
// デバッグ出力
Serial.print("Analog: ");
Serial.print(sensorValue);
Serial.print(" PWM: ");
Serial.println(pwmValue);
delay(20); // 更新間隔(20ms)
}
次回予告
第4回では、ESP32‑S3 と PC(Python アプリ)を連携させるための 通信プロトコル(JSON コマンド) を扱います。
双方向通信を行い、PC からデバイスを制御できる仕組みを作っていきます。
📘 ESP32-S3 IO デバイス連載のまとめ記事はこちら
👉 https://qiita.com/Noritama-Lab/items/cae87dc4cd67fe438c82


