#105初級

ESP32でボタンによるLED制御(トグル)

ボタンを押すたびにLEDの状態が切り替わり、点灯中なら消灯し、消灯中なら点灯します。基本的なトグル動作です。チャタリング対策でボタンの機械的なノイズを除去し、1回の操作で1回だけ切り替わるようにします。

4.6(39)
57 完了
ESP32でボタンによるLED制御(トグル)
家の照明スイッチのように、ボタンを1回押すとLEDが点灯し、もう1回押すと消灯します。ESP32はボタンが押された瞬間を捉え、内部の細かな接点の跳ね返りを無視するため、1回押すたびに1回だけ状態が変わります。多くの機器にあるオン・オフボタンの仕組みを学べます。

動画

回路図

ESP32でボタンによるLED制御(トグル) - Circuit

ソースコード

Arduino (C++)
1// ─────────────────────────────────────────
2//   BlueGrays · bluegrays.com
3//   ESP32 LED Control with Pushbutton (Toggle)
4// ─────────────────────────────────────────
5// Each press of the button toggles the LED: on becomes off, off becomes
6// on. A 50 ms debounce makes sure one press gives exactly one toggle.
7//
8// Pins:
9//   GPIO 5 -> Red LED (with a 220 ohm resistor)
10//   GPIO 4 -> Button (other leg to GND)
11
12const int LED_PIN = 5;      // LED output
13const int BUTTON_PIN = 4;   // Button input
14
15bool ledState = false;               // Is the LED on now
16bool lastButton = HIGH;              // Previous button reading
17bool stableButton = HIGH;            // Stable (debounced) button state
18unsigned long lastChange = 0;        // Last time the reading changed (ms)
19const unsigned long DEBOUNCE = 50;   // Debounce time (ms)
20
21void setup() {
22  pinMode(LED_PIN, OUTPUT);
23  pinMode(BUTTON_PIN, INPUT_PULLUP);  // Reads HIGH when not pressed
24}
25
26void loop() {
27  bool buttonState = digitalRead(BUTTON_PIN);
28
29  // Restart the timer whenever the reading changes
30  if (buttonState != lastButton) lastChange = millis();
31
32  // A reading that stays the same for DEBOUNCE ms counts as stable. The LED toggles once, only when
33  // the stable state turns LOW (a new press).
34  if (millis() - lastChange > DEBOUNCE && buttonState != stableButton) {
35    stableButton = buttonState;
36    if (stableButton == LOW) {
37      ledState = !ledState;
38      digitalWrite(LED_PIN, ledState);
39    }
40  }
41  lastButton = buttonState;
42}
43

よくある質問

チャタリング対策の待ち時間はどのくらいが適切ですか?▾

多くのボタンでは20–50 msで十分です。短すぎると接点の跳ね返りまで検知し、長すぎると素早く連続して押した操作を取りこぼします。

トグル動作では、どの状態を検知すればよいですか?▾

ボタンが「押された」瞬間だけを検知してください。INPUT_PULLUPを使う場合は、HIGHからLOWへの変化です。押し続けている間にLEDが何度も切り替わらないよう、前回のボタンの状態を変数に保存してください。

チャタリング対策に`delay()`を使ってもよいですか?▾

簡単なプロジェクトでは使えますが、delay()は現在のloop()の実行を一時停止するため、同じ処理の流れにあるほかの操作が遅れます。ESP32のほかのタスクは動作できます。loop()内の処理を止めずに進めるには、millis()を使った時間管理が適しています。

電源を入れ直してもLEDの前回の状態を記憶できますか?▾

はい。ESP32ではPreferencesライブラリを使って状態を不揮発性メモリに書き込み、起動時に読み出せます。電源が切れて再び入っても、LEDは前回の状態から動作を開始します。