Edited at

Raspberry Pi 3 Model Bに Adafruit PiOLED を接続


Raspberry Pi 3 Model Bに Adafruit PiOLED を接続


はじめに

Raspberry Pi 3 で CO2濃度を測る で取得したCO2濃度の値を、他システムに通知するなどの仕組みを設けずにRaspberry Pi 3上で直接参照できるよう、OLEDを取り付けてみました。

ここでは、Raspberry Pi用 128x32 モノクロOLEDモジュールの取付けとサンプルプログラムの実行までを記載します。


準備する物


前提条件


参考情報


ライブラリのインストール


RPi.GPIO ライブラリのインストール

gcc 、python-devel 、 pip をインストールした後、RPi.GPIO ライブラリをインストールします。 

$ sudo yum install -y gcc python-devel

$ curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
$ sudo python get-pip.py
$ sudo pip install RPi.GPIO

Collecting RPi.GPIO
Using cached RPi.GPIO-0.6.3.tar.gz
Building wheels for collected packages: RPi.GPIO
Running setup.py bdist_wheel for RPi.GPIO ... done
Stored in directory: /root/.cache/pip/wheels/ae/4d/3b/e924997dbf06810adf3b2e37f1d9627b2327eb9cbb285949c9
Successfully built RPi.GPIO
Installing collected packages: RPi.GPIO
Successfully installed RPi.GPIO-0.6.3


python-imaging 、smbusライブラリのインストール

python-imaging、sumbusライブラリをインストールします。

$ sudo  yum install -y python-imaging

$ sudo yum install libffi-devel
$ sudo pip install smbus-cffi


モノクロOLEDモジュールの接続

Raspberry Pi 3 をシャットダウンし、モノクロOLEDモジュールを接続して起動します。

モノクロOLEDモジュールを直接GPIOに接続する場合は、https://www.switch-science.com/catalog/3393/Pi Zeroへの搭載例 にあるように挿すだけです。

MH-Z19センサーとモノクロOLEDモジュールを同時に使用する場合は、

http://elinux.org/File:Pi-GPIO-header.pnghttps://cdn-learn.adafruit.com/assets/assets/000/042/248/medium800/adafruit_products_schem.png?1496376981 の回路図をもとにジャンパーケーブルで接続します。



Drawn by Cacoo


カーネルモジュールのロード

I2C通信に必要なカーネルモジュール ( i2c-dev, i2c-bcm2708 ) の情報は以下のとおり。

$ sudo modinfo i2c-dev

filename: /lib/modules/4.9.35-v7.1.el7/kernel/drivers/i2c/i2c-dev.ko
license: GPL
description: I2C /dev entries driver
author: Frodo Looijaard <frodol@dds.nl> and Simon G. Vogl <simon@tk.uni-linz.ac.at>
srcversion: 39CD4E8A99571AFB173792F
depends:
intree: Y
vermagic: 4.9.35-v7.1.el7 SMP mod_unload modversions ARMv7 p2v8

$ sudo modinfo i2c-bcm2708

filename: /lib/modules/4.9.35-v7.1.el7/kernel/drivers/i2c/busses/i2c-bcm2708.ko
alias: platform:bcm2708_i2c
license: GPL v2
author: Chris Boot <bootc@bootc.net>
description: BSC controller driver for Broadcom BCM2708
srcversion: 0C1F4F8690E98B7CEAABAE5
alias: of:N*T*Cbrcm,bcm2708-i2cC*
alias: of:N*T*Cbrcm,bcm2708-i2c
depends:
intree: Y
vermagic: 4.9.35-v7.1.el7 SMP mod_unload modversions ARMv7 p2v8
parm: baudrate:The I2C baudrate (uint)
parm: combined:Use combined transactions (bool)

カーネルモジュールをロードします。

ロードすると、さきほど確認したカーネルモジュール情報の description が dmesg に出力されます。

$ sudo modprobe i2c-dev

$ dmesg | grep i2c
[ 5.202056] i2c /dev entries driver


/dev/i2c-1 の作成

必要となるスペシャルファイル( /dev/i2c-1 もしくは /dev/i2c/1 ) が存在しないため、作成します。

スペシャルファイルを作成する mknod コマンドの引数となるmajor number (ここでは89)を確認します。

$ cat /proc/devices | grep i2c

89 i2c

mknod コマンドを実行し、/dev/i2c-1 が作成されたことを確認します。

$ sudo mknod /dev/i2c-1 c 89 1

$ ls /dev/i2c-1
/dev/i2c-1


i2c-toolsのインストール

モノクロOLEDモジュールが接続されていることを確認するため、i2c-tools をインストールします。

$ sudo yum install -y i2c-tools

i2cdetectコマンドを実行し、モノクロOLEDモジュールのアドレス 0x3c が出力されることを確認します。

$ sudo i2cdetect -y 1

0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --


サンプルプログラム

サンプルプログラムを git cloneします。

git がインストールされていない場合は、先にインストールします。

# sudp yum -y install git

$ git clone https://github.com/adafruit/Adafruit_Python_SSD1306.git


サンプルプログラムのセットアップ

サンプルプログラムの実行環境をセットアップします。

$ cd Adafruit_Python_SSD1306

$ sudo python ./setup.py build
$ sudo python ./setup.py install


サンプルプログラムの実行

以下のように、stats.py を実行するとモノクロOLEDモジュールに出力例のようなリソース情報が出力されます。

$ python ./examples/stats.py &

出力例)

IP: 192.168.1.110

CPU Load: 0.50
Mem: 48/923MB 5.20%
Disk: 1/14GB 9%

モノクロOLEDモジュールを直接GPIOに接続した場合

MH-Z19センサーとモノクロOLEDモジュールを同時に使用する場合


OS起動時のカーネルモジュール自動ロード設定

OS起動時にカーネルモジュールが自動的に読み込まれるよう設定します。

/boot/config.txtの末尾に以下の2行を追記します。

$ sudo vi /boot/config.txt 

dtparam=i2c=on1=on
dtparam=i2c_arm=on

/etc/modules-load.d 以下に i2c-dev.conf を新規作成し、i2c-dev と追記します。

$ sudo vi /etc/modules-load.d/i2c-dev.conf

i2c-dev


MH-Z19センサーの値を表示

Raspberry Pi 3 で CO2濃度を測る で取得したCO2濃度の値をモノクロOLED モジュールに表示します。


mh_z19.py を呼び出し

サンプルプログラムの stats.py で 4 行目に表示していたディスク使用量をCO2濃度の値にします。

./examples/stats.py を ./examples/stats-co2.py など別名にし、 実行コマンドを置き換えます。

差分は以下のとおり。

/PATH/TO/slider/mh_z19.py の箇所は、実際のパスに置き換えます。

time.sleep(.1) では実行頻度が多すぎるので、time.sleep(60)に変更します。

$ diff ./examples/stats.py ./examples/stats-co2.py

117,118c117,120
< cmd = "df -h | awk '$NF==\"/\"{printf \"Disk: %d/%dGB %s\", $3,$2,$5}'"
< Disk = subprocess.check_output(cmd, shell = True )
---
> #cmd = "df -h | awk '$NF==\"/\"{printf \"Disk: %d/%dGB %s\", $3,$2,$5}'"
> #Disk = subprocess.check_output(cmd, shell = True )
> cmd = "python /PATH/TO/slider/mh_z19.py |awk '{printf \"CO2: %d\", $2}'"
> CO2 = subprocess.check_output(cmd, shell = True )
125c127,128
< draw.text((x, top+25), str(Disk), font=font, fill=255)
---
> draw.text((x, top+25), str(CO2), font=font, fill=255)
> #draw.text((x, top+25), str(Disk), font=font, fill=255)
130c133
< time.sleep(.1)
---
> time.sleep(60)


実行

4行目に  CO2: 335 と、実行結果が表示されました。

$ sudo python ./examples/stats-co2.py &


実行頻度を多くした場合のエラー対策

stats.py では、time.sleep(.1) となっていて、0.1秒毎に実行されています。

この頻度で mh_z19.py が呼ばれると、systemctl の再起動制限に該当し、以下のメッセージがコンソールに出力されます。

Job for serial-getty@ttyS0.service failed because start of the service was attempted too often. See "systemctl status serial-getty@ttyS0.service" and "journalctl -xe" for details.

To force a start use "systemctl reset-failed serial-getty@ttyS0.service" followed by "systemctl start serial-getty@ttyS0.service" again.

10秒間に6回以上の再起動でエラー となるため、time.sleep(60) のように間隔をあけるか、systemdファイルに StartLimitBurst=0 を追記します。

ファイルのパスを確認します。

$ systemctl show -p FragmentPath  serial-getty@ttyS0.service

FragmentPath=/usr/lib/systemd/system/serial-getty@.service

$ sudo vi FragmentPath=/usr/lib/systemd/system/serial-getty\@.service

IgnoreSIGPIPE=no
SendSIGHUP=yes
StartLimitBurst=0 <- この行を追加

[Install]
WantedBy=getty.target

systemdを再起動します。

$ sudo systemctl daemon-reload