Raspberry Pi 5がリリースされ、より強力な Pi が導入されましたが、いくつかの点も変更されており、最も注目すべきは GPIO です。
40ピンGPIOは変わりませんが、新しいRP1サウスブリッジチップに接続されているため、動作が少し異なります。なぜこれが重要なのでしょうか?結局のところ、GPIOを操作するコードの書き方の問題です。かつては多くのプロジェクトでRPi.GPIOが好まれていました。これはBen Croston氏によるコミュニティプロジェクトで、複数世代のRaspberry Piでうまく機能していました。しかし、Raspberry Pi 5では、GPIOピンのメモリマップ方法によりRPi.GPIOを使用できなくなりました。そのため、代替手段を使う必要があり、このチュートリアルではlibgpiodに焦点を当てます。
gpiodを使って、とてもシンプルなプロジェクトを2つ作成します。1つ目は出力(LED)です。2つ目は入力(LEDの点灯・消灯をトリガーするボタン)です。
これらのプロジェクトに必要なのは
- ラズベリーパイ5
- ブレッドボード
- オス-メスのジャンパーワイヤー4本
- LED 1個
- 100オーム抵抗器(茶-黒-茶-金)
- プッシュボタン
プロジェクト1: 出力、LEDの点滅
言語やフレームワークを学ぶ際の最初の目標は、「Hello World」プログラムを作成することです。ハードウェア、ハッキング、エレクトロニクスの世界では、これは点滅するLEDのようなものです。
回路は非常にシンプルです。LEDの長い脚(アノード)をジャンパー線でGPIO 17に接続します。短い脚(カソード)は抵抗器と別のジャンパー線を介してGNDに接続します。抵抗器の値は100~330Ω(オレンジ-オレンジ-茶-金)の範囲で任意に設定できます。詳しくは抵抗器リファレンスガイドをご覧ください。
1. Thonnyを開き、2つのコードモジュールをインポートします。1つ目はgpiodで、GPIOの制御と読み取りに使用します。2つ目はtimeで、コードに一時停止を追加するために使用します。
Tom's Hardware の最高のニュースと詳細なレビューをあなたの受信箱に直接お届けします。
import gpiod
import time
2. LED_PINという変数を作成し、値17を格納します。この変数には、Raspberry Piの全モデルのGPIOピンに対応するBroadcomピンリファレンスが格納されます。Broadcomピンリファレンスは、Raspberry Piのすべてのドキュメントで使用されている標準規格です。SoCからGPIOへのブレークアウトを使用しています。私たちには論理的に見えないかもしれませんが、ボードを開発するエンジニアにとっては、ピンのブレークアウトは正しく行われています。
LED_PIN = 17
3.コードにGPIOの場所を指示します。Raspberry Piには元々、メモリにマッピングされたgpiomemデバイスが1つしかなく、RPi.GPIOなどのPythonモジュールで使用できました。Raspberry Pi 5とRP1チップでは、デバイスが動的に分割され、GPIOはgpiomem4にあります。
chip = gpiod.Chip('gpiochip4')
4. led_lineという変数を作成し、LEDのGPIOピンへの参照を保存します。gpiodモジュールは、linesを使ってGPIOピンを参照します。
led_line = chip.get_line(LED_PIN)
5. LEDを出力として設定します。LEDに電流を流します。
led_line.request(consumer="LED", type=gpiod.LINE_REQ_DIR_OUT)
6.コードの本体をtryとwhile Trueループで囲みます。tryは例外ハンドラーの一部で、コードの実行を試みます。例外を処理し、終了時にコードの一部を実行します。
try: while True:
7. LEDを点灯させてから1秒間待ちます。これにより、LEDは1秒間点灯した状態になります。
led_line.set_value(1) time.sleep(1)
8. LEDをオフにして1秒間待ちます。スリープモードにより、LEDは1秒間オフのままになります。
led_line.set_value(0) time.sleep(1) # Sleep for one second
9.コード終了時にGPIOをクリーンアップするコードセクションを追加します。GPIO Zeroではこの処理は必要ありませんが、gpiod(および古いRPi.GPIO)では終了前にクリーンアップする必要があります。
finally: led_line.release()
10.コードをblinky.pyとして保存し、「実行」をクリックして開始します。GPIO 17のLEDが1秒ごとに点滅します。終了するには、Ctrl + Cを押すか、「停止」をクリックしてください。
プロジェクト1: 完全なコードリスト
import gpiod
import time
LED_PIN = 17
chip = gpiod.Chip('gpiochip4')
led_line = chip.get_line(LED_PIN)
led_line.request(consumer="LED", type=gpiod.LINE_REQ_DIR_OUT)
try: while True: led_line.set_value(1) time.sleep(1) led_line.set_value(0) time.sleep(1)
finally:
led_line.release()
プロジェクト2: 入力、ユーザー入力への反応
「Hello World」の後、次の目標は入力を作成することです。この例ではボタンを作成し、片側をボタンGPIOピンに、もう片側を3V3に接続します。ボタンGPIOピンのデフォルトの状態は電源なし(0、False、Low)ですが、ボタンを押すと3V3ピンをボタンGPIOピンに接続し、状態を電源あり(1、True、High)に変更します。コードはこの状態の変化を検出し、それに応じて反応します。必要なのはボタンと2本のジャンパー線だけです。
1. Thonnyを開き、2つのコードモジュールをインポートします。1つ目はgpiodで、GPIOの制御と読み取りに使用します。2つ目はtimeで、コードに一時停止を追加するために使用します。
import gpiod
import time
2. LED_PINという変数を作成し、値17を格納します。この変数には、Raspberry Piの全モデルのGPIOピンに対応するBroadcomピンリファレンスが格納されます。Broadcomピンリファレンスは、Raspberry Piのすべてのドキュメントで使用されている標準規格です。SoCからGPIOへのブレークアウトを使用しています。私たちには論理的に見えないかもしれませんが、ボードを開発するエンジニアにとっては、ピンのブレークアウトは正しく行われています。
LED_PIN = 17
3. BUTTON_PINという変数を作成し、そこに値27を格納します。GPIO 27はGPIO 17のすぐ隣にあります。
BUTTON_PIN = 27
4.コードにGPIOの場所を指定します。Raspberry Piには元々、メモリにマッピングされたgpiomemデバイスが1つしかなく、RPi.GPIOなどのPythonモジュールで使用できました。Raspberry Pi 5とRP1チップでは、デバイスが動的に分割され、GPIOはgpiomem4にあります。
chip = gpiod.Chip('gpiochip4')
5. led_lineという変数を作成し、LED GPIOピンへの参照を保存します。gpiodモジュールは、linesを使用してGPIOピンを参照します。
led_line = chip.get_line(LED_PIN)
6. button_line という変数を作成し、ボタン GPIO ピンへの参照を保存します。
button_line = chip.get_line(BUTTON_PIN)
7. LEDを出力として設定します。LEDに電流を流します。
led_line.request(consumer="LED", type=gpiod.LINE_REQ_DIR_OUT)
8.ボタンを入力として設定します。
button_line.request(consumer="Button", type=gpiod.LINE_REQ_DIR_IN)
9.コードの本体をtryとwhile Trueループで囲みます。tryは例外ハンドラの一部で、コードの実行を試みます。例外を処理し、終了時にコードの一部を実行します。
try: while True:
10.ボタン GPIO ピンの現在のステータスを取得し、button_state という変数に保存します。
button_state = button_line.get_value()
11. if文を使ってボタンが押されたかどうかを確認します。押された場合はLEDを点灯します。ボタンGPIOピンのデフォルト状態はロー(0, False)です。しかし、ボタンが押されたときは、Raspberry Pi 5の3VピンをボタンGPIOピンに接続します。これにより、ボタンピンはハイ(1, True)になります。この状態変化がコードのトリガーとなります。
if button_state == 1: # Button is pressed led_line.set_value(1) # Turn the LED on
12. else 条件を使用して、ボタンが押されていないときに LED をオフにします。
else: led_line.set_value(0) # Turn the LED off
13.コード終了時にGPIOをクリーンアップするコードセクションを追加します。GPIO Zeroではこの処理は必要ありませんが、gpiod(および古いRPi.GPIO)では終了前にクリーンアップする必要があります。
finally: led_line.release() button_line.release()
14.コードをbutton-press.pyとして保存し、「実行」をクリックして開始します。ボタンを押すとLEDが点灯し、離すと消灯します。 終了するには、Ctrl + Cを押すか、「停止」をクリックします。
プロジェクト2: 完全なコードリスト
import gpiod
LED_PIN = 17
BUTTON_PIN = 27
chip = gpiod.Chip('gpiochip4')
led_line = chip.get_line(LED_PIN)
button_line = chip.get_line(BUTTON_PIN)
led_line.request(consumer="LED", type=gpiod.LINE_REQ_DIR_OUT)
button_line.request(consumer="Button", type=gpiod.LINE_REQ_DIR_IN)
try: while True: button_state = button_line.get_value() if button_state == 1: led_line.set_value(1) else: led_line.set_value(0)
finally: led_line.release()
button_line.release()