ラズベリーパイのGPIO応答速度を測定(Python編)
Raspberry Pi 2 Model B(古い!!!)を昔ちょっと使ってほったらかしになっていたのですが、これのGPIO応答速度を測定してみました。
Windowsなんかだとmsオーダー、下手をすれば数10msオーダーなのでリアルタイム処理にはほぼ使えませんが、Linuxならもう少しは速いんだろうな、と思い実力の程を確かめてみました。
ラズベリーパイの準備
前に使っていたmicro SDカードは8GBでFullが8.6GB必要なため入らずLiteでもいいのですが今後も使うことがあるだろうと思い、Extreme PRO 32GBを購入してみました
Raspberry Pi ImagerでRaspberry PI OSをSDカードにインストール後、Raspberry Piにモニター、キーボードを挿して起動して、初期設定とupdateをして(updateはとりあえず必須ではないですが)、”sudo raspi-config”で設定ツールを開き、sshとリモートGPIOをEnableにして下準備完了です。
以降はssh接続でやります(ラズベリーパイにつなげるキーボードやマウスが不要になるので)。
1 |
PS C:\Users\xxx> ssh pi@raspberrypi.local |
上記のコマンドを入力後、パスワードを入れて(初期値のままならraspberry)ログインします。私はWindows10からやっているのでVSCode上のターミナル(Power Shell)がらやっています。
ラズベリーパイのGPIO操作
GPIOの制御はPythonでやることにします。
PythonでのGPIO制御にはRPi.GPIOパッケージを利用すればいいようなのでネット記事を参考に以下のコードを書いてみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import RPi.GPIO as GPIO ledOut = 17 swIn = 18 ledOnOffIn = 23 GPIO.setmode(GPIO.BCM) GPIO.setup(ledOut, GPIO.OUT) GPIO.setup(swIn, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(ledOnOffIn, GPIO.IN, pull_up_down=GPIO.PUD_UP) while True: if GPIO.input(swIn): GPIO.output(ledOut,True) else: GPIO.output(ledOut,False) if False==GPIO.input(ledOnOffIn): break; GPIO.cleanup() |
BCMピン番号でGPIO18を入力(swIn)、GPIO17を出力(ledOut)、GPIO23をループ終了入力(ledOnOffIn)としました。
1 |
pi@raspberrypi:~$ python iotest.py |
でプログラムを走らせると、18ピン入力信号をそのまま17ピンに出力して、23ピンにLowを入力するとピン設定をクリアして終了します。入力ピンは内部でプルアップしているので外付けのプルアップ抵抗は不要です。
計測用 マイコンボードの準備
GPIO18への入力とGPIO17の出力の時間差計測はオシロスコープを使えば簡単ですが、会社にはあっても個人で持っていないので、マイコンボードで時間を測定するファームウェアを書いて測定してみることにしました。
マイコンボードはよく使うSTマイクロのNucleo F411を使いました。ピン配置は以下のとおりです。
P13(B1[Blue PushButton])にNucleoに実装されている青のプッシュボタンが接続されているのでこのプッシュボタンが押されるとチャタリングを取ってPC10(B1Out)にトグル信号を出すようにしています。
すなわちプッシュボタンを押すたびにPC10(B1Out)のHigh/Lowが切り替わります。
これをラズベリーパイのGPIO18(swIn)と計測用にPA0(RPiIn/インプットキャプチャTimer2 Channel1)に入れます。
ラズベリーパイのGPIO17(ledOut)出力をやはり計測用にPA1(RPiOut/インプットキャプチャーTimer2 Channel2)に入れます。
配線内容をまとめると
Nucleo F411 | Raspberry Pi | |
Nucleo上の青のプッシュボタン ↓ PC13(B1[Blue PushButton) | ||
↓ (チャタリング除去) | ||
PC10(B1Out) | → | GPIO18(swIn) |
↓ PA0(RPiIn / インプットキャプチャーTimer2 Channel1) | ↓ (ラズベリーパイ Pythonプログラムで折り返し) | |
PA1(RPiIn / インプットキャプチャーTimer2 Channel2) | ← | GPIO17(ledOut) |
となります。
ラズベリーパイのGPIOの応答速度 測定
Timer2は1/84Mz(≒12ns)単位で32bitタイマーなので2^32/84M≒51.1秒で1周するタイマーです。
インプットキャプチャーは2チャンネルとも両エッジトリガーでそれぞれ割り込みが発生した時点のTimer値をstartTime,endTimeとして記録してentTime記録時に(endTime – startTime)を秒単位に換算してresponseTimeとして記録するようにした結果が以下のとおりです。
右側の黄色にマーキングされているところが計測値でresponseTimeが約7.6usになっています。思った以上に速いので一応、会社のオシロスコープで測ってみました(結局、会社の備品を使った^^;)がやはり正しかったです(下記のオシロスコープ波形は5us/1divなので一致している)。
そうはいってもOSなので何回も測定してみると3us~10usくらいにはバラついてはいます。バラついてはいますがこの程度のバラツキが許容できる用途なら使用できそうです。
Nucleo STM32F411向け ラズベリーパイGPIO応答速度 測定プロジェクトはこちらから。
終わり