この記事でわかること
ラズパイPicoW(Raspberry Pi Pico W)の汎用入出力(GPIO)に、LEDとタクトスイッチを接続し、タクトスイッチを押すごとに、LEDを点滅、消灯させます。
実験準備
実験に必要な機器と部品を準備します。
機器
「ラズパイPicoWを始めよう。」記事で書きましたラズパイPicoWと、統合開発環境ThonnyとMicroPythonファームウェアをインストールしたRaspi4Bを準備します。
部品
「ラズパイPicoW:デジタル出力でLED点灯・消灯。」で準備した部品の他に、次の部品を追加して実験に使う部品を準備します。
部 品 名 | 規 格 | 数 量 | 取扱い店(参考) |
カーボン抵抗 | 1/4W 68KΩ | 1 | 電子工作ステーション |
タクトスイッチ | 高さ5mm | 1 | 電子工作ステーション |
機器/部品の実装とプログラミング
準備した機器と部品を実際につなぎ、MicroPythonでプログラミングを行い、タクトスイッチ押すごとに、LEDを点滅、消灯させます。
配線
ブレッドボードを使って「赤いLED」、「タクトスイッチ」、「抵抗」などをジャンパーワイヤでつなぎます。
プログラミング
Raspi4BのThonnyを起動し、次のコードを「エディタ」に入力するか、リストをコピーしてペーストします。
Thonnyの「エディタ」には直接、日本語が入力できませんので、「Text Editor」に入力後、コピー・ペーストします。
#モジュールの読み込み(インポート)
from machine import Pin, Timer
#グローバル変数 LED点滅(True)/消灯(False)フラグを設定します。
led_st = True
#GPピン28を出力とする、クラスPinのインスタンス「led」を作成します。
led = Pin(28, Pin.OUT)
#GPピン27を入力とする、クラスPinのインスタンス「sw」を作成します。
sw = Pin(27, Pin.IN)
#LEDの点滅用のタイマーとして、クラスTimerのインスタンス「tim」を作成します。
tim = Timer()
#タクトスイッチが押された後、チャタリングを吸収するタイマーとして、
#クラスTimerのインスタンス「tm_sht」を作成します。
tm_sht = Timer()
#LEDを点滅させる関数「blink」を定義します。
def blink(t):
#インスタンス「led」の「toggle」メソッドを呼出します。
led.toggle()
#LED点滅、消灯を選択する関数「chtrng_absrb」を定義します。
def chtrng_absrb(t1):
#グローバル変数として宣言します。
global led_st
#LEDを点滅させます。
if led_st == True:
#0.5秒ごとに関数「blink」を呼出すように、
#LEDの点滅用のタイマーを設定します。
tim.init(period=500, mode=Timer.PERIODIC, callback=blink)
led_st = False
#LEDを消灯させます。
else:
led.off()
#LEDの点滅用のタイマーを停止します。
tim.deinit()
led_st = True
#タクトスイッチの割り込みを処理する関数「itr_sw_req」を定義します。
def itr_sw_req(p):
#200ms経過後に、一回だけ「chtrng_absrb」を呼び出すように、
#チャタリングを吸収するタイマーを設定します。
tm_sht.init(period=200, mode=Timer.ONE_SHOT, callback=chtrng_absrb)
#タクトスイッチの割り込み処理を設定します。
sw.irq(trigger=Pin.IRQ_RISING, handler=itr_sw_req)
Thonnyの「F5」キーを押して、現在のスクリプトを実行します。
タクトスイッチを押すたびに、LEDが0.5秒ごとに点滅、消灯します。
確認後、Thonnyの「Ctrl + F2」キーを押して、停止します。
任意のファイル名でラズパイPicoWに保存します。(ここでは「3_3digin.py」で保存しました。)
回路の説明
ブレッドボードの配線を回路図に表すと次にようになります。
接続について
- 抵抗(R1)及びLEDに接続については、「ラズパイPicoW:デジタル出力でLED点灯・消灯。」を参照して下さい。
- 抵抗(R2)に接続されているGPピン27(32ピン)は、プログラムの設定でディジタル信号(HighまたはLow)の入力または出力を行います。(今回の実験ではタクトスイッチの状態を検出しますので入力として設定します。)
- 抵抗(R2)はプルアップ抵抗と呼ばれ、抵抗を通して電源(3V3)と信号(GPピン27)を接続し、タクトスイッチ(S1)が押されていない場合は、GPピン27をHighに引き上げて状態を安定させます。
- タクトスイッチ(S1)が押された場合は、GPピン27はGNDと接続されるためLowになります。
プルアップ抵抗を通さず、直接、電源(3V3)と信号(GPピン27)を接続すると、回路が壊れる場合がありますので注意が必要です。
タクトスイッチ(S1)が押された場合、プルアップ抵抗が無いと、電源(3V3)とGNDが直接接続され、回路が壊れる場合がありますので注意が必要です。
電気的特性と設定値
出力状態としてのGPピン28とLED(OSR5JA3Z74A同等品)の電気的特性及び電流制限抵抗(R1)の値を計算・設定については、「ラズパイPicoW:デジタル出力でLED点灯・消灯。」を参照して下さい。
▶️入力状態としてのGPピン27の電気的特性
項 目 | 表 記 | 値 | 備 考 |
Lowレベルの入力電圧 | ViL | 0V | 標準値 |
Highレベルの入力電圧 | ViH | 3.3V | 標準値 |
Lowレベルの入力電流 | IoL | 4mA(最大8mA) | 初期設定値 |
▶️プルアップ抵抗(R2)値の設定
今回の実験ではプルアップ抵抗を外付けしましたが、ラズパイPicoWはプログラムによる制御で、内部プルアップ抵抗を設定することもできます。
内部プルアップ抵抗の仕様は50KΩ~80KΩとなっていますので、68KΩの抵抗を使いました。
プログラムの説明
Thonnyを起動し、ラズパイPicoWに保存したプログラムファイル(3_3digin.py)を読み込みます。
#モジュールの読み込み(インポート)
from machine import Pin, Timer
#グローバル変数 LED点滅(True)/消灯(False)フラグを設定します。
led_st = True
#GPピン28を出力とする、クラスPinのインスタンス「led」を作成します。
led = Pin(28, Pin.OUT)
#GPピン27を入力とする、クラスPinのインスタンス「sw」を作成します。
sw = Pin(27, Pin.IN)
#LEDの点滅用のタイマーとして、クラスTimerのインスタンス「tim」を作成します。
tim = Timer()
#タクトスイッチが押された後、チャタリングを吸収するタイマーとして、
#クラスTimerのインスタンス「tm_sht」を作成します。
tm_sht = Timer()
#LEDを点滅させる関数「blink」を定義します。
def blink(t):
#インスタンス「led」の「toggle」メソッドを呼出します。
led.toggle()
#LED点滅、消灯を選択する関数「chtrng_absrb」を定義します。
def chtrng_absrb(t1):
#グローバル変数として宣言します。
global led_st
#LEDを点滅させます。
if led_st == True:
#0.5秒ごとに関数「blink」を呼出すように、
#LEDの点滅用のタイマーを設定します。
tim.init(period=500, mode=Timer.PERIODIC, callback=blink)
led_st = False
#LEDを消灯させます。
else:
led.off()
#LEDの点滅用のタイマーを停止します。
tim.deinit()
led_st = True
#タクトスイッチの割り込みを処理する関数「itr_sw_req」を定義します。
def itr_sw_req(p):
#200ms経過後に、一回だけ「chtrng_absrb」を呼び出すように、
#チャタリングを吸収するタイマーを設定します。
tm_sht.init(period=200, mode=Timer.ONE_SHOT, callback=chtrng_absrb)
#タクトスイッチの割り込み処理を設定します。
sw.irq(trigger=Pin.IRQ_RISING, handler=itr_sw_req)
プログラム全体の流れ
「スイッチでデジタル入力」プログラムは次の処理を行います。
実装順 | 流 れ | 説 明 |
GPピン番号と状態の設定 | ** | LEDを点滅、消灯させるGPピン番号と、タクトスイッチの状態を検出するGPピン番号を設定します。 |
LEDのGPピンは出力を、タクトスイッチのGPピンは入力に設定します。 | ||
タイマーの設定 | ** | LEDの点滅用のタイマーを設定します。 |
タクトスイッチが押された後、チャタリング時間を吸収するタイマーを設定します。 | ||
LEDを点滅させる関数 | 4 | 0.5秒周期のLED点滅用のタイマーにより呼び出され、LEDを点滅させます。 |
LED点滅、消灯を選択する関数 | 3 | タクトスイッチの状況により、0.5秒タイマーを設定し、「LEDを点滅させる関数」を呼び出すか、LEDを消灯する関数を呼出します。 |
タクトスイッチの割り込みを処理する関数 | 2 | タクトスイッチのチャタリングにより発生した複数の割り込みを吸収するため、200msの一回限りのタイマーを設定し、「LED点滅、消灯を選択する関数」を呼び出します。 |
タクトスイッチの割り込み処理 | 1 | タクトスイッチが押された時に割り込みを発生させ、「タクトスイッチの割り込みを処理する関数」を呼び出します。 |
チャタリングとは、スイッチがオンになる時に機械的な振動によって数ms~数百msの間、オン・オフを繰り返す現象です。
モジュールの読み込み(インポート)、GPピン番号と状態の設定、タイマーの設定、LEDを点滅させる関数については、「ラズパイPicoW:デジタル出力でLED点灯・消灯。」を参照して下さい。
LED点滅、消灯を選択する関数(chtrng_absrb)
グローバル変数の「led_st」フラグがTrueの場合はLEDを点滅させ、Falseの場合はLEDを消灯させます。
LED点滅(True)/消灯(False)の判定は、「if xx:~else xx:」条件判断文で行います。
「if」文は関数の記述と同じように、ブロックを4個の半角スペース(空白)でインデント(字下げ)します。
▶️LEDを点滅させます。
if led_st == True: | |
global led_st | グローバル変数led_stを関数の中で変更できるように、global宣言します。 |
tim.init(period=500, mode=Timer.PERIODIC, callback=blink) | 0.5秒ごとに関数「LEDを点滅させる関数(blin))」を呼出すように、LEDの点滅用のタイマーを設定します。 詳細は「ラズパイPicoW:デジタル出力でLED点灯・消灯。」を参照してください。 |
led_st = False | 点滅処理が終了したので「led_st」フラグをFalseにします。 |
▶️LEDを消灯させます。
else: | |
led.off() | LEDを消灯させます。 |
tim.deinit() | LEDの点滅用のタイマーを停止します。 |
led_st = True | 消灯処理が終了したので「led_st」フラグeにします。 |
タクトスイッチの割り込みを処理する関数(itr_sw_req)
タクトスイッチのチャタリングを吸収するために、200ms経過後に、一回だけ「LED点滅、消灯を選択する関数(chtrng_absrb)」を呼び出すように、チャタリングを吸収するタイマーを設定します。
tm_sht.init(period=200, mode=Timer.ONE_SHOT, callback=chtrng_absrb) | |
tm_sht.init | 「init」メソッドで、チャタリングを吸収するタイマーを初期化します。 |
period=200 | タイマー期間をミリ秒単位で設定します。(ここでは200msを設定しています。) タイマーの周波数単位(Hz)で設定しする場合は「freq」を使います。 |
mode=Timer.ONE_SHOT | タイマーの実行方法を設定します。 ・mode=Timer.PERIODIC:タイマーは、設定した周期で定期的に実行します。 ・mode=Timer.ONE_SHO:タイマーは、設定した周期が経過した後に1回だけ実行します。 |
callback=chtrng_absrb | タイマー期間が終了したときに呼び出されるコールバック関数を設定します。(ここではchtrng_absrbを設定しています。) |
タクトスイッチの割り込み処理を設定
タクトスイッチが押された時に割り込みを発生させ、「タクトスイッチの割り込みを処理する関数(itr_sw_req)」を呼び出します。
タクトスイッチが押された時はチャタリングが発生しますので、割り込みも複数、発生します。
sw.irq(trigger=Pin.IRQ_RISING, handler=itr_sw_req) | |
sw.irq | クラスPinのインスタンスで指定したGPピン(ここではsw)に、割り込みが発生した時の処理を設定します。 |
trigger=Pin.IRQ_RISING | triggerは割り込みを生成する状態を設定します。 ・Pin.IRQ_FALLING :立ち下がりエッジで割り込みを生成します。 ・Pin.IRQ_RISING :立ち上がりエッジで割り込みを生成します。 ・Pin.IRQ_LOW_LEVEL :ローレベルで割り込みを生成します。 ・Pin.IRQ_HIGH_LEVEL :ハイレベルで割り込みを生成します。 |
handler=itr_sw_req | handler は割り込みが発生した時に呼び出される関数を指定します。(ここではitr_sw_reqを呼び出します。) |
まとめ
ラズパイPicoWのGPピンにタクトスイッチを入力として接続し、タクトスイッチを押すごとに、LEDを点滅、消灯させました。
グローバル変数とif xx:~else xx:文の使い方を学びました。
タクトスイッチを押した時に発生する割り込みの設定方法と、タイマーでチャタリングを吸収する方法を学びました。