はじめに
RaspberryPi Picoで、GPIOの割り込み処理をする方法を解説します。回路はシンプルにLED2つ、言語はMicroPythonを使います。
一定時間で同じ処理を行いたい場合、ループとスリープを使う方法がありますが、コードが複雑になりがちです。しかし今回解説する「タイマー割り込み」を使えば、シンプルに記載することができます。
今回は上記「タイマー割り込み」の使用方法を解説します。
~ この記事の内容 / Contents ~
環境
この記事は以下の環境で作成しています。
環境 | バージョンなど | 備考 |
開発用PCのOS | Windows11 | Windows10でもOKです |
言語 | MicroPython | |
開発環境 Thonny | 3.3.13 | |
ボード | RaspberryPi Pico |
RaspberryPi Picoとの接続
RaspberryPi PicoののGPIOに、LEDを2つつなげます。抵抗は1kΩを使用していますが、直結を防止しているだけなので、220Ωなどの小さいものでも構いません。LEDは足の長い方(アノード)をPico側に接続してください。
ピン番号 | 内容 | 備考 |
38 | GND | グラウンド |
36 | 3V3(OUT) | 電源(3.3V) |
22 | GP17 | 点灯用のLEDに使います |
21 | GP16 | 点滅用のLEDに使います |
Picoピンアサイン(Pin-Out)
※ Pico公式サイトより引用
使用する部品
今回は以下のものを使用します。
RaspberryPi Pico
Pico本体です。半導体不足でも価格・納期とも安定して手に入ります。
ブレッドボード
国内サンハヤト製のブレッドボードです。少々堅めの指し心地ですが、海外製と違ってピン穴の番号がすべて印刷されており、品質も高いのでおすすめです。
LED
抵抗
お手持ちのものでOKです。ない方は一度セットで揃えてしまうと送料と時間が節約できます。
プログラム概要
今回のプログラムの概要は以下の通りです。
- タイマーを作成する。
- タイマーを使って、LEDを点滅・点灯させる。
実行結果
後述するプログラムを実行すると、点滅用のLEDが1秒周期で点滅、3秒経過後に点灯用のLEDが点灯します。
全体コード
全体コードは以下の通りです。詳細な内容は後述する「コードのポイント」で解説します。
from machine import Pin, Timer
import micropython,time
# 割り込み処理中の例外を作成するための設定です
micropython.alloc_emergency_exception_buf(100)
# Ledに使うピンを定義・初期化します。
blink = machine.Pin(16, machine.Pin.OUT)
light = machine.Pin(17, machine.Pin.OUT)
# タイマーを作成します
blinkTimer = Timer()
oneShotTimer = Timer()
#
# LEDを点滅させる関数です
#
def blinkFunc(timer):
# 関数の外で定義したピンを参照します
global blink
# LEDの状態を確認して、反転させます
if blink.value() == 0 :
blink.value(1) # 点灯
else:
blink.value(0) # 消灯
#
# LEDを点灯させる関数です
#
def oneShotFunc(timer):
# 関数の外で定義したピンを参照します
global light
light.value(1) # 点灯
# LEDを消灯で初期化します。
blink.value(0)
light.value(0)
# 周期的に実行(周波数指定)
blinkTimer.init(mode=Timer.PERIODIC, freq=1, callback=blinkFunc)
# 周期的に実行(ミリ秒指定)
#blinkTimer.init(period=1000, callback=blinkFunc )
# 3000ms 後に1度だけ実行
oneShotTimer.init(mode=Timer.ONE_SHOT, period=3000, callback=oneShotFunc)
#
# メイン処理です。
# タイマーは自動で呼ばれるので、何もする必要がありません。
#
print ("タイマーを開始しました")
コードのポイント
例外用の容量確保
割り込み処理内で例外が発生した場合、デフォルトでは情報が少ないので、デバッグが大変になります。以下のコードで例外用のバッファを設定しておくと、例外時の情報が多くなるのでデバッグが楽になります。
# 割り込み処理中の例外を作成するための設定です
micropython.alloc_emergency_exception_buf(100)
LEDの初期化
LEDに使うピン(GP16,GP17)を出力用のピンとして設定します。
# Ledに使うピンを定義・初期化します。
blink = machine.Pin(16, machine.Pin.OUT)
light = machine.Pin(17, machine.Pin.OUT)
タイマーを作成
点滅用と点灯用で2つのタイマーを作成します。
作成後、init関数で「モード設定」「周期」「呼び出し用の関数」を設定します。
init関数を実行すると、タイマーが開始され、設定間隔に従って自動的に関数が実行されます。基本的にメインループ等で処理をする必要はありません。
モード設定、周期の詳細は後述の表で説明します。
# タイマーを作成します
blinkTimer = Timer()
oneShotTimer = Timer()
#
# ~~~~~ 中略 ~~~~~
#
# 周期的に実行(周波数指定)
blinkTimer.init(mode=Timer.PERIODIC, freq=1, callback=blinkFunc)
# 周期的に実行(ミリ秒指定)
#blinkTimer.init(period=1000, callback=blinkFunc )
# 3000ms 後に1度だけ実行
oneShotTimer.init(mode=Timer.ONE_SHOT, period=3000, callback=oneShotFunc)
関数はタイマー初期化の前(上の行)に書いてください。初期化よりも後に書くと関数が定義されていない。としてエラーになります。
モードの詳細
モード | 動作 |
ONE_SHOT | 一度のみタイマーを実行 |
PERIODIC | 毎周期タイマーを実行 |
周期の詳細
周期 | 動作 |
freq | 周波数(Hz)で実行間隔を指定。 |
period | 時間指定(ミリ秒)で実行間隔を指定。 |
※両方指定した場合は「freq」が優先されます。
タイマー処理・メイン処理
タイマーに設定する、点滅・点灯用の関数です。関数外のピンを参照するため、globalを付けます。
解説するコードでは、シンプル化のためにメインの部分に何も書いていませんが、メイン部分に処理を記載してももちろんOKです。
※呼び出し用の関数には引数がないとエラーになるため、記載してきますが、関数内では使用していません。
#
# LEDを点滅させる関数です
#
def blinkFunc(timer):
# 関数の外で定義したピンを参照します
global blink
# LEDの状態を確認して、反転させます
if blink.value() == 0 :
blink.value(1) # 点灯
else:
blink.value(0) # 消灯
#
# LEDを点灯させる関数です
#
def oneShotFunc(timer):
# 関数の外で定義したピンを参照します
global light
light.value(1) # 点灯
# ~~~~~ 中略 ~~~~~
#
# メイン処理です。
# タイマーは自動で呼ばれるので、何もする必要がありません。
#
print ("タイマーを開始しました")
まとめ
RaspberryPi Pico でタイマー割り込みをする方法を解説しました。
ループ・スリープの組み合わせでも同様の処理は出来ますが、タイマーを使うとよりシンプルに書けて、デバッグや拡張が楽になります。簡単に使えるので、みんさんもぜひ使ってみてください。参考になればうれしいです。
お知らせ
MicroPythonのプログラミングガイドブックが遂に発売!
「MicroPython」の本が遂にでました。
この一冊で、MicroPythonの言語仕様から、プログラミングの仕方まで”ガッツリ”学べます!。
内容は、普段別言語で開発している人や、これからマイコンを始める(工学系の)学生を対象としているので「初心者向け」ではありません。しかし、「自前のライブラリの作成」が目標なので、これ一冊で「ガッツリ」とMicroPythonを学ぶことができます。
全ての内容はここでは紹介しきれないので、詳細は以下のAmazonページをご覧ください。目次だけでも”ガッツリ”なのが確認できると思います。
Pico/Pico W関連のおすすめ本
RaspberryPi Pico / Pico W関連のおすすめ本を独断と偏見で3つ選んでみました。Picoやるならとりあえずこれ買っとけ的な本や、電子工作全般で使える本などを厳選しています。
質問・要望 大歓迎です
「こんな解説記事作って」「こんなことがしたいけど、〇〇で困ってる」など、コメント欄で教えてください。 質問・要望に、中の人ができる限り対応します。
使えたよ・設定できたよの一言コメントも大歓迎。気軽に足跡を残してみてください。記事を紹介したい方はブログ、SNSにバシバシ貼ってもらってOKです。