🐝

ESP32でスイッチのON /OFFを調べる

2022/12/01に公開


はじめに

この記事ではスイッチをESP32開発ボードに接続し、PythonプログラムによりスイッチのON/OFFを調べる方法について記述しています。

In English

This article describes how to check on/off status of the switches connected to ESP32 development board in Japanese.

基礎知識

下の図で、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となります。

altSW説明図

タクトスイッチについて

一般的なタクトスイッチは4本の端子が出ていて、ボタンを押すとONになり、離すとOFFになります。
スイッチのON/OFFは同一辺にある端子間で行われ、反対側の辺に出ている端子は内部で繋がってる(右側の写真では手前右側の端子と奥右側同士が、手前左側の端子と奥左側同士が、左側の写真では手前右側と手前左側が、奥右側と奥左側が内部で接続されている)ので、ブレッドボードに実装する場合は方向に注意する必要があります。

altタクトスイッチ
上の写真で右側に写っているタクトスイッチで、手前側の端子同志がスイッチを押すとONになります。

チャタリングについて

機械的な接触を伴うスイッチでは、チャタリングという現象が生じます。 チャタリングを考慮しないで、短い間隔でスイッチの状態をチャックすると予期しない結果となる場合があります。
チャタリングを回避する方法にはハードウェアで行う場合とソフトウェアで行う場合があります。
チャタリングについての詳細は以下のサイトを参照して下さい。
https://ja.wikipedia.org/wiki/チャタリング

結線

結線はLちかの結線を行ったブレッドボードに拡張する形で行います。
用意する部品は以下の通りです。

  1. タクトスイッチ 3個
  2. 10kΩ抵抗 3個
  3. リード線 オレンジ、緑、青各1本、赤3本の合計6本

下の図を参考に結線して下さい。

altスイッチの結線

実際の結線例
alt実際の結線例

MicroPythonのドキュメントについて

Micropythonのドキュメントは以下のリンクを参照して下さい。

日本語
https://micropython-docs-ja.readthedocs.io/ja/latest/

本家(英語)
https://docs.micropython.org/en/latest/

サンプルプログラム1

1秒毎にスイッチ1(ESP32に近い側)が接続されているGPIO14をチェックしてスイッチが押されているかどうかを表示します。 (ファイル名:sw1.py)

altsw1.py
sw1.py

コピペ用 sw1.py
sw1.py
# Check Switch status
# sw1.py

from machine import Pin
import time

# SW1 is connected to GPIO14
SW1 = 14

# Make sw instance
sw1 = Pin(SW1, Pin.IN)

while True:
    print(sw1.value())
    time.sleep(1)

サンプルプログラム2

スイッチ1(ESP32に近い側)を押している間、赤色LED(GPIO4)が点灯し、押すのをやめると消灯します。
(ファイル名: sw2.py)

altsw2.py
sw2.py

コピペ用 sw2.py
sw2.py
# Check Switch status every 0.2 seconds and turn ON/OFF Red LED
# sw2.py

from machine import Pin
import time

# Red LED is connected to GPIO4
LED = 4

# SW1 is connected to GPIO14
SW1 = 14

# Make led instance
led = Pin(LED, Pin.OUT)

# Make sw instance
sw1 = Pin(SW1, Pin.IN)

while True:
    status = sw1.value()
    if status == 0:
        led.off()
        print("SW1 OFF")
    else:
        led.on()
        print("SW1 ON")
        
    time.sleep(0.2)
    

演習問題

  1. サンプルプログラム2のsw2.pyに加えて、スイッチ2(真ん中)とスイッチ3(ESP32より遠い側)を押しているあいだ、それぞれ、緑色LED、青色LEDが点灯し、押すのをやめると消灯するようなプログラムを作成して下さい。
    (ファイル名: sw-ex1.py)
    ヒント:
  • 緑色LED、青色LEDが接続されたGPIO0、GPIO15を出力モードにする。
  • スイッチ2が接続されたGPIO12およびスイッチ3が接続されたGPIO13をそれぞれ入力モードにする。
  • 無限ループの中で、もし、スイッチ2(真ん中)が押されていたら、緑色LEDを点灯、押されていなかったら消灯し、スイッチ3(ESP32より遠い側)が押されていたら、青色LEDを点灯、押されていなかったら、消灯する。
  1. 上のプログラムを変更し、スイッチ1(ESP32に近い側)を2秒以上長押しすると赤のLEDが3秒間点灯し、スイッチ2(ESP32より遠い側)を2秒以上長押しすると緑のLEDが3秒間点灯するプログラムを作成してください。
    (ファイル名:sw-ex2.py)
    ヒント:
    例えば、

    • swflag_red = 0 とする
    • 0.1秒ごとにスイッチをチェックする( スイッチ1(ESP32に近い側)が押されていたらswfla_redをカウントアップし、swfla_redが20以上ならLEDを点灯する。押されてなかったら、swfla_red = 0にし、消灯する。緑のLEDについてもswflag_greenとして同様に行う。)
  2. スイッチ1(ESP32に近い側)を2秒以上長押しすると赤のLEDが点灯し、もう一度2秒以上長押しすると赤のLEDが消灯するプログラムを作成してください。
    (ファイル名:sw-ex3.py)
    ヒント:
    例えば、
    ledflag を用意する。LEDが点灯している場合はledflag = Trueにし、消灯している場合は ledflag = False にする。
    ledflag を参照して、次に点灯するのか、消灯するのか判断する。

  3. スイッチ1(ESP32に近い側)を押すごとに、3ビットの2進数に見立てた3色のLEDがカウントアップして行き、スイッチ2(ESP32に遠い側)を押すとリセットされて、3色のLEDが全部消灯するプログラムを作成して下さい。(ファイル名:sw-ex4.py)
    ヒント:
    ledonoff(n)やledreset()のような関数を作成し、それぞれのボタンが押されると関数を実行するようにする。
    checksw(sw)のような関数を作成し、引数で与えられたスイッチを5ms程度の間隔で最低2回チェックしてチャタリングを回避するようにするのが望ましい。

Discussion