mattintosh note

どこかのエンジニアモドキの備忘録

Raspberry Pi の GPIO の意外な?真実

Raspberry Pi の GPIO についてちょっと気になったことがあったので色々試してみた。

Raspberry Pi の GPIO2 と GPIO3 は物理的にプルアップされているそうだ。これは実物を見れば抵抗につながっているのが確認できる。その他のピンは「プルアップされている」とか「プルダウンされている」とか、よくわからない。

とりあえずうちにある Raspberry Pi 3 のうちの Element14 番で試してみる。

まず最初に /sys/class/gpio の初期状態。

$ ls -l /sys/class/gpio
total 0
--w------- 1 root root 4096 Jan  7 00:01 export
lrwxrwxrwx 1 root root    0 Dec 10 10:11 gpiochip0 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpiochip0
lrwxrwxrwx 1 root root    0 Dec 10 10:11 gpiochip100 -> ../../devices/platform/soc/soc:virtgpio/gpio/gpiochip100
--w------- 1 root root 4096 Jan  7 00:01 unexport

一気に書き込むとエラーになるので sleep 2 を入れつつ徐々に有効にする。

$ for f in {4..27}; do echo $f >/sys/class/gpio/export; sleep 2; done

GPIO4 から GPIO27 までが使えるようになった。

$ ls -l /sys/class/gpio
total 0
--w------- 1 root root 4096 Jan  7 00:04 export
lrwxrwxrwx 1 root root    0 Jan  7 00:04 gpio10 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio10
lrwxrwxrwx 1 root root    0 Jan  7 00:04 gpio11 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio11
lrwxrwxrwx 1 root root    0 Jan  7 00:04 gpio12 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio12
lrwxrwxrwx 1 root root    0 Jan  7 00:04 gpio13 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio13
lrwxrwxrwx 1 root root    0 Jan  7 00:04 gpio14 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio14
lrwxrwxrwx 1 root root    0 Jan  7 00:04 gpio15 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio15
lrwxrwxrwx 1 root root    0 Jan  7 00:04 gpio16 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio16
lrwxrwxrwx 1 root root    0 Jan  7 00:04 gpio17 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio17
lrwxrwxrwx 1 root root    0 Jan  7 00:04 gpio18 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio18
lrwxrwxrwx 1 root root    0 Jan  7 00:04 gpio19 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio19
lrwxrwxrwx 1 root root    0 Jan  7 00:04 gpio20 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio20
lrwxrwxrwx 1 root root    0 Jan  7 00:04 gpio21 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio21
lrwxrwxrwx 1 root root    0 Jan  7 00:04 gpio22 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio22
lrwxrwxrwx 1 root root    0 Jan  7 00:04 gpio23 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio23
lrwxrwxrwx 1 root root    0 Jan  7 00:04 gpio24 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio24
lrwxrwxrwx 1 root root    0 Jan  7 00:04 gpio25 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio25
lrwxrwxrwx 1 root root    0 Jan  7 00:05 gpio26 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio26
lrwxrwxrwx 1 root root    0 Jan  7 00:05 gpio27 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio27
lrwxrwxrwx 1 root root    0 Jan  7 00:04 gpio4 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio4
lrwxrwxrwx 1 root root    0 Jan  7 00:04 gpio5 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio5
lrwxrwxrwx 1 root root    0 Jan  7 00:04 gpio6 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio6
lrwxrwxrwx 1 root root    0 Jan  7 00:04 gpio7 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio7
lrwxrwxrwx 1 root root    0 Jan  7 00:04 gpio8 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio8
lrwxrwxrwx 1 root root    0 Jan  7 00:04 gpio9 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio9
lrwxrwxrwx 1 root root    0 Dec 10 10:11 gpiochip0 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpiochip0
lrwxrwxrwx 1 root root    0 Dec 10 10:11 gpiochip100 -> ../../devices/platform/soc/soc:virtgpio/gpio/gpiochip100
--w------- 1 root root 4096 Jan  7 00:01 unexport

この状態で各ピンのモードと値を取ってみたところ、モードはすべて in。値は一部のピンはプルダウンされていないのか、1 になっていた。ちなみに /sys/class/gpio/unexport してやり直しても directionvalue の値は同じだった。このことを考えると入力として使うのに向いたピンとそうでないピンがあるのだろうか。

$ for f in {4..27}; do printf '%2s %3s %s\n' $f `cat /sys/class/gpio/gpio$f/{direction,value}`; done
 4  in 1
 5  in 1
 6  in 1
 7  in 1
 8  in 1
 9  in 0
10  in 0
11  in 0
12  in 0
13  in 0
14  in 0
15  in 1
16  in 0
17  in 0
18  in 0
19  in 0
20  in 0
21  in 0
22  in 0
23  in 0
24  in 0
25  in 0
26  in 0
27  in 0

今度はすべてのピンを out にしてみる。値はすべて 0 になった。

$ for f in {4..27}; do echo out >/sys/class/gpio/gpio$f/direction; sleep .5; done
$ for f in {4..27}; do printf '%2s %3s %s\n' $f `cat /sys/class/gpio/gpio$f/{direction,value}`; done
 4 out 0
 5 out 0
 6 out 0
 7 out 0
 8 out 0
 9 out 0
10 out 0
11 out 0
12 out 0
13 out 0
14 out 0
15 out 0
16 out 0
17 out 0
18 out 0
19 out 0
20 out 0
21 out 0
22 out 0
23 out 0
24 out 0
25 out 0
26 out 0
27 out 0

direction の設定は inout だと思っていたのだが、ネットを徘徊していたときにちらっと high というワードを見かけたので一旦 in に戻した後、high にしてみたら驚いた。すべて綺麗に 1echo out >/sys/class/gpio/gpioX/directionecho high >/sys/class/gpio/gpioX/direction は別物のようだ。

$ for f in {4..27}; do echo in   >/sys/class/gpio/gpio$f/direction; sleep .5; done
$ for f in {4..27}; do echo high >/sys/class/gpio/gpio$f/direction; sleep .5; done
$ for f in {4..27}; do printf '%2s %3s %s\n' $f `cat /sys/class/gpio/gpio$f/{direction,value}`; done
 4 out 1
 5 out 1
 6 out 1
 7 out 1
 8 out 1
 9 out 1
10 out 1
11 out 1
12 out 1
13 out 1
14 out 1
15 out 1
16 out 1
17 out 1
18 out 1
19 out 1
20 out 1
21 out 1
22 out 1
23 out 1
24 out 1
25 out 1
26 out 1
27 out 1

high があるなら low もあるんだろうということでやってみたら今度は out だけど値は 0 になった。

$ for f in {4..27}; do echo in   >/sys/class/gpio/gpio$f/direction; sleep .5; done
$ for f in {4..27}; do echo low  >/sys/class/gpio/gpio$f/direction; sleep .5; done
$ for f in {4..27}; do printf '%2s %3s %s\n' $f `cat /sys/class/gpio/gpio$f/{direction,value}`; done
 4 out 0
 5 out 0
 6 out 0
 7 out 0
 8 out 0
 9 out 0
10 out 0
11 out 0
12 out 0
13 out 0
14 out 0
15 out 0
16 out 0
17 out 0
18 out 0
19 out 0
20 out 0
21 out 0
22 out 0
23 out 0
24 out 0
25 out 0
26 out 0
27 out 0

以前、エアコンの信号を夜に取るのに赤外線受光モジュールの足を15番に繋いだような繋いでないような。ものすごく不安定でまともに信号を読み取れなかったのだが、何か関係しているのだろうか。(この時は充電最適化機能付きの電源を使っているのが問題だったのだが)

とりあえずボタン入力とかは 4/5/6/7/8/15 を避けた方が安定しそうだ。

時間ができたら UK 版と JP 版の Raspberry Pi 3、それから Zero でも調べてみよう。入力で初期値を決めるワードってなんだろうか。あと OS とか Raspberry Pi のバージョンでも違うんだろうか。

そういえばよく見たら17番ピンの3.3Vにちゃんと抵抗ついてた。これを目印にすれば3.3Vの取り出しは間違え無さそうだ。

Raspberry Pi Zero Raspbian

Raspberry Pi Zero Raspbian でも試してみたところ、こちらは 4/5/6/7/8/15 に加え、14 も 1 になった。

# for f in {4..27}; do echo $f >/sys/class/gpio/export; sleep 2; done
# for f in {4..27}; do printf '%2s %3s %s\n' $f `cat /sys/class/gpio/gpio$f/{direction,value}`; done
 4  in 1                                                                                                                                              
 5  in 1                                                                                                                                              
 6  in 1                                                                                                                                              
 7  in 1                                                                                                                                              
 8  in 1                                                                                                                                              
 9  in 0                                                                                                                                              
10  in 0                                                                                                                                              
11  in 0                                                                                                                                              
12  in 0                                                                                                                                              
13  in 0                                                                                                                                              
14  in 1                                                                                                                                              
15  in 1                                                                                                                                              
16  in 0                                                                                                                                              
17  in 0                                                                                                                                              
18  in 0                                                                                                                                              
19  in 0                                                                                                                                              
20  in 0
21  in 0
22  in 0
23  in 0
24  in 0
25  in 0
26  in 0
27  in 0

4/5/6/7/8 に関しては http://elinux.org/RPi_BCM2835_GPIOs に High と書いてあるのだけど 14/15 はわからないな。