Help us understand the problem. What is going on with this article?

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 の回路図をもとにジャンパーケーブルで接続します。

OLED.png
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に接続した場合
DSC_1399s.jpg

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

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 &

DSC_1450.JPG

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

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
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away