いっぺーちゃんの いろいろやってみよ~

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() と実行します。