micropython on ESP32 でLチカ
ということで、定番のLチカ
GPIO端子(下の例ではIO22とIO23)にLEDと電流制限用抵抗を接続しておきます。
Active HighでもActive LowでもOK(点滅するので、どっちになってても分からない)。
以下のプログラムを実行すると、LEDがそれぞれの周期で点滅します。
import sys platform = sys.platform # platform : ESP32 => 'esp32' # Linux => 'linux' if platform == 'linux': raise ValueError("Linux not support GPIO") import machine # 現在のpinレベルを反転して出力 def pin_toggle(p) : cur_data = p.value() p.value(not cur_data) # 端子を初期化(出力モード、Low出力) pin22=machine.Pin(22, mode=machine.Pin.OUT, value=0) pin23=machine.Pin(23, mode=machine.Pin.OUT, value=0) # タイマ0用割り込みハンドラ def int_handler_timer0(t): # t はタイマのインスタンスが入っている pin_toggle(pin22) # タイマ1用割り込みハンドラ def int_handler_timer1(t): # t はタイマのインスタンスが入っている pin_toggle(pin23) # タイマ0の設定 t0 = machine.Timer(0) # タイマは0~3が指定可能 t0.init(period=1300, mode=machine.Timer.PERIODIC, callback=int_handler_timer0) # タイマ1の設定 t1 = machine.Timer(1) t1.init(period=1000, mode=machine.Timer.PERIODIC, callback=int_handler_timer1)
プログラムを実行するには、ESP32を接続したシリアルコンソールで1文字ずつ入力するか、CTRL+Eでペーストモードにして(プロンプトが===に変わる)、ソースをコピペし、CTRL+Dで通常モードに戻すとプログラムが実行されます。
通常モードでコピペすると悲しいことになりますので注意してください。
以下解説のようなものです。
現在の実行環境をチェックします。Linux版ではGPIOを使えないのでエラー終了しています。
import sys platform = sys.platform # platform : ESP32 => 'esp32' # Linux => 'linux' if platform == 'linux': raise ValueError("Linux not support GPIO")
GPIOやタイマを使用するため、machineモジュールをインポートします。
import machine
GPIO端子の出力を反転する関数です。Espruinoのようなtoggleメソッドは用意されていないようです。
valueメソッドはパラメータなしのとき、現在の端子の値を取得します。パラメータにFalseや0を指定するとLowが、Trueや1を指定するとHighが出力されます。
def pin_toggle(p) : cur_data = p.value() p.value(not cur_data)
端子の初期化です。IO22を出力モードで、Lowレベル出力に初期化しています。
以下、説明はIO22端子側だけですが、IO23端子も同様の処理を行っています。
pin22=machine.Pin(22, mode=machine.Pin.OUT, value=0)
周期的に実行するため、タイマのcallbackを使用します。そのcallback関数です。端子を反転する処理を行っています。
関数のパラメータtには対象のタイマのインスタンスが入っていますが、特に有用な情報が入っていないので参照していません。でも書いておかないと実行時にエラー(TypeError: function takes 0 positional arguments but 1 were given)になります。
def int_handler_timer0(t): # t はタイマのインスタンスが入っている pin_toggle(pin22)
細かい話ですが、このcallback関数はハードウェアの割り込みハンドラで直接実行されるのではなく、ハードウェアの割り込みハンドラで仮想マシンの例外をアサートし、仮想マシンのコマンドループ内で例外として処理されるようです。
タイマの初期化です。
タイマは0~3が指定できます。それ以上を指定した場合は指定値を0x03でマスクした値が使用されます。つまり、4を指定すると0が、5を指定すると1が指定されたものとみなします。
modeにmachine.Timer.PERIODICを指定することでperiodicで指定した時間(msec)間隔でcallbackで指定した関数が実行されます。
modeにmachine.Timer.ONE_SHOTを指定すると、 periodicで指定した時間(msec)後に1回だけcallbackで指定した関数が実行されます。
t0 = machine.Timer(0) # タイマは0~3が指定可能 t0.init(period=1300, mode=machine.Timer.PERIODIC, callback=int_handler_timer0)
タイマを停止するときは t0.deinit() と実行します。