micropython on ESP32 でぽちっとな
またまた定番のボタンをぽちっと押してみます。
GPIO端子(下の例ではIO21)にpull-up抵抗とスイッチを接続し、Active Lowな入力にします。
以下のプログラムを実行すると、スイッチを押したり放したりすると「ぽちっとな~」とか「はなしたでー」とか表示されます。
。。。ん?そうです、micropythonは日本語が使えるんです。
ということで、シリアルコンソールの日本語モードは「UTF-8」に設定しておいてください。gtktermはUTF-8のみ対応のようなので、これを使う場合は特に設定不要です。
また、コンソール上で通常モード時は日本語入力ができないので、CTRL+Eでペーストモードにしてからコピペし、CTRL-Dで通常モードに戻してください。
import sys platform = sys.platform # platform : ESP32 => 'esp32' # Linux => 'linux' if platform == 'linux': raise ValueError("Linux not support GPIO") import machine import utime # 前回の割り込み受付時刻 pin21_prev_time = utime.ticks_ms() # PIN21の割り込みハンドラ def int_handler_gpio21(p): global pin21_prev_time cur_time = utime.ticks_ms() if cur_time < pin21_prev_time + 100 : # 前回受付から100msec未満だったらチャタリングと判断してスキップ return # 前回の割り込み受付時刻を更新 pin21_prev_time = cur_time # 現在のpinレベル cur_data = p.value() # 現在のpinレベルをスイッチ状態の文字列に変換(active LOWなのでTrueのとき"OFF") message = 'はなしたでー' if cur_data else 'ぽちっとな~' # active LOW print(message) # PIN21を入力モードに設定 pin21=machine.Pin(21, machine.Pin.IN) # int_handler_gpio21 を PIN21の割り込みハンドラに設定(両エッジ) pin21.irq(trigger=machine.Pin.IRQ_RISING | machine.Pin.IRQ_FALLING, handler=int_handler_gpio21)
以下解説。
最初の方は前回と同じです。
時刻関連の処理を行うため、utimeモジュールをインポートします。今回は相対時間だけ欲しいので、時刻合わせは不要です。
import utime # 前回の割り込み受付時刻 pin21_prev_time = utime.ticks_ms()
割り込み発生間隔を測るための時刻ですが、最初に1回読み込んでおきます。
端子の入力レベルが変化したときに実行されるcallback関数です。関数のパラメータpには対象の端子のインスタンスが入っています。これを使えば複数の端子に同じcallback関数を割り当てる、という使い方も可能です。
# PIN21の割り込みハンドラ def int_handler_gpio21(p): ....
Espruinoではチャタリング除去時間を設定できましたが、micropythonではそのような機能がありません。そこで、現在の時刻とcallback関数が前回実行された時刻の差が100msec以下だったらチャタリングとみなして何も処理せずに終了します。100msecが妥当かどうかは検証する必要があるでしょう。
global pin21_prev_time cur_time = utime.ticks_ms() if cur_time < pin21_prev_time + 100 : # 前回受付から100msec未満だったらチャタリングと判断してスキップ return # 前回の割り込み受付時刻を更新 pin21_prev_time = cur_time
現在の端子レベルを読み込んで、Lowレベルだったら「ぽちっとな~」、Highレベルだったら「はなしたでー」を表示します。Active Lowのスイッチなので、こうなっています。Active Highのスイッチの場合は文字列を逆にしてください。(このコードだとチャタリングの発生タイミングによっては正常な値が読めるとは限らないんだよなぁーー。細かいことは目をつぶってください。)
# 現在のpinレベル cur_data = p.value() # 現在のpinレベルをスイッチ状態の文字列に変換(active LOWなのでTrueのとき"OFF") message = 'はなしたでー' if cur_data else 'ぽちっとな~' # active LOW print(message)
messageを設定している部分はCで言う三項演算子です。ちょっとわかりにくいですね。
Cで書くとこんな感じかな。
message = cur_data ? "はなしたでー" : "ぽちっとな~"
使用する端子を入力モードに設定します。
pin21=machine.Pin(21, machine.Pin.IN)
端子の割り込み処理を登録します。
triggerでIRQ_RISING(立ち上がり)とIRQ_FALLING(立ち下り)を指定しているので両エッジでcallback関数が実行されます。
pin21.irq(trigger=machine.Pin.IRQ_RISING | machine.Pin.IRQ_FALLING, handler=int_handler_gpio21)