《2024年6月 更新》
Raspberry Pi 5 では pinctrl
コマンドを使う必要があります。
詳しくは、Raspberry Pi 5 におけるGPIO操作は pinctrl
を使う (raspi-gpio後継コマンド) をご覧ください。
論よりコード
raspi-gpio
コマンドを使いましょう。
$ raspi-gpio get
BANK0 (GPIO 0 to 27):
GPIO 0: level=1 fsel=0 func=INPUT
GPIO 1: level=1 fsel=0 func=INPUT
《省略》
$ raspi-gpio get 6 | awk -v RS=" " -F "=" -v k="level" '$1==k {print $2}'
1
Wiring Pi は deprecated (非推奨) です
Raspberry Pi の GPIO 操作でお世話になる「Wiring Pi」は、Bullseye ベースの Rasbpberry Pi OS のリポジトリから無くなり、インストールが失敗します。
$ sudo apt install wiringpi
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
E: Unable to locate package wiringpi
Wiring Pi は2019年に開発停止を表明しており、それがいよいよ反映された形です。
ちなみに Buster ベースの Raspberry Pi OS であれば apt install wiringpi
でインストールできますが、今後は raspi-gpio
に一本化したほうが良さそうです。
ちなみに、Bullseye ベース、Buster ベースの Rasbpberry Pi OS については 「Raspberry Pi OS」、2種類が提供へ--Buster版とBullseye版 や、 Bullseye – the new version of Raspberry Pi OS をご覧ください。
raspi-gpio コマンド
Wiring Pi が提供する gpio
コマンドの互換プロダクトは無いようです。ただ、コマンドラインツール自体は raspi-gpio
が存在しています。
raspi-gpio
は Bullseye ベース、Buster ベース、両方の Rapsberry Pi に標準インストール済みです。
以下 raspi-gpio
の help です。
$ raspi-gpio help
WARNING! raspi-gpio set writes directly to the GPIO control registers
ignoring whatever else may be using them (such as Linux drivers) -
it is designed as a debug tool, only use it if you know what you
are doing and at your own risk!
The raspi-gpio tool is designed to help hack / debug BCM283x GPIO.
Running raspi-gpio with the help argument prints this help.
raspi-gpio can get and print the state of a GPIO (or all GPIOs)
and can be used to set the function, pulls and value of a GPIO.
raspi-gpio must be run as root.
Use:
raspi-gpio get [GPIO]
OR
raspi-gpio set <GPIO> [options]
OR
raspi-gpio funcs [GPIO]
OR
raspi-gpio raw
GPIO is a comma-separated list of pin numbers or ranges (without spaces),
e.g. 4 or 18-21 or 7,9-11
Note that omitting [GPIO] from raspi-gpio get prints all GPIOs.
raspi-gpio funcs will dump all the possible GPIO alt funcions in CSV format
or if [GPIO] is specified the alternate funcs just for that specific GPIO.
Valid [options] for raspi-gpio set are:
ip set GPIO as input
op set GPIO as output
a0-a5 set GPIO to alternate function alt0-alt5
pu set GPIO in-pad pull up
pd set GPIO pin-pad pull down
pn set GPIO pull none (no pull)
dh set GPIO to drive to high (1) level (only valid if set to be an output)
dl set GPIO to drive low (0) level (only valid if set to be an output)
Examples:
raspi-gpio get Prints state of all GPIOs one per line
raspi-gpio get 20 Prints state of GPIO20
raspi-gpio get 20,21 Prints state of GPIO20 and GPIO21
raspi-gpio set 20 a5 Set GPIO20 to ALT5 function (GPCLK0)
raspi-gpio set 20 pu Enable GPIO20 ~50k in-pad pull up
raspi-gpio set 20 pd Enable GPIO20 ~50k in-pad pull down
raspi-gpio set 20 op Set GPIO20 to be an output
raspi-gpio set 20 dl Set GPIO20 to output low/zero (must already be set as an output)
raspi-gpio set 20 ip pd Set GPIO20 to input with pull down
raspi-gpio set 35 a0 pu Set GPIO35 to ALT0 function (SPI_CE1_N) with pull up
raspi-gpio set 20 op pn dh Set GPIO20 to ouput with no pull and driving high
ピンの指定方法
raspi-gpio
のピンの指定方法は BMC ピン番号です。
gpio
コマンド使えていた Wiring Pi 独自ピン番号は使えません。gpio -g ...
で指定していたピン番号であれば、そのまま raspi-gpio
の引数に使えます。
Wiring Pi 独自ピンと BMC ピンの対比は KSY さんのこのページが大変便利です。
コマンド対応表
Wriring Pi | raspi-gpio | |
---|---|---|
GPIO 全てを読む | gpio readall |
raspi-gpio get |
BMC ピン 6 番を読む | gpio -g read 6 |
raspi-gpio get 6 |
出力フォーマット比較
gpio
と raspi-gpio
は、出力フォーマットにかなりの差があります。
gpio readall
と raspi-gpio get
$ gpio readall
+-----+-----+---------+------+---+---Pi 3B--+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| | | 3.3v | | | 1 || 2 | | | 5v | | |
| 2 | 8 | SDA.1 | IN | 1 | 3 || 4 | | | 5v | | |
| 3 | 9 | SCL.1 | IN | 1 | 5 || 6 | | | 0v | | |
| 4 | 7 | GPIO. 7 | IN | 1 | 7 || 8 | 0 | IN | TxD | 15 | 14 |
| | | 0v | | | 9 || 10 | 1 | IN | RxD | 16 | 15 |
| 17 | 0 | GPIO. 0 | IN | 0 | 11 || 12 | 0 | IN | GPIO. 1 | 1 | 18 |
| 27 | 2 | GPIO. 2 | IN | 0 | 13 || 14 | | | 0v | | |
| 22 | 3 | GPIO. 3 | IN | 0 | 15 || 16 | 0 | IN | GPIO. 4 | 4 | 23 |
| | | 3.3v | | | 17 || 18 | 0 | IN | GPIO. 5 | 5 | 24 |
| 10 | 12 | MOSI | IN | 0 | 19 || 20 | | | 0v | | |
| 9 | 13 | MISO | IN | 0 | 21 || 22 | 0 | IN | GPIO. 6 | 6 | 25 |
| 11 | 14 | SCLK | IN | 0 | 23 || 24 | 1 | IN | CE0 | 10 | 8 |
| | | 0v | | | 25 || 26 | 1 | IN | CE1 | 11 | 7 |
| 0 | 30 | SDA.0 | IN | 1 | 27 || 28 | 1 | IN | SCL.0 | 31 | 1 |
| 5 | 21 | GPIO.21 | IN | 1 | 29 || 30 | | | 0v | | |
| 6 | 22 | GPIO.22 | IN | 1 | 31 || 32 | 0 | IN | GPIO.26 | 26 | 12 |
| 13 | 23 | GPIO.23 | IN | 0 | 33 || 34 | | | 0v | | |
| 19 | 24 | GPIO.24 | IN | 0 | 35 || 36 | 0 | IN | GPIO.27 | 27 | 16 |
| 26 | 25 | GPIO.25 | IN | 0 | 37 || 38 | 0 | IN | GPIO.28 | 28 | 20 |
| | | 0v | | | 39 || 40 | 0 | IN | GPIO.29 | 29 | 21 |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+---Pi 3B--+---+------+---------+-----+-----+
$ raspi-gpio get
BANK0 (GPIO 0 to 27):
GPIO 0: level=1 fsel=0 func=INPUT
GPIO 1: level=1 fsel=0 func=INPUT
GPIO 2: level=1 fsel=0 func=INPUT
GPIO 3: level=1 fsel=0 func=INPUT
GPIO 4: level=1 fsel=0 func=INPUT
GPIO 5: level=1 fsel=0 func=INPUT
GPIO 6: level=1 fsel=0 func=INPUT
GPIO 7: level=1 fsel=0 func=INPUT
GPIO 8: level=1 fsel=0 func=INPUT
GPIO 9: level=0 fsel=0 func=INPUT
GPIO 10: level=0 fsel=0 func=INPUT
GPIO 11: level=0 fsel=0 func=INPUT
GPIO 12: level=0 fsel=0 func=INPUT
GPIO 13: level=0 fsel=0 func=INPUT
GPIO 14: level=0 fsel=0 func=INPUT
GPIO 15: level=1 fsel=0 func=INPUT
GPIO 16: level=0 fsel=0 func=INPUT
GPIO 17: level=0 fsel=0 func=INPUT
GPIO 18: level=0 fsel=0 func=INPUT
GPIO 19: level=0 fsel=0 func=INPUT
GPIO 20: level=0 fsel=0 func=INPUT
GPIO 21: level=0 fsel=0 func=INPUT
GPIO 22: level=0 fsel=0 func=INPUT
GPIO 23: level=0 fsel=0 func=INPUT
GPIO 24: level=0 fsel=0 func=INPUT
GPIO 25: level=0 fsel=0 func=INPUT
GPIO 26: level=0 fsel=0 func=INPUT
GPIO 27: level=0 fsel=0 func=INPUT
BANK1 (GPIO 28 to 45):
GPIO 28: level=1 fsel=0 func=INPUT
GPIO 29: level=0 fsel=1 func=OUTPUT
GPIO 30: level=0 fsel=7 alt=3 func=CTS0
GPIO 31: level=0 fsel=7 alt=3 func=RTS0
GPIO 32: level=1 fsel=7 alt=3 func=TXD0
GPIO 33: level=1 fsel=7 alt=3 func=RXD0
GPIO 34: level=0 fsel=7 alt=3 func=SD1_CLK
GPIO 35: level=1 fsel=7 alt=3 func=SD1_CMD
GPIO 36: level=1 fsel=7 alt=3 func=SD1_DAT0
GPIO 37: level=1 fsel=7 alt=3 func=SD1_DAT1
GPIO 38: level=1 fsel=7 alt=3 func=SD1_DAT2
GPIO 39: level=1 fsel=7 alt=3 func=SD1_DAT3
GPIO 40: level=0 fsel=4 alt=0 func=PWM0
GPIO 41: level=0 fsel=4 alt=0 func=PWM1
GPIO 42: level=0 fsel=4 alt=0 func=GPCLK1
GPIO 43: level=0 fsel=4 alt=0 func=GPCLK2
GPIO 44: level=1 fsel=0 func=INPUT
GPIO 45: level=1 fsel=0 func=INPUT
BANK2 (GPIO 46 to 53):
GPIO 46: level=1 fsel=0 func=INPUT
GPIO 47: level=1 fsel=1 func=OUTPUT
GPIO 48: level=0 fsel=4 alt=0 func=SD0_CLK
GPIO 49: level=1 fsel=4 alt=0 func=SD0_CMD
GPIO 50: level=1 fsel=4 alt=0 func=SD0_DAT0
GPIO 51: level=1 fsel=4 alt=0 func=SD0_DAT1
GPIO 52: level=1 fsel=4 alt=0 func=SD0_DAT2
GPIO 53: level=1 fsel=4 alt=0 func=SD0_DAT3
※出力結果には "GPIO: xx" って出てますけど、これは BMC のピン番号です。そのため、この出力で実質使えるのは GPIO 0 ~ 27 ということになります。
gpio -g read 6
と raspi-gpio get 6
$ gpio -g read 6
1
# OR => 0
$ raspi-gpio get 6
GPIO 6: level=0 fsel=0 func=INPUT
# Or => GPIO 6: level=1 fsel=0 func=INPUT
level=
の値が gpio read
で返されていた時の値となります。使いづらい...
raspi-gpio get
の出力を gpio read
互換にする
GNU awk の力を借りると、gpio read
の出力と互換が取れます。
$ gpio -g read 6
1
$ raspi-gpio get 6 | awk -v RS=" " -F "=" -v k="level" '$1==k {print $2}'
1
-
-v RS=" "
: key-value 間の区切り文字 (今回は空白) -
-F "="
: key と value の区切り文字 (今回は =) -
-v k="level"
: 探したい key 名 (今回は level) -
$1==k
: 読み込んだkeyが-v k=
で指定した変数と一致したか? -
{print $2}
: $2=value を表示 ($1はkey)
-F
-v RS=
をうまく使えば key1=value1, key2=value2, key3=value3
みたいな文字列から値だけ切り出すのも一発です。覚えておいて損は無いかと。
$ echo -n 'key1=value1, key2=value2, key3=value3' | awk -v RS=", " -F "=" -v k="key1" '$1==k {print $2}'
value1
$ echo -n 'key1=value1, key2=value2, key3=value3' | awk -v RS=", " -F "=" -v k="key3" '$1==k {print $2}'
value3
ところで、今後も大丈夫なの?
まあ Raspberry Pi のなかのひと(Serge-san)がメンテしてるので、長いこと使えるんじゃないでしょうか。しらんけど。
$ apt-cache show raspi-gpio | grep Maintainer
Maintainer: Serge Schneider <serge@raspberrypi.org>
あとがき
よいお年を!
参考資料
- 「Raspberry Pi OS」、2種類が提供へ--Buster版とBullseye版
- Bullseye – the new version of Raspberry Pi OS
- wiringPi – deprecated…
- wiringpi is missing from bullseye. how do i install it? - Raspberry Pi Stack Exchange
EoT