Raspberry PiのGPIO操作(1)Lチカ、OLED表示

せっかく久しぶりにRaspbianをインストールしたので、これまでやっていなかった、Raspbianからのデバイス制御を試してみました。

RaspbianはStretch-Liteをインストールし、raspi-configでシリアルポートを有効化しました。
これでシリアルポートからログインできるようになり、キーボードやディスプレイを接続する必要が無くなります。
Pi Zero Wなら、ネットワークとsshを有効にしておけばネットワーク経由でログインできますので、シリアルケーブルも不要になります。

これでRPi周辺がすっきりしましたので、GPIOでのデバイス接続を試してみました。

まず、Raspberry Pi Zero/Zero WのGPIOですが、BCM2835のマニュアルP102によると、ピンに対して機能が以下の図のように割り当てられています。
このうち、ピンヘッダで信号を取り出せるのはGPIO2~27となっています。

ざっと見ると、いわゆるGPIOとしての入出力以外に(ピンヘッダから)使える主な機能は

・I2C ×1 (SDA1/SCL1)
・SPI ×2 (SPI0、SPI1)
・UART ×1 (TXD0/RXD0/CTS0/RTS0、またはTXD1/RXD1/CTS1/RTS1)
・PWM ×2 (PWM0、PWM1)
・PCM ×1 (PCM_CLK/PCM_FS/PCM_DIN/PCM_DOUT)
・JTAG ×1 (ARM_TDI/ARM_TDO/ARM_RTCK/ARM_TMS/ARM_TCK)

であることが解ります。
このほかにGPIO Clock(オーディオデバイスにクロックを供給するために使われるらしい)、BSC Slave(I2C互換のBroadcom独自インタフェースらしいです)、メモリインタフェース(SDx、SAxがそれぞれデータバス/アドレスバス)があるようです。

他のRaspberry Piも含めた、より詳しい一覧表が以下のページにあります。

RPi BCM2835 GPIOs – eLinux.org

一つのピンに複数の機能は割り振れないので、例えばSPI1とRTS0/CTS0/RTS1/CTS1を同時に使用することはできません。
ピン配置は以前も掲載しましたが下図の通りです。

●Lチカ

GPIOを制御するには、Pythonのライブラリが公開されています。
しかしRaspbianはLinuxなので、GPIOのオン・オフくらいファイルシステム経由でできるだろう、と考えて調べてみたら、やはりそういったインタフェースが用意されていました。

Raspberry Pi でLチカする方法がたくさんありすぎる件について – Qiita

The Most Basic Way to Access GPIO on a Raspberry Pi

GPIOをオンオフするには、/sys/class/gpio以下のファイルに設定を書き込みます。
先日試したオンボードのLEDがつながっているGPIO47は、BUSYで制御できませんでしたので、普通にピンヘッダのほうのGPIOを試してみました。

1)echo ピン番号 > /sys/class/gpio/export で該当のGPIOを有効化
2)echo out > /sys/class/gpio/ピン番号/direction で出力ピンに設定
3)echo 0か1 > /sys/class/gpio/ピン番号/value でHまたはLを出力

という形で制御できます。
入力の場合は、echo in > /sys/class/gpio/ピン番号/directionで設定し、cat /sys/class/gpio/ピン番号/value で値を取得します。

以下の例ではGPIO4(ピンヘッダの7番ピン)に出力しています。
LEDのアノードを7番ピン、カソードを9番ピン(GND)に接続すれば、LEDをオン・オフできます。

raspbianにはraspi-gpioというパッケージがあり、

sudo apt-get install raspi-gpio

でインストールできます。
このパッケージを使うと、上記と同等のことをより簡単に行うことができます。
例えばGPIOの状態を取得するには、以下のようになります。

●I2C

まず、sudo raspi-configで「5 Interfacing Options」を選択し、I2CとSPIをenabledにしておきます。
これでデバイスドライバが自動で読み込まれるようになります。
I2Cは/dev/i2c-1、SPIは/dev/spidev0.0と/dev/spidev0.1がデバイスファイルとして作成されます。

I2Cは標準コマンドのみで操作することは難しいようですが、Linuxではプログラムを書かずに操作するための専用のi2c-toolsというパッケージがあります。

Raspberry Pi Tutorial Series: I2C – Waveshare Wiki

これはデフォルトのraspbianではインストールされていないので、

sudo apt-get install i2c-tools

でインストールします。
すると、以下のコマンドがインストールされます。

/usr/sbin/i2cdetect
/usr/sbin/i2cget
/usr/sbin/i2c-stub-from-dump
/usr/sbin/i2cdump
/usr/sbin/i2cset

これらのコマンドで、i2cデバイスを制御することができます。
とはいえ、i2cデバイスごとのドライバが必要にはなりますが。
おなじみのOLED、SSD1306のI2C版を接続してみました。結線は下図の通りです。

rpi-ssd1306.png

デバイスの検索は

i2cdetect -a 1

で行えます。1はI2Cバス番号です。
Raspberry Piでは、ピンヘッダ(ピン3、ピン5)で利用できるのはI2C1ですので、1を指定しています。
SSD1306 OLEDを接続した状態で実行すると、以下のようにアドレス「3C」にデバイスがあることが表示されます。
このアドレスは、製品によって異なる場合があるようです。

このOLEDへコマンドを送るには、i2csetを使います。
ちょっと長いですが、こちらのサンプルを借用して、I2Cバス番号とデバイスアドレスだけ書き換えたシェルスクリプトを作ってみました。

実行すると、こんな感じでOLEDに表示されます。

raspbian-ssd1306.jpg

コメント