はじめに
RaspberryPi Picoで、GPIOの割り込み(ハードウェア割り込み)を使う方法を解説します。回路はタクトスイッチとLED、言語はMicroPythonを使います。
入力信号を確認する際、入力をループで確認する「ポーリング処理」をよく使いますが、読み込みの間に信号が来た場合の「取りこぼし」が不安になります。
今回解説する「GPIOの割り込み」を使うと、取りこぼしの心配はなくなりますし、信号が来た際の立ち上り・たち下がりのタイミングも引数の設定のみで指定できます。
今回は上記、「GPIOの割り込み」の使い方について解説します。
~ この記事の内容 / Contents ~
環境
環境 | バージョン | 備考 |
開発用PCのOS | Windows11 | Windows10でもOKです |
言語 | MicroPython | |
開発環境 Thonny | 3.3.13 | |
ボード | RaspberryPi Pico |
※ Picoのセットアップ方法については、こちらの記事をご覧ください。
RaspberryPi Picoとの接続
RaspberryPi PicoののGPIOに「タクトスイッチ」「LED」を以下のようにつなげます。
抵抗は220Ωのような小さなものでもOKです(直結防止)。LEDは足の長い方(アノード)をPico側に接続してください。
ピン番号 | 内容 | 備考 |
38 | GND | グラウンド |
36 | 3V3(OUT) | 電源(3.3V) |
25 | GP19 | タクトスイッチの入力に使います。 |
21 | GP16 | LEDの出力に使います。 |
Picoピンアサイン(Pin-Out)
※ Pico公式サイトより引用
使用する部品
今回の回路では、以下のものを使用します。
ブレッドボード
国内サンハヤト製のブレッドボードです。少々堅めの指し心地ですが、海外製と違ってピン穴の番号がすべて印刷されており、品質も高いのでおすすめです。
タクトスイッチ
ブレッドボードで使えるものであればOKです。
抵抗
お手持ちのものでOKです。ない方は一度セットで揃えてしまうと送料と時間が節約できます。
プログラム概要
今回のプログラムの概要は以下の通りです。
- タクトスイッチが押されたら、割り込み処理を行う。
- 割り込みでフラグが立ったら、LEDを0.5秒間つける
実行結果
後述するプログラムの実行結果です。タクトスイッチが押されると割り込みが発生し、LEDが点灯します。
全体コード
全体コードは以下の通りです。詳細な内容は後述する「コードのポイント」で解説します。
from machine import Pin
import _thread, time, micropython
# 割り込み処理中の例外を作成するための設定です
micropython.alloc_emergency_exception_buf(100)
#
# 割り込み処理用に登録する関数です。
#
def DetectInput( pin ):
# detectTactSw をグローバル指定します
global detectTactSw
# 検知フラグをTrueにします。
detectTactSw = True
# タクトスイッチ(入力)用のピンを設定します
tactSw = machine.Pin(19, machine.Pin.IN, machine.Pin.PULL_DOWN)
# Led(出力)の設定です。
Led = machine.Pin(16, machine.Pin.OUT)
# タクトスイッチの検知のフラグです
detectTactSw = False
# タクトスイッチの割り込み処理を設定します。
tactSw.irq(trigger=Pin.IRQ_RISING, handler=DetectInput)
#
# メイン処理
#
while(True):
#
# 割り込み処理でタクトスイッチが検知された場合
#
if detectTactSw == True:
# フラグを書き換える前に割り込みを止めます
state = machine.disable_irq()
detectTactSw = False
# 書き換え後に割り込みを再開します。
machine.enable_irq(state)
# LEDを0.5秒点灯します
Led.value(1)
time.sleep(0.5)
Led.value(0)
else:
print("タクトスイッチ検知なし")
time.sleep(1)
Pico/Pico Wだけ(PCなし)でプログラムを実行する場合は、ファイル名を「main.py」にして、Pico/Pico W本体に保存してください。
コードのポイント
例外用の容量確保
割り込み処理内で例外が発生した場合、デフォルトでは情報が少ないので、デバッグが大変です。以下のコードで例外用のバッファを設定しておくと、例外時の情報が多くなるのでデバッグが楽になります。
# 割り込み処理中の例外を作成するめの設定です
micropython.alloc_emergency_exception_buf(100)
GPIOピンに割り込み処理をつける
GPIOピンに、ポート番号や、入出力、プルアップの設定をしたあと、irq関数で割り込みの設定を行います。引数には、割り込みタイミング(トリガ)、割り込み処理用の関数名を指定します。
IRQ: Interrupt ReQuest
# タクトスイッチ(入力)用のピンを設定します
tactSw = machine.Pin(19, machine.Pin.IN, machine.Pin.PULL_DOWN)
# Led(出力)の設定です。
Led = machine.Pin(16, machine.Pin.OUT)
# タクトスイッチの検知のフラグです
detectTactSw = False
# タクトスイッチの割り込み処理を設定します。
tactSw.irq(trigger=Pin.IRQ_RISING, handler=DetectInput)
関数はirq関数の設定より前(上の行)に書いてください。irq関数よりも後に書くと関数が定義されていない。としてエラーになってしまいます。
トリガーの指定
triggerには以下を指定することができます。
trigger名 | 割り込み生成タイミング |
IRQ_FALLING | 立ち上がりエッジ(入力用) |
IRQ_RAISING | 立ち下がりエッジ(入力用) |
IRQ_LOW_LEVEL | ローレベル(出力用) |
IRQ_HIGH_LEVEL | ハイレベル(出力用) |
※ 以下のMicroPythonのリファレンスから引用しています。
https://micropython-docs-ja.readthedocs.io/ja/latest/library/machine.Pin.html
割り込み処理は短く
割り込み処理としてirq関数に登録する関数です。メイン処理と共有するフラグをグローバル変数に指定し、フラグを書き換えます。
割り込み処理中は、メインの処理が「停止」するため、割り込み処理はできるだけ短時間で終わる処理にします。
#
# 割り込み処理用に登録する関数です。
#
def DetectInput( pin ):
# detectTactSw をグローバル指定します
global detectTactSw
# 検知フラグをTrueにします。
detectTactSw = True
sleepはもちろん、printも実は重い(時間のかかる)処理なので、デバッグの時以外の使用は厳禁です。
Pico/Pico W だけ(PCなし)でプログラムを実行したい場合は「main.py」というファイル名で、Picoにファイルを保存してください。
割り込みを停止する
割り込み処理と共有しているフラグを書き換える際、割り込みを停止しないと、フラグを書き換えている「最中」に割り込みが発生する可能性があり、「FalseにしたのにTrueのまま」のような挙動になってしまいます。
そのため、割り込み処理と共有する変数等へのアクセス(クリティカルセクション)を行う際は、割り込み停止による排他制御(≒ロック)を行うと安全です。
なお、sleepや信号の送受信処理では、内部的に割り込みを使用しているものもあり、割り込み停止によりフリーズ等が発生する場合もあります。そのため、クリティカルセクションは「共有データの書き換え処理のみ」に限定します。
#
# 割り込み処理でタクトスイッチが検知された場合
#
if detectTactSw == True:
# フラグを書き換える前に割り込みを止めます
state = machine.disable_irq()
detectTactSw = False
# 書き換え後に割り込みを再開します。
machine.enable_irq(state)
# LEDを0.5秒点灯します
Led.value(1)
time.sleep(0.5)
Led.value(0)
まとめ
RaspberryPi Picoで、GPIOの割り込み処理をする方法について解説しました。
「処理内容は短く」「停止はピンポイントで」など、お約束ごともありますが、信号入力を効率的で簡単に処理できる便利な機能です。
使っていくと排他制御などの、一歩進んだプログラミングの知識を身に着けることもできるので、是非積極的に使っていただけたらうれしいです。
お知らせ
MicroPythonのプログラミングガイドブックが遂に発売!
「MicroPython」の本が遂にでました。
この一冊で、MicroPythonの言語仕様から、プログラミングの仕方まで”ガッツリ”学べます!。
内容は、普段別言語で開発している人や、これからマイコンを始める(工学系の)学生を対象としているので「初心者向け」ではありません。しかし、「自前のライブラリの作成」が目標なので、これ一冊で「ガッツリ」とMicroPythonを学ぶことができます。
全ての内容はここでは紹介しきれないので、詳細は以下のAmazonページをご覧ください。目次だけでも”ガッツリ”なのが確認できると思います。
Pico/Pico W関連のおすすめ本
RaspberryPi Pico / Pico W関連のおすすめ本を独断と偏見で3つ選んでみました。Picoやるならとりあえずこれ買っとけ的な本や、電子工作全般で使える本などを厳選しています。
お知らせ
MicroPythonのプログラミングガイドブックが遂に発売!
「MicroPython」の本が遂にでました。
この一冊で、MicroPythonの言語仕様から、プログラミングの仕方まで”ガッツリ”学べます!。
内容は、普段別言語で開発している人や、これからマイコンを始める(工学系の)学生を対象としているので「初心者向け」ではありません。しかし、「自前のライブラリの作成」が目標なので、これ一冊で「ガッツリ」とMicroPythonを学ぶことができます。
全ての内容はここでは紹介しきれないので、詳細は以下のAmazonページをご覧ください。目次だけでも”ガッツリ”なのが確認できると思います。
Pico/Pico W関連のおすすめ本
RaspberryPi Pico / Pico W関連のおすすめ本を独断と偏見で3つ選んでみました。Picoやるならとりあえずこれ買っとけ的な本や、電子工作全般で使える本などを厳選しています。
質問・要望 大歓迎です
「こんな解説記事作って」「こんなことがしたいけど、〇〇で困ってる」など、コメント欄で教えてください。 質問・要望に、中の人ができる限り対応します。
使えたよ・設定できたよの一言コメントも大歓迎。気軽に足跡を残してみてください。記事を紹介したい方はブログ、SNSにバシバシ貼ってもらってOKです。