温度・湿度・気圧・照度をRaspberry Pi 3B+ で24時間監視する

2018年8月11日

温湿度・気圧をまとめて計測できてしまうBME280と言う超小型のセンサモジュールと、照度が計れるTSL2561センサモジュールが手に入ったので、Raspberry 3B+に繋いで、自宅の24時間環境モニタリングをやってみました!

計測したデータをこんな感じで可視化してみます。

使ったモノ

  • Raspberry Pi 3B+、Raspbian Stretch
$ uname -a
Linux rpi3-03p 4.14.52-v7+ #1123 SMP Wed Jun 27 17:35:49 BST 2018 armv7l GNU/Linux
$ cat /etc/debian_version
9.4
  • 温湿度・気圧センサ(BME280)
  • 照度センサ(TLS2561)
  • ソケット付きケーブル(ばら売りで安く売っていた物)

 

物理的な接続

センサとの通信は、I2C(アイ・スクエアド・シー)で行います。

1つのI2Cポートに2つのセンサモジュールをつなぐので、以下のようにまとめて1本になるようにケーブルをハンダ付けしました。

 

ラズベリーパイのポートは gpio readall で確認できるので、3.3V、SDA.1、SCL.1、0V(GND)を見つけて接続します。

 

物理ピンで3.3V(#1/赤)、SDA.1(#3/橙)、SCL.1(#5/白)、GND(#6/黒)に接続します。

接続した様子はこんな感じです。※念のため電源を落とした状態で配線しましょう。

 

センサデータの読み取り

コチラのサイトを参考にさせていただきました。
RPZ-IR-Sensor

raspi-config で I2C を使えるようにする

ラズパイのインターフェースの設定でI2Cを使えるようにします。

コンソールで設定する場合は、SSHで接続するか直接ターミナルを開いて、sudo raspi-config を実行し、インターフェース>I2C>Enable を選んだ後再起動します。

GUIで設定する場合には、設定>Raspberry Pi の設定>インターフェイス>I2C「有効」を選択します。

サンプルプログラムを入手する

上記の参考サイトから「rpz-sensor.zip」を入手します。
ラズベリーパイの適当なフォルダ(ここでは ${HOME}/src/env-monitor/)を作って展開します。

$ mkdir -p ~/src/env-monitor/
$ cd ~/src/env-monitor/
$ wget http://indoor.lolipop.jp/IndoorCorgiElec/RPZ-IR-Sensor/rpz-sensor.zip
$ unzip rpz-sensor.zip

 

動作テスト

先ほど展開してできたディレクトリに入ると、readme.txtがあるので一通り目を通しておきましょう。

$ cd rpz-sensor
$ ls
cpp python3 readme.txt

python3を使っていきます。
なお、python3が入っていない場合は初めにaptで入手しておきましょう。

$ sudo apt install python3
$ cd ./python3

まずは、bme280i2c.py 温湿度・気圧の情報を取得・表示します。

$ ./bme280i2c.py
BME280 0x76
dig_H1 : 75
dig_H2 : 364
dig_H3 : 0
dig_H4 : 312
dig_H5 : 50
dig_H6 : 30
dig_P1 : 37711
dig_P2 : -10593
dig_P3 : 3024
dig_P4 : 8371
dig_P5 : -54
dig_P6 : -7
dig_P7 : 9900
dig_P8 : -10230
dig_P9 : 4285
dig_T1 : 28172
dig_T2 : 26620
dig_T3 : 50
t_fine : 140750
adc_T : 537375
adc_P : 311316
adc_H : 29711
Temp : 27.5C
Pressure : 1003.1hPa
Humidity : 54.1%

1回目はおかしな値になっている場合があり、普通の環境では有り得ない値(Pressureの値が600になっていたりする)になっていたらもう1度実行してみてください。

(台風が近づいているので、若干低めですね。もうすぐ1000hPaを下回るかも。)

 

次に、tsl2561.py 照度情報を取得・表示しますが、モジュール基板の状態に併せてアドレスを修正します。

入手した基板のアドレスピンは未接続だったので、スイッチサイエンスさんの「光センサ TSL2561 の使い方」を参考に、vim tsl2561.pymain()のアドレス部分を書き換えます。

# tsl2561 = TSL2561(0x29)
tsl2561 = TSL2561(0x39)

実行してみましょう!

$ ./tsl2561.py
ADC Time : 402ms
ADC Gain : High
ch0 : 0x624
ch1 : 0x1BF
Lux : 31.0lux

31 lux !

ちょっと暗いのは、、、夜中の部屋の隅っこだからですw

 

最後に、ログファイルを作成できる rpz_sensor.py を使ってみます。

まずは必要になるdocoptパッケージをインストールします。

sudo pip3 install docopt

また、tsl2561.py の時と同じように、0x29を0x39に書き換えておきます。

ではセンサデータを表示してみましょう。

$ ./rpz_sensor.py
BME280 0x76
Temp : 30.4C
Pressure : 1002.8hPa
Humidity : 48.8%

TSL2561
Lux : 30.9lux

やった!
これで、温度・湿度・気圧・照度を取得できるようになりました!

 

CSVファイルとして書き出す

rpz_sensor.py にはログファイルを出力する機能があります。

./rpz_sensor.py -l log.csv
のようにlオプションを付けて、ファイルを指定することで、csv形式のファイルが作成されます。

中身はこんな感じ。

$ cat log.csv
Time,Temp ch1,Temp ch2,Pressure ch1,Pressure ch2,Humidity ch1,Humidity ch2,Lux
2018/08/08 01:14,30.6,,1002.7,,48.7,,30.8
2018/08/08 01:16,30.0,,1002.8,,50.0,,30.8

日付の表示形式イマイチなので修正します。rpz_sensor.py76行目付近を次のように修正します。

#datestr = datetime.now().strftime("%Y/%m/%d %H:%M")
datestr = datetime.now().strftime("%s")+"000"

最後に“000”をつけているのは、後ほどグラフ化する際にミリ秒で指定する必要があるための小細工です。

これで実行すると、以下のようにunixtime表示になります。

1533660686000,30.8,,1002.4,,49.6,,30.5

 

cronで定期的に実行する

無事にセンサデータを取得できるようになったので、定期的に実行できるようにcronに設定します。

まず、logファイル置き場を作っておきます。

mkdir ~/log/

設定しやすいように以下の設定ファイルを作ります。

mkdir -p ~/src/cron
vim ~/src/cron/cron-pi

cron-pi の中身はこのように。

# m h dom mon dow command
LOG_DIR="/home/pi/log"
APP1="/home/pi/src/env-monitoring/rpz-sensor/python3/rpz_sensor.py"

*/10 * * * * ${APP1} -l ${LOG_DIR}/env.$(date +\%Y\%m\%d).csv > /dev/null
  • 10分毎に記録し続けます。1日に144行分(6*24)のデータができます。
  • ファイル名に日付を入れて日ごとに別ファイルになるようにしています。

現在のcronの設定を残しておきます。

crontab -l > ~/src/cron/cron-pi.org

cronに設定します。

crontab ~/src/cron/cron-pi

設定されているか確認します

$ crontab -l
# m h dom mon dow command
LOG_DIR="/home/pi/log/"
APP1="/home/pi/src/env-monitoring/rpz-sensor/python3/rpz_sensor.py"

*/10 * * * * ${APP1} -l ${LOG_DIR}/env.$(date +\%Y\%m\%d).csv > /dev/null

これで、10分毎に計測されたデータが記録されるようになりました!

こんな感じで記録されていきます。

Time,Temp ch1,Temp ch2,Pressure ch1,Pressure ch2,Humidity ch1,Humidity ch2,Lux
1533661415000,31.4,,1002.3,,48.3,,30.5
1533661801000,31.5,,1002.3,,48.1,,30.5
1533662401000,31.6,,1002.2,,47.9,,31.0
1533663002000,31.4,,1002.0,,48.6,,0.0
1533663602000,30.6,,1001.8,,50.9,,0.0
1533664202000,30.8,,1001.6,,50.7,,0.0
1533664802000,30.0,,1001.6,,53.3,,0.0
1533665402000,30.0,,1001.7,,53.1,,0.0
1533666002000,28.9,,1001.4,,56.3,,0.0
1533666601000,28.6,,1001.5,,56.9,,0.0
1533667202000,28.7,,1001.1,,56.8,,0.0
1533667802000,28.5,,1000.9,,57.2,,0.0

 

データの可視化

データの羅列を眺めていてもつまらない(日時すらわからない)ので、わかりやすいようグラフ化していきましょう!

apache2でphp7が動くようにする

Webサーバーをインストールして動かします。

sudo apt install apache2 apache2-mod-php7.0

php7系を使いたいので、何が使えるが探してみます。

apt-cache search php7

php7.0系がずらずらっと出てくるので、使いたいモノを適当に入れます。

sudo apt install php7.0 php7.0-fpm php7.0-dev php7.0-mysql php7.0-sqlite3 php7.0-gd php7.0-mbstring php7.0-curl php-pear php7.0-mcrypt php7.0-xml php7.0-xmlrpc php7.0-zip php7.0-imap ssl-cert

インストールが終わったら、piユーザーで作業できるようにオーナーを変更して、エラー対策としてfqdn.confを作ってServerNameを指定します。

sudo chown -R pi /var/www/
cd /etc/apache2/
sudo sh -c "echo ServerName $HOSTNAME > /etc/apache2/conf-available/fqdn.conf"
sudo a2enconf fqdn
sudo systemctl reload apache2

 

canvasJSを使ってcsvデータをグラフ化する

csvでデータを取得したのでわかりやすくグラフ化します。

こちらを参考にしました。PHP Chart from CSV Data

CSVファイルをコピーしてapacheからアクセスできるようにします。

mkdir /var/www/html/log
cp /home/pi/log/env.$(date +\%Y\%m\%d).csv /var/www/html/log/ latest.csv

参考サイトに倣って以下のようなhtmlファイル(index.html)を作ります。

<!DOCTYPE html>
<html>
<head>
<title>Chart using XML Data</title>
<script type="text/javascript" src="https://canvasjs.com/assets/script/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script type="text/javascript">
    window.onload = function() {
        var dataPoints = [];
         
        function getDataPointsFromCSV(csv) {
            var dataPoints = csvLines = points = [];
            csvLines = csv.split(/[\r?\n|\r|\n]+/);         
                        
            for (var i = 0; i < csvLines.length; i++)
                if (csvLines[i].length > 0) {
                    points = csvLines[i].split(",");
                    dataPoints.push({ 
                        x: parseFloat(points[0]), 
                        y: parseFloat(points[5])                
                    });
                }
            return dataPoints;
        }
        
        $.get("http://rpi3-03p.local/log/latest.csv", function(data) {
            var chart = new CanvasJS.Chart("chartContainer", {
                    title: {
                         text: "",
                    },
                    axisX:{
                        title: "time",
                    },
                    axisY:{
                            title: "Humidity (%RH)",
                               minimum: 0,
                               maximum: 100,
                    },
                    data: [{
                         type: "area",
                         xValueType: "dateTime",
                         dataPoints: getDataPointsFromCSV(data)
                      }]
                    
             });
                
              chart.render();

        });
  }
</script>
</head>
<body>
        <div id="chartContainer" style="width:100%; height:300px;"></div>
</body>
</html>

$.get() にはログファイルを置いた場所を指定します。URL部分は自分の環境に合わせて書き換えてください。

$.get("http://rpi3-03p.local/log/latest.csv", function(data) {

Webブラウザで http://rpi3-03p.local/index.html にアクセスするとグラフが表示されます。

表示したいデータは getDataPointsFromCSV() の中にある points[] の添え字を変更すればOKです!

y: parseFloat(points[5])

1: 温度, 3: 大気圧, 5: 湿度, 7: 照度

 

まとめ: BME280とTSL2561をRaspberry 3B+につないで、温湿度・気圧、照度を24時間モニタリングできた!

今回やったことのまとめです。

  •  BME280とTSL2561をRaspberry 3B+に接続
  • raspi-configでI2CをEnable
  • RPZ-IR-Sensorのサンプルプログラムを入手
  • アドレス部分を修正
  • コマンドを実行してデータをCSV形式で保存
  • cronに設定して定期的にデータ取得
  • apache2+php7をインストール
  • canvasJSを使ってCSVデータを可視化

自宅に転がしていたラズベリーパイと数百円で手に入るセンサ基板を使って、24時間の環境モニタリング体制ができました!

また、blynkと組み合わせれば、スマホからいつでもどこでも状態がわかるようになりますね^^

それではみなさん、良いラズパイ生活を( ^o^)ノ