ESP32-C3M-TRYでSW(スイッチ)の状態を調べる
はじめに
この記事ではESP32-C3M-TRYのSW(スイッチ)の状態を調べてその状態に応じてLEDを制御する方法について解説します。
なお、この記事は「ESP32でスイッチのON /OFFを調べる」をESP32-C3M-TRYに合わせて書き換えたものです。
基礎知識
下の図で、GPIO12に接続されている端子は10kΩの抵抗R1を介してGNDに接続されているので、スイッチS1を開いている状態ではLOW(0)となります。S1を閉じるとGPIO12は3.3Vと同じ電位となり、HIGH(1)となります。
このような結線はスイッチが開いている時、GPIOポートがGNDに引っ張られているので、プルダウン(Pull Down) と言います。
一方、GPIO14は10kΩの抵抗R2を介して3.3Vに接続されているので、S2を開いている状態ではHIGHとなり、S2を閉じるとGNDと同じ電位となり、LOWとなります。
このような結線はスイッチが開いている時、GPIOポートが3.3Vに引っ張られているので、プルアップ(Pull Up) と言います。
今回は右側のようにプルダウンで結線を行い、スイッチを押していない状態ではGPIOポートはLOWとなり、スイッチを押すとHIGHとなります。
チャタリングについて
機械的な接触を伴うスイッチでは、チャタリングという現象が生じます。 チャタリングを考慮しないで、短い間隔でスイッチの状態をチャックすると予期しない結果となる場合があります。
チャタリングを回避する方法にはハードウェアで行う場合とソフトウェアで行う場合があります。
チャタリングについての詳細は以下のサイトを参照して下さい。
ESP32-C3M-TRYのSWの場所
ESP32-C3M-TRYは下図のように3箇所にSW1、SW2、SW3があり、それぞれGPIO2、GPIO3、GPIO6のポートに接続されています。
SWの状態を調べる場合、それぞれのGPIOポートを入力モードとして設定し、そのポートの値を読み取ればSWが押されているか、押されていないかが分かります。
ESP32-C3M-TRYのSWの回路図
ESP32-C3M-TRYのSWは下図のように接続されているため、SWを押していない場合はR2のプルアップ抵抗を通じて3.3VがGPIOポートに供給されています。
SWを押すとGPIOポートがGND(グランド)と同電位となります。
これらのことから、SWが押されていない場合はGPIOポートはHight(1) となり、SWが押された場合はLow(0) となります。
R2の抵抗は通常、10KΩ程度が使われていて、GPIOポートを3.3Vに引き上げているのでプルアップ抵抗とよびます。
R2とSWを入れ替えた場合は、R2はGPIOポートをGND(0V)に引き下げているのでプルダウン抵抗と言います。
この場合、SWが押されていない場合はGPIOポートはLow(0) となり、押されるとHigh(1) となります。
プルダウン方式はノイズの影響を受けやすいので、SWなどではプルアップ方式を使うのが一般的です。
回路の接続によりプログラムが変わるので注意が必要です。
引用元の https://www.microfan.jp/document/ESP32-C3M-TRY-R1-20230701.pdf を加筆修正
サンプルコード1
SW1の状態を1秒ごとに調べて表示するプログラムです。
押されていると「0」と表示され、押されていないと「1」が表示されます。
# ESP32-C3M-TRYでSW1の状態を調べる
# プログラムの停止はCTRL+cもしくはThonnyのSTOPボタンをクリックする
# May 4th 2025
import machine
import time
# SW1はGPIO2に接続されている
SW1 = 2
# SW1のインスタンス作成
sw1 = machine.Pin(SW1, machine.Pin.IN)
# 無限ループでスイッチの状態を調べ表示する
while True:
# SWの状態はvalue()で取得できる
sw1_value = sw1.value()
print(sw1_value)
time.sleep(1)
サンプルコード2
サンプルコード1を変更して、SW1が押されていると「SW1が押されています」と表示されるように変更してみました。
# ESP32-C3M-TRYでSW1の状態を調べる
# プログラムの停止はCTRL+cもしくはThonnyのSTOPボタンをクリックする
# May 4th 2025
import machine
import time
# SW1はGPIO2に接続されている
SW1 = 2
# SW1のインスタンス作成
sw1 = machine.Pin(SW1, machine.Pin.IN)
# 無限ループでスイッチの状態を調べ表示する
while True:
# SWの状態はvalue()で取得できる
sw1_value = sw1.value()
# SW1が押された場合
if sw1_value == 0:
print("SW1が押されています。")
time.sleep(1)
サンプルコード3
SW1を押している時だけ、LED1(ESP32右側の水色のLED)を点灯させ、押すのをやめるとLEDが消灯するコードです。
# ESP32-C3M-TRYでSW1の状態を調べるてLEDを点灯、消灯させる
# プログラムの停止はCTRL+cもしくはThonnyのSTOPボタンをクリックする
# May 4th 2025
import machine
import time
# SW1はGPIO2に接続されている
SW1 = 2
# LEDはGPIO0に接続されている
LED = 0
# SW1のインスタンス作成
sw1 = machine.Pin(SW1, machine.Pin.IN)
# LEDのインスタンス作成
led = machine.Pin(LED, machine.Pin.OUT)
# 無限ループでスイッチの状態を調べ表示する
while True:
# SWの状態はvalue()で取得できる
sw1_value = sw1.value()
# SW1が押された場合
if sw1_value == 0:
print("SW1が押されました。")
# LED点灯
led.on()
else:
# LED消灯
led.off()
# 待機時間を短くする
time.sleep(0.2)
演習問題
-
SW1を押すとLED10が赤色に、SW2を押すとLED11が緑色に、SW3を押すとLED12が青色にそれぞれ点灯し、押すのをやめると消灯するプログラムを作成して下さい。(ファイル名: sw-ex1.py)
ヒント:SW1、SW2、SW3それぞれのインスタンスを作成する必要があります。カラーLEDのプログラムについてはESP32-C3M-TRYでLEDを点滅(Lちか)させるを参照して下さい。 -
SW1を2秒以上長押しするとLED11が赤色に点灯し、3秒後に消灯するプログラムを作成して下さい。(ファイル名: sw-ex2.py)
ヒント:
例えば、swflag_red = 0 とする
0.1秒ごとにSW1をチェックする。
もし、SW1が押されていたらswfla_redをカウントアップし、swfla_redが20以上ならLED11を赤色に点灯する。
押されてなかったら、swfla_red = 0にし、消灯する。 -
SW1を2秒以上長押しするとLED11が赤色に点灯し、もういちど2秒以上長押しすると消灯するプログラムを作成して下さい。(ファイル名: sw-ex3.py)
ヒント:
例えば、
ledflag11 を用意する。
LED11が点灯している場合はledflag11 = Trueにし、消灯している場合は ledflag11 = False にする。
ledflag11 を参照して、次に点灯するのか、消灯するのか判断する。 -
2番の問題をSW2でLED11が緑色で点灯し、SW3でLED12が青色に点灯するように拡張して下さい。(ファイル名: sw-ex4.py)
-
同様に、3番の問題をSW2でLED11が緑色で点灯し、SW3でLED12が青色に点灯するように拡張して下さい。(ファイル名: sw-ex5.py)
Discussion