2017 年度 OSS リテラシー 3 : 第 10 回 センサーの利用 & 監視

はじめに: 利用するセンサー

I2C(アイ・スクエア・シー, アイ・アイ・シー, アイ・ツー・シー)は低速な 周辺機器をマイコンに接続したり, 組み込みシステムや携帯電話などで利用される.

演習では以下の I2C 規格のセンサーを利用する. これらのセンサー が全てラズパイの GPIO 2, 3 (ピン番号 3, 5) に接続されている.

  • 気圧・温度センサー: Adafruit BMP180
    • 精度: -4 ~ 2 hPa (圧力 (絶対値)), -2 ~ +2 度 (温度)
    • I2C アドレス: 0x77
  • 照度センサー: Adafruit TSL2561
    • ダイナミックレンジ: 0.1 ~ 40,000 Lux
    • I2C アドレス: 0x39 (0x29, 0x49)
  • 非接触型温度計 (放射温度計): Adafruit TMP007
    • I2C アドレス: 0x40 (0x47)

なお, I2C 規格以外ではないが, 本演習では温度・湿度センサー SENSIRION SHT75 も用いる. このセンサーは精度が良く, I2C 規格のそれに比べてノイズに強い (ケーブル長を長くとれる) という利点がある. 松江高専の環境モニタリングシステムの主力はこの SHT75 である.

  • 温度・湿度センサー: SENSIRION SHT75
    • 精度: -0.3 ~ +0.3 度 (温度), -1.8 ~ +1.8 % (湿度)

センサーの接続

I2C 規格のセンサーは演習用基板の CON 1, CON 2, CON 3 のどれかに 接続するすれば良い. これらのポートはラズパイの GPIO 2, GPIO 3 (ピン番号 3, 5) に並列に接続されている. ユーザは I2C 機器が接続されている GPIO の番号を意識する必要はない.

温度・湿度センサーは練習用基盤の CON6 ポートに接続する. このポートは GPIO 23 ピンと GPIO 24 ピンに接続されている. 今回は使わないが, CON 4 ポートは GPIO17 ピンと GPIO18 ピンに, CON5 ポートは GPIO27 ピンと GPIO22 ピンに接続されている.

I2C 規格のセンサーのセットアップ

"メニュー" => "設定" => "Raspberry Pi の設定" を選択し, "インターフェイス" タブより I2C を有効にする

I2C で接続された周辺機器には固有のアドレスが付与される. 接続した I2C 機器に振られたアドレスを確認するためには, i2cdetect コマンドを使う. 機器ごとにアドレスが決まっているので, アドレスが表示されるか確認をする. 0x39 が TSL2561, 0x40 が TMP007, 0x77 が BMP180 である.

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

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

各センサーの python ライブラリが配布されているので, それをインストールする. pip コマンドは Python のパッケージ管理システムである. 近年は言語ごとに パッケージ管理システムを持ち, OS が用意している以外のライブラリを インストールことが容易になっている (例えば ruby なら gem).

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

$ sudo pip install adafruit-bmp

  Collecting adafruit-bmp
    Downloading Adafruit_BMP-1.5.2-py2-none-any.whl
  Collecting Adafruit-GPIO>=0.6.5 (from adafruit-bmp)
    Downloading Adafruit_GPIO-1.0.3.tar.gz
  Collecting adafruit-pureio (from Adafruit-GPIO>=0.6.5->adafruit-bmp)
    Downloading Adafruit_PureIO-0.2.1-py2-none-any.whl
  Requirement already satisfied: spidev in /usr/lib/python2.7/dist-packages (from Adafruit-GPIO>=0.6.5->adafruit-bmp)
  Building wheels for collected packages: Adafruit-GPIO
    Running setup.py bdist_wheel for Adafruit-GPIO ... done
    Stored in directory: /root/.cache/pip/wheels/b3/9c/46/979f3d85515bc2cc73b7ec36eba4310d7b5e1d915b6489995d
  Successfully built Adafruit-GPIO
  Installing collected packages: adafruit-pureio, Adafruit-GPIO, adafruit-bmp
  Successfully installed Adafruit-GPIO-1.0.3 adafruit-bmp-1.5.2 adafruit-pureio-0.2.1

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

$ sudo pip install adafruit-tmp

  Collecting adafruit-tmp
    Downloading Adafruit_TMP-1.6.1-py2-none-any.whl
  Requirement already satisfied: Adafruit-GPIO>=0.6.5 in /usr/local/lib/python2.7/dist-packages (from adafruit-tmp)
  Requirement already satisfied: adafruit-pureio in /usr/local/lib/python2.7/dist-packages (from Adafruit-GPIO>=0.6.5->adafruit-tmp)
  Requirement already satisfied: spidev in /usr/lib/python2.7/dist-packages (from Adafruit-GPIO>=0.6.5->adafruit-tmp)
  Installing collected packages: adafruit-tmp
  Successfully installed adafruit-tmp-1.6.1

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

$ sudo pip install tsl2561

  Collecting tsl2561
    Downloading tsl2561-3.3-py2.py3-none-any.whl
  Installing collected packages: tsl2561
  Successfully installed tsl2561-3.3

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

$ sudo pip install sht-sensor

  Collecting sht-sensor
    Downloading sht_sensor-17.5.5-py2-none-any.whl
  Installing collected packages: sht-sensor
  Successfully installed sht-sensor-17.5.5

実習用サンプルスクリプト

実習用サンプルスクリプトを GitHub から入手する.

$ git clone https://github.com/sugiymki/iotex-sensor.git

clone した iotex-sensor の bin 以下にサンプルスクリプトが存在する. 以下の手順に従って, 接続したセンサーが実際に動作するか確認せよ.

bmp007

bmp007 を用いると温度 (Temp), 圧力 (Pressure) が得られる.

$ ./iotex-sensor/bin/bmp180
Temp = 17.00 *C
Pressure = 101521.00 Pa

オプション -t, -p をつけるとそれぞれ温度と圧力の値のみが出力される.

$ ./iotex-sensor/bin/bmp180 -t
17.00

$ ./iotex-sensor/bin/bmp180 -p
101521.00

TMP007

tmp007 を用いると基板の温度 (Die temperature) と TMP007 を向けている方向の壁か何かの放射温度 (Object temperature) が表示される.

$ ./iotex-sensor/bin/tmp007
Object temperature: 18.714 *C
Die temperature: 17.219 *C

オプション -t, -r をつけるとそれぞれ基板の温度と放射温度の値のみが出力される.

$ ./iotex-sensor/bin/tmp007 -t
17.219

$ ./iotex-sensor/bin/tmp007 -r
18.714

練習:センサーの前に手をかざすと放射温度 (Object temperature) が変化することを確認せよ.

TSL2561

tsl2561 を用いると照度を Lux 単位で測ることができる.

$ ./iotex-sensor/bin/tsl2561
LUX: 262

オプション -l をつけると照度の値のみが出力される.

$ ./iotex-sensor/bin/tsl2561
262

練習:センサーの前に手をかざしたり, センサーを蛍光灯に向けると照度が変化することを確認せよ.

SHT75 の利用

SHT75 については, pip install sht-sensor を行うことで, 実行ファイルが /usr/local/bin/sht としてインストールされる. 従って, /usr/local/bin 以下にインストールされた sht コマンドを用ることで温度, 湿度, 露点温度, を測定することができる.

$ /usr/local/bin/sht -v -trd 24 23

  temperature: 24.48
  rh: 55.7499717405
  dew_point: 15.0566070705

なお引数は以下の通りである.

-t: 温度 (temperature)
-r: 相対湿度 (relative humidity)
-d: 露点温度 (dew point)

なお, 今回は関係ないが, CON4 と CON5 に SHT75 を接続した場合は以下のように実行する.

$ /usr/local/bin/sht -v -trd 18 17
$ /usr/local/bin/sht -v -trd 27 22

追加設定: ディスプレイの出力設定

ラズパイは起動してすぐに HDMI で接続された機器とネゴシエーションを行い, その結果に基づいて画面表示を開始する. ネゴシエーションに失敗すると コンポジット(いわゆるビデオ信号)での表示となる. そのため, ラズパイを起動した後に HDMI ディスプレイを接続しても画面に何も映らないことになる. ラズパイを用いたセンサーは, 普段はディスプレイを接続する必要はないが, トラブルシューティングの際にディスプレイが必要となる. 今回はディスプレイの出力を固定することにする.

$ sudo -s 
# cd /boot
# cp config.txt  config.txt.bk   (バックアップ) 

# vi config.txt

  # uncomment if hdmi display is not detected and composite is being output
  hdmi_force_hotplug=1    (コメントアウトを外す)

  # uncomment to force a specific HDMI mode (this will force VGA)
  hdmi_group=1    (コメントアウトを外す)
  hdmi_mode=4     (コメントアウトを外し, 値を 4 にする)

# reboot

hdmi_force_hotplug=1 をすることで, 強制的に HDMI から出力することができる. また, 上記は hdmi_group=1 と hdmi_mode=4 とすることで, 解像度を 720p60 (1280x760) に固定することができる. 解像度に関する設定は以下を参考にすること. <URL:https://www.raspberrypi.org/forums/viewtopic.php?f=5&t=5851>

再起動後に HDMI ケーブルを抜き差しせよ. 設定がうまくいっていれば, HDMI ディスプレイに再びデスクトップ画面が映る.

crontab の設定

ラズパイが起動するたびに, GitHub から clone した iotex-sensor に含まれているスクリプトを自動実行し, 観測データのバックアップを サーバに 6 時間ごとに送るよう設定しなおす. なお, 以下の例で jxxxx は自分の学生番号に直すこと.

$ crontab -e

  PATH=/usr/bin:/bin:/usr/sbin:/sbin
  MAILTO=sugiyama@matsue-ct.jp
  # */5 * * * * hostname -I > data_now/ip.txt ; rsync -e "ssh -l jxxxx" -a data_now sky.epi.it.matsue-ct.jp:~/   (今までの命令はコメントアウト)
  0 */6 * * * hostname -I > data_now/ip.txt ; rsync -e "ssh -l jxxxx" -a data_now sky.epi.it.matsue-ct.jp:~/   (実行間隔のみを変更)
  @reboot ./iotex-sensor/bin/monitoring    (追加)

上記の設定は iotex-sensor ディレクトリがホームディレクトリ直下に存在することを想定している. もし, ホームディレクトリ以外に置いた場合は以下のようにディレクトリを移動せよ.

$ mv iotex-sensor ~/

Zabbix の設定

遠隔地に配置された多数のセンサーを一元的に管理するためには zabbix のようなサーバ監視ソフトウェアが欠かせない. GitHub から clone したリポジトリに zabbix の設定ファイルが含まれているのでそれを利用する.

まず, サーバ監視ソフトウェア zabbix の agent をラズパイにインストールする.

$ sudo -s

# apt-get update

  ... (略) ...

# apt-get install zabbix-agent

  パッケージリストを読み込んでいます... 完了
  依存関係ツリーを作成しています                
  ... (略)....
  取得:3 http://moon.epi.it.matsue-ct.jp/raspbian stretch/main armhf zabbix-agent armhf 1:3.0.7+dfsg-3 
  ... (略)....

設定ファイルは既に GitHub から clone した iotex-sensor に含まれているファイルをそのまま用いる.

# cp iotex-sensor/conf/zabbix_agentd.conf /etc/zabbix/

再起動

# /etc/init.d/zabbix-agent restart

zabbix サーバ <URL:http://sky.epi.it.matsue-ct.jp/zabbix/> に guest でログインし, 以下のように選択して自分のラズパイの状態を確認せよ. なお, グラフの横軸を最新 1 時間にしておくと良いだろう (マウスで表示領域を柔軟に変更できるので試してみよ).

  • [監視データ] => [スクリーン] => IoT デバイス : 状態監視 (デバイス毎) => ホスト : <自分のラズパイのホスト名>
  • [監視データ] => [スクリーン] => IoT デバイス : 観測値 (デバイス毎) => ホスト : <自分のラズパイのホスト名>

課題

注) 12/16 (土) に皆さんのラズパイの SD カードを構内モニタリングシステムに 移設するので, 金曜までに必ず課題を終えること.

  • 以下の zabbix の画面 (2 つ) でラズパイの状態と観測値を確認し, そのスクリーンショットを wbt より提出すること. なお, ラズパイには必ず温度・湿度センサー SHT75 を接続すること.
    • [監視データ] => [スクリーン] => IoT デバイス : 観測値 (デバイス毎) => ホスト : <自分のラズパイのホスト名>
    • [監視データ] => [スクリーン] => IoT デバイス : 状態監視 (デバイス毎) => ホスト : <自分のラズパイのホスト名>
  • 年明けの演習 3 回はグループワークをする予定である. 4 名程度のグループを作って wbt のオンラインテキストで報告せよ.