rcmdnk's blog

20190826_superchart_200_200

Raspberry PiでBME280というセンサーを使って 温度、湿度、気圧を測ってスマホで見れる様にしてみます。

用意するもの

適当なRaspberry Piを用意して初期設定します。

今回必要なものは秋月電子で買うなら以下のもの:

これ以外にRaspberry Pi用のmicroSDがなければ必要。

Raspberry Pi Zeroはスマホに使うようなmicro USB用の充電器でも使えますが、 ACアダプターも買っておくと安心です。

BME280

BME280は温度、湿度、気圧センサーで、 これを使ってRaspberry Piでそれらを測ってみます。

BME280使用 温湿度・気圧センサモジュールキット: センサ一般 秋月電子通商-電子部品・ネット通販

ピンヘッダ付きのモジュールキットが秋月電子で1080円。

これはAmazonとかでも売ってます。

湿度センサのないBMP280というのもあるのでちょっと注意

これ以外だとDHT11という温度、湿度センサーが付いたものがよく使われてる感じでした。

以下のページの比較が参考になります。

第5回 温度と湿度を測定するセンサ Electronic DIY with Arduino

今回はせっかくなので気圧も測ろうということと読み込みのコードの例などが豊富にありそうだったので、 BME280を使いました。

BME280のハンダ付け

BME280のモジュールセットにはセンサが載ってる基盤とピンヘッダがセットで入ってますが、 これははんだ付けしないといけません。

ハンダ付け道具を持ってなかったので、ダイソーで500円のハンダごてと 100円のハンダを買ってきました。

20190826_handa.jpg

まあ、今後色々やるならちゃんとしたの買った方が良さそうですが、とりあえずのハンダ付けは出来ます。 (スポンジと入れておけるカップみたいのを準備しておく。)

ただ、はんだ取り線か吸引器は買っておきたいところでした。

ともかく、 ピンヘッダは8ピンあるので8ピン分をニッパーとかで切り取ります。

で、短い方を穴に入れてピンが外側に出るようにして裏側でハンダ付け。

20190826_bme280.jpg

ひどい。。。ちゃんと使うときはやり直します。

Raspberry Piの準備

適当なRaspberry Piを用意して初期設定します。

Raspberry Pi Zero WHを使っています。

セットアップ

Raspberry PiとBME280を接続します。

今回も全開のLチカに引き続きブレッドボードを用いてとりあえずの接続で試します。

BME280はI2CとSPIの2つの通信方法を選ぶことが出来ますが、 今回はI2C通信を選びます。 I2C通信にする場合、説明書では基板上のJ3の部分をハンダでつなぐ、 とありますが、下にもあるようにBME280の左から3番目のピンをVDD (3.3V)につなぐと 同じ状態に出来るので今回はそれを利用します。

BME280のモジュールからは6本のピンが出ています。

20190826_bme280front.jpg

これをそれぞれ

BME280 Raspberry Pi GPIO
VDD PIN 1 (3.3V)
GND PIN 6 (GND)
CSB PIN 17 (3.3V)
SDI PIN 3 (SDA.1)
SDO PIN 14 (GND)
SCK PIN 5 (SCL.1)

という感じでつなぎます。 5番目のピンをグラウンドにすることでI2Cのアドレスが0x76になります。 これをVDD(3.3V)にすると0x77になります。

20190826_setting.jpg

以下のサイトを参照しました。

Raspberry PiとBME280モジュールで自動で温度・湿度・気圧を測定してグラフ化する - karaage. [からあげ]

モジュールをブレッドボードに挿して あとはジャンパでつなぐだけです。

Raspberry PiのI2Cを有効にする

Raspberry PiではデフォルトでI2C通信が有効になっていないため これを有効にします。

これにはraspi-configというコマンドを使います。

pi@raspberrypi:~ $ sudo raspi-config

これで色々と変更するためのRaspberry Pi Software Configuration Toolが立ち上がるので、そこから

5 Interfacin Options

に進み、さらに

P5 I2C

を選択し、Would you like the APM I2C interface to be enabled?と聞かれたYesの方を選択します。

出来たら一度再起動

pi@raspberrypi:~ $ sudo reboot

BME280の接続確認

lsmodコマンドで認識されてるかどうかチェック:

pi@raspberrypi:~ $ lsmod
...
i2c_bcm2835             7818  185
...

こんな感じでi2c_bcm2835が見えてることを確認。

アドレスを確認するためにi2c-toolsをインストールしてみます。

pi@raspberrypi:~ $ sudo apt install i2c-tools

コレを使って

pi@raspberrypi:~ $ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- 76 --

こんな感じで0x76にi2c接続されてることがわかります。

測定

Pythonスクリプト例

Raspberry Piなども含めいろいろな電子機器を販売している スイッチサイエンスがサンプルプログラムを提供してくれているのでそれを使ってみます。

Python2.7用のサンプルコードが入っているので使ってみます。

pi@raspberrypi:~ $  git clone https://github.com/SWITCHSCIENCE/samplecodes.git
pi@raspberrypi:~ $  cd ~/samplecodes/BME280/Python27
pi@raspberrypi:~/samplecodes/BME280/Python27 $ ls
bme280_sample.py  requirements.txt
pi@raspberrypi:~/samplecodes/BME280/Python27 $ sudo pip install -r requirements.txt
...
pi@raspberrypi:~/samplecodes/BME280/Python27 $ python bme280_sample.py
temp : 24.74  ℃
pressure : 1009.65 hPa
hum :  59.04 %

こんな感じで温度と気圧、湿度を取得することが出来ました。

C言語例

C言語の例としては以下のものがシンプルでわかりやすかったので使ってみました。

必要なライブラリをインストール:

pi@raspberrypi:~ $ sudo apt install libi2c-dev i2c-tools wiringpi

そして

pi@raspberrypi:~ $ git clone https://github.com/andreiva/raspberry-pi-bme280.git
pi@raspberrypi:~ $ cd ~/raspberry-pi-bme280
pi@raspberrypi:~/raspberry-pi-bme280 $ make
gcc -g -Wall -Wextra -pedantic -std=c11 -D_DEFAULT_SOURCE -D_BSD_SOURCE -o bme280 bme280.c -lwiringPi -lm
pi@raspberrypi:~/raspberry-pi-bme280 $ ./bme280
{"sensor":"bme280", "humidity":70.19, "pressure":1010.35, "temperature":26.69, "altitude":22.06, "timestamp":15XXXXXXXX}

という感じでJSON形式での出力を出してくれます。

こちらではaltitudeということで標高が表示されていますが、 コードを見てみると

bme280.h
1
#define MEAN_SEA_LEVEL_PRESSURE       1013
bme280.c
1
2
3
4
5
6
7
8
9
10
float getAltitude(float pressure) {
  // Equation taken from BMP180 datasheet (page 16):
  //  http://www.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf

  // Note that using the equation from wikipedia can give bad results
  // at high altitude.  See this thread for more information:
  //  http://forums.adafruit.com/viewtopic.php?f=22&t=58064

  return 44330.0 * (1.0 - pow(pressure / MEAN_SEA_LEVEL_PRESSURE, 0.190294957));
}

となっていて、気圧から計算するようになってるので平均的な気圧のときに 正しい標高が出るようになっています。

Blynkを使ってスマホモニターを作る

Raspberry Pi上で測定できるようになったのでそれをスマホから見える様に してみます。

使うのはBlynkというサービス/アプリです。

今回はSuper Chartというリッチなチャートを使います。 ENERGY BALANCEを900使うので無料分全体2000の半分くらい使ってしまいますが、 複数の値を同時に載せられるのでこれを使って温度、湿度、気圧のチャートを表示してみます。

まずは上の記事に従ってスマホでBlynkアプリをインストールし、 適当なプロジェクトを作成します。

次にRaspberry Pi側で blynkkk/blynk-library を取ってきてきます。

pi@raspberrypi:~ $  git clone https://github.com/blynkkk/blynk-library.git

これとは別に上で使った raspberry-pi-bme280のファイルを使います。

pi@raspberrypi:~ $  git clone https://github.com/andreiva/raspberry-pi-bme280.git

取ってきたら blynk-librarylinuxというディレクトリで作業します。

pi@raspberrypi:~ $  cd blynk-library/linux
pi@raspberrypi:~/blynk-library/linux $ cp ~/raspberry-pi-bme280/bme280/bme280.c ./bme280.cpp
pi@raspberrypi:~/blynk-library/linux $ cp ~/raspberry-pi-bme280/bme280/bme280.h ./bme280.h

Blynk側はC++なのでcppに変更してしまいます。

関数だけ使いたいのでbme280.cppの中のmain関数を全てコメントアウトしておきます。

次に、Blynkのmain.cppへの変更。

includeファイルとして

main.cpp
1
2
#include "stdio.h"
#include <stdlib.h>

を追加。

bme280.cppのmain関数をベースに情報を抜き出す関数をmain.cppの中に追加します。

main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void bme280chart(){
  int fd = wiringPiI2CSetup(BME280_ADDRESS);
  if(fd < 0) {
    printf("BME280 Device not found");
  }

  bme280_calib_data cal;
  readCalibrationData(fd, &cal);

  wiringPiI2CWriteReg8(fd, 0xf2, 0x01);
  wiringPiI2CWriteReg8(fd, 0xf4, 0x25);

  bme280_raw_data raw;
  getRawData(fd, &raw);

  int32_t t_fine = getTemperatureCalibration(&cal, raw.temperature);
  float t = compensateTemperature(t_fine);
  float p = compensatePressure(raw.pressure, &cal, t_fine) / 100;
  float h = compensateHumidity(raw.humidity, &cal, t_fine);

  Blynk.virtualWrite(V20,  t);
  Blynk.virtualWrite(V21,  h);
  Blynk.virtualWrite(V22,  p);
}

void myTimerEvent(){
  bme280chart();
}

最後のBlynk.virtualWriteというところで バーチャルPINの20~22番に書き出すようにしています。

最後のmyTimerEventは後で他のイベントも追加できるようにするための ラッパー関数です。

Super Chartではこの様に書き出す作業を定期的にRaspberry Pi側で行い、 これを受け取る、という受動的な形式になります。

これを定期的にRaspberry Pi側で行うために、 main.cpp内のsetup[関数を以下の様に変更します。

main.cpp
1
2
3
4
5
6
7
8
 void setup()
 {
     Blynk.begin(auth, serv, port);
-    tmr.setInterval(1000, [](){
-      Blynk.virtualWrite(V0, BlynkMillis()/1000);
-    });
+    tmr.setInterval(1000, myTimerEvent);
}

もともと1000ms毎に、V0に対して定期的にBlynkMillisという現在時刻のミリ秒(を1000で割って秒)を 渡す関数がtmr.setIntervalに渡される例が入っていますが、 それと入れ替えで、myTimerEventを登録します。

これで毎秒、温度、湿度、気圧を測定して20~22のバーチャルPINへ登録が行われます。 これらの記録はBlynkサーバーに送られてアカウントの元管理されます。

ちなみにBlynk.virtualWriteに関しては1秒に10個より多くの値は送らないでください、との 注意書きがBlynkのサイトにありました 1

最後にMakefileにbme280を含めるようにします。

Makefile
1
2
3
4
5
6
7
8
9
10
11
12
diff --git a/linux/Makefile b/linux/Makefile
index d014e98..f4a46e9 100644
--- a/linux/Makefile
+++ b/linux/Makefile
@@ -51,6 +51,7 @@ ifeq ($(target),raspberry)
 endif

 SOURCES=main.cpp \
+ bme280.cpp \
  ../src/utility/BlynkDebug.cpp \
  ../src/utility/BlynkHandlers.cpp \
  ../src/utility/BlynkTimer.cpp

準備ができたら

pi@raspberrypi:~/blynk-library/linux $ make

して

pi@raspberrypi:~/blynk-library/linux $ sudo ./blynk --token=<YourToken>

とかして実行します。

これでサーバー側に毎秒情報が送られます。

これでRaspberry Pi側の準備ができたので アプリでチャートを準備します。

まずはWidget BoxからSuper Chartを選択して設置します。

20190826_widgetbox.jpg

Super Chartの設定ではDATASTREAMSの項目に 温度、湿度、気圧、を追加。

20190826_superchartsetting1.jpg 20190826_superchartsetting2.jpg

X軸の値の表示などの設定もしておきます。

次に、温度などの各項目の右側のボタンを押して設定に入り、 INPUTとしてVirtual PINの20から22をそれぞれ選びます。

20190826_supercharttemperature1.jpg 20190826_supercharttemperature2.jpg

MIN/MAXを適当に選び、SUFFIXもわかりやすく記入。

下の方にあるY-AXIS VALUESSHOWにしておきます。

各値については

測定値 温度 湿度 気圧
PIN V20 V21 V22
MIN 20 40 990
MAX 30 80 1010
SUFFIX % hPa

となってます。

これでRaspberry Piに接続すれば値が見れるはずです。 最初は値が過去分十分ないのでLiveで、しばらくすると長期間分見ることができます。 アプリを立ち上げていなくてもサーバー側に情報が保存されるのでRaspberry Pi側でblynkが動いていた分だけの情報を見ることができます。 (実際どれだけの情報が保存できるのかはちょっと調べられてません。)

半日分くらいのチャートがこちら。

20190826_superchart.jpg

帰宅後にエアコンを付けて温度が下がって、外出中はエアコンを切ってるのでちゃんと上がってる様子がわかります。

参考文献

上にも書いた今回参考にしたセットアップ:

第5回 温度と湿度を測定するセンサ Electronic DIY with Arduino

SPI通信を使った例(各データの説明などが細かくてわかりやすい):

ツール・ラボ » 第35回 温湿度・気圧センサ(BME280) 〜データ取得プログラム〜

I2CでLuaを用いたコード例:

BME280を用いた NodeMCUの温湿度・気圧測定 プログラム TomoSoft

スイッチサイエンスによる説明ページ:

BME280 – スイッチサイエンス

スイッチサイエンスによるPythonコード例(Arduino用になってますがC++の例もあります):

BME280ディレクトリの中にPython2.7用(I2C用)の例とArduino用のC++の例があります。

C言語によるシンプルなI2C用ドライバ実装:

まとめ

BME280のモジュールはハンダ付けしないといけないのでちょっと敷居が高いですが、 それさえできればあとは他に抵抗とか何もなしで簡単にRaspberry Piに取り付ける事ができます。

読み出しに付いても十分なサンプル例があるのでそれを使って簡単に読み出すことが出来ます。

また、Blynkを使えばこれも簡単にスマホでモニタリングすることも出来るようになります。

これを使えば、何度以上になったらエアコンを付ける、などと言ったことも 可能になってきます。

Sponsored Links
Sponsored Links

« Raspberry PiでLチカする Windows用のマウスの買い替え: Logicool G703h »

}