LoginSignup
19
18

More than 5 years have passed since last update.

BluemixでRaspberryPi2のセンサーデータを拾う (5)センサーを付けてデータを拾う 温度・湿度・気圧まとめて採取編

Posted at

概要

BluemixのRaspberryPi登録レシピに登場するデバイス用のsampleプログラムは、どんなにセンサーがたくさん付いていようが固定の4項目のデータのみをBluemixに送信する作りになっている。

Raspberry Pi 2にセンサーを付け加えて固定4項目以外のデータをBluemixで取得するには、sampleプログラムのソースコードを修正してビルドすれば良い。その方法を整理する。

整理している内に長くなってきたので、(1)Sampleプログラムの仕組みの整理と(2)どこをどのように変更すればよいのかを分けることにした。

(1) 仕組みの理解
(2) センサーを付けてデータを拾う 温度センサーデジタル編
(3) センサーを付けてデータを拾う 温度センサーアナログ編
(4) センサーを付けてデータを拾う 温度センサーデジタル編(リベンジ)
(5) センサーを付けてデータを拾う 温度・湿度・気圧まとめて採取編 (これ)
番外編 『ムック「日経Linux ラズパイマガジン 2015年春号 」電子工作入門キット パーツセット』に入っていたもの

今回のポイント

ポイント1:複数のデータを纏めて採取する

センサーを色々手に入れたつもりが実は温度センサーしか持っていないことが判明したので、
他のセンサーを試してみることにした。
以下の条件に見合うセンサーを探した結果、温度・湿度・気圧の3つのデータを採取可能な『BME280搭載 温湿度・気圧センサモジュール』というものを使うことにした。
 選定条件1:生活に密着したデータを採取できる(身近なところで気軽にデータを採取したい)
 選定条件2:放置しておくだけで、人がいなくても動きのあるデータを得たい(楽してデータを採取したい)
 選定条件3:Raspberry Pi 2で動く(or動きそう)という事例がある
 選定条件4:見た目やサイズ感がシンプルで小さい
 選定条件5:手ごろな値段

ポイント2:はんだ付けから逃げない

『BME280搭載 温湿度・気圧センサモジュール』「姉妹商品としてピンヘッダ実装済の物もある」とのことだが、「はんだづけカフェ」の存在を知ってしまったことと選定条件5(手ごろな値段)を考慮して、ピンヘッダ未実装の方を選択した。
(実際は差額の324円よりはんだづけカフェへの往復の交通費の方が高かった。。。)

ポイント3:複数のデータを纏めてBluemixで確認

同時に採取するデータが増えた際に、RasPi上のソースコードやBluemix上のNode-REDの定義で何を増やせばよいかを実際に作って確認する。

回路(ネタ)

今回はこちら↓をやってみる。
http://qiita.com/masato/items/027e5c824ae75ab417c1

過去にExcelで作った回路を真似して同じような書きっぷりで描いてみた。(Excelで作図)
温度・湿度・気圧を測定するための回路.png

回路(設計)

元ネタの図の通りにFritzingで作ってみた。
BME280のパーツはここからから入手して、Fritzingにインポートした。
https://sites.google.com/site/takafuminakahrm1017/fritzing/
BME280 Barometric Pressure, Temperature and Humidity Sensor .fzpz
(ファイル名に空白を含む様なので注意)
温度・湿度・気圧を測定するための回路.png

回路(実装)

Fritzingで作った絵の通りにつなげてみた。
BME280は、当然はんだ付けしてある ←ポイント2
温度・湿度・気圧デジタル_回路(実装).jpg

Raspberry Pi 2上でI2Cの有効化

作業はRaspberry Pi 2にログインして行う。
実行時ユーザは次の通り
$ : pi
# : root

WiringPiの導入

# cd /var/tmp
# git clone git://git.drogon.net/wiringPi
# cd wiringPi
# ./build

導入確認のためにバージョンを確認してみる。
# gpio -v
IMG_3201.png
バージョンが表示されること。

I2C有効化

Raspberry Pi 2はraspi-configから設定する。
# raspi-config

「8 Advanced Options」を選択して、「Select」を押下
I2C有効化1.png

「A7 I2C」を選択して、「Select」を押下
I2C有効化2.png

「はい」を押下
I2C有効化3.png

「了解」を押下
I2C有効化4.png

「はい」を押下
I2C有効化5.png

「了解」を押下
I2C有効化6.png

「Finish」を押下。どれが選択されていても良い。
I2C有効化7.png

「はい」を押下。再起動される。
I2C有効化8.png

再起動後にI2C用のモジュールが読み込まれていることを確認する。
$ lsmod | grep i2c
「i2c_bcm2708」が表示されること。

I2C用ツールのインストール

# apt-get -y install i2c-tools
# reboot

デバイスのアドレス確認

# i2cdetect -y 1

IMG_3203.png
アドレス(76)が表示されること。

PythonからI2Cバスをコントロールするためのツールのインストール

# apt-get -y install python-smbus

IMG_3205.png

Raspberry Pi 2上で気温・気圧・湿度を読んでみる

参考サイトの通りに、スイッチサイエンスのBMEリポジトリにあるpythonのサンプルコード「bme280_sample.py」をダウンロード・実行してみる。
画面に気温・気圧・湿度をまとめて出力する。
実行にはroot権限が必要

$ mkdir -p ~/bin
$ cd ~/bin
$ wget https://raw.githubusercontent.com/SWITCHSCIENCE/BME280/master/Python27/bme280_sample.py
$ ll bme280_sample.py
$ sudo python ./bme280_sample.py

IMG_3206.png

画面出力例)

temp : 25.59  ℃
pressure : 1007.20 hPa
hum :  54.82 %

temp   : 気温
pressure : 気圧
hum   : 湿度

Raspberry Pi 2上で気温・気圧・湿度を個別に読んでみる

3つのデータを個別に読めるようにするため、サンプルコード「bme280_sample.py」を手直しして以下の3つのプログラムを作成する。

$ cd ~/bin
$ cp bme280_sample.py bme280_temp.py
$ cp bme280_sample.py bme280_presssure.py
$ cp bme280_sample.py bme280_hum.py
$ vi bme280_temp.py
$ vi bme280_presssure.py
$ vi bme280_hum.py

IMG_3207.png

気温を取得するプログラム

bme280_temp.py(修正前 69~71行目)
    compensate_T(temp_raw)
    compensate_P(pres_raw)
    compensate_H(hum_raw)
bme280_temp.py(修正後)
    compensate_T(temp_raw)
    # compensate_P(pres_raw)
    # compensate_H(hum_raw)
bme280_temp.py(修正前 103行目)
    print "temp : %-6.2f ℃" % (temperature) 
bme280_temp.py(修正後)
    print "%-6.2f" % (temperature) 

気圧を取得するプログラム

bme280_presssure.py(修正前 69~71行目)
    compensate_T(temp_raw)
    compensate_P(pres_raw)
    compensate_H(hum_raw)
bme280_presssure.py(修正後)
    # compensate_T(temp_raw)
    compensate_P(pres_raw)
    # compensate_H(hum_raw)
bme280_presssure.py(修正前 95行目)
    print "pressure : %7.2f hPa" % (pressure/100)
bme280_presssure.py(修正後)
    print "%7.2f" % (pressure/100)

湿度を取得するプログラム

bme280_hum.py(修正前 69~71行目)
    compensate_T(temp_raw)
    compensate_P(pres_raw)
    compensate_H(hum_raw)
bme280_hum.py(修正後)
    # compensate_T(temp_raw)
    # compensate_P(pres_raw)
    compensate_H(hum_raw)
bme280_hum.py(修正前 117行目)
    print "hum : %6.2f %" % (var_h)
bme280_hum.py(修正後)
    print "%6.2f" % (var_h)

実行してみる。
それぞれ画面に気温・気圧・湿度を個別に出力する。
実行にはroot権限が必要

$ cd ~/bin/
$ ll bme280_temp.py bme280_pressure.py bme280_hum.py
$ sudo python ./bme280_temp.py
$ sudo python ./bme280_pressure.py
$ sudo python ./bme280_hum.py

IMG_3208.png

プログラムの改修内容

BluemixのRaspberryPi登録レシピに登場するデバイス用のsampleプログラムを次の通り修正する。
修正前のソースコードはこちらで参照可能

修正するファイル 新規で追加するファイル
iotmain.c
iot.h
jsonator.c
Makefile
bme280.c

追加・修正内容は以下の通り。

修正内容1

iotmain.c(修正前 61行目)

iotmain.c(修正後)
//bme280_temp.py
float getBme280Temp();

//bme280_pressure.py
float getBme280Pressure();

//bme280_hum.py
float getBme280Hum();

修正内容2

iotmain.c(修正前 152~153行目)
        JsonMessage json_message = { DEVICE_NAME, getCPUTemp(), sineVal(
                MIN_VALUE, MAX_VALUE, 16, count), GetCPULoad() };
iotmain.c(修正後)
        JsonMessage json_message = { DEVICE_NAME, getCPUTemp(), sineVal(
                MIN_VALUE, MAX_VALUE, 16, count), GetCPULoad(), getBme280Temp(), getBme280Pressure(), getBme280Hum() };

修正内容3

iot.h(修正前 22~27行目)
  struct json {
      char myname[100];
      float cputemp;
      float sine;
      float cpuload;
  };
iot.h(修正後)
  struct json {
      char myname[100];
      float cputemp;
      float sine;
      float cpuload;
      float bme280temp;
      float bme280pressure;
      float bme280hum;
  };

修正内容4

jsonator.c(修正前 50行目)

jsonator.c(修正後)
    strcat(jsonReturned, ",");

    strcat(jsonReturned, "\"bme280temp\":");
    sprintf(buffer, "%.2f", passedrpi.bme280temp);
    strcat(jsonReturned, buffer);
    strcat(jsonReturned, ",");

    strcat(jsonReturned, "\"bme280pressure\":");
    sprintf(buffer, "%.2f", passedrpi.bme280pressure);
    strcat(jsonReturned, buffer);
    strcat(jsonReturned, ",");

    strcat(jsonReturned, "\"bme280hum\":");
    sprintf(buffer, "%.2f", passedrpi.bme280hum);
    strcat(jsonReturned, buffer);

修正内容5

Makefile(修正前 12~14行目)
iot: iotmain.c cpustat.c mac.c mqttPublisher.c jsonator.c iot.h jsonReader.c
    export LIBRARY_PATH=$(COMPILELIBDIR):$(LIBRARY_PATH)
    $(CC) iotmain.c cpustat.c mac.c mqttPublisher.c jsonator.c cJSON.c jsonReader.c -o $@ -l$(LIBNAME) -lpthread -lssl -lm -L $(COMPILELIBDIR) -I .
Makefile(修正後)
iot: iotmain.c cpustat.c mac.c mqttPublisher.c jsonator.c iot.h jsonReader.c bme280.c
    export LIBRARY_PATH=$(COMPILELIBDIR):$(LIBRARY_PATH)
    $(CC) iotmain.c cpustat.c mac.c mqttPublisher.c jsonator.c cJSON.c jsonReader.c bme280.c -o $@ -l$(LIBNAME) -lpthread -lssl -lm -L $(COMPILELIBDIR) -I .

追加内容1

bme280.c
#include <stdio.h>
#include <stdlib.h>
#define BUF 256

float getBme280Temp();
float getBme280Pressure();
float getBme280Hum();

float getBme280Temp(){
    FILE    *fp;
    char    *cmdline = "python /home/pi/bin/bme280_temp.py";
    if ( (fp=popen(cmdline,"r")) ==NULL) {
        perror ("can not exec commad");
        exit(EXIT_FAILURE);
    }
    char buf[BUF];
    fgets(buf, sizeof(buf), fp);
    (void) pclose(fp);

    return atof(buf);
}

float getBme280Pressure(){
    FILE    *fp;
    char    *cmdline = "python /home/pi/bin/bme280_pressure.py";
    if ( (fp=popen(cmdline,"r")) ==NULL) {
        perror ("can not exec commad");
        exit(EXIT_FAILURE);
    }
    char buf[BUF];
    fgets(buf, sizeof(buf), fp);
    (void) pclose(fp);

    return atof(buf);
}

float getBme280Hum(){
    FILE    *fp;
    char    *cmdline = "python /home/pi/bin/bme280_hum.py";
    if ( (fp=popen(cmdline,"r")) ==NULL) {
        perror ("can not exec commad");
        exit(EXIT_FAILURE);
    }
    char buf[BUF];
    fgets(buf, sizeof(buf), fp);
    (void) pclose(fp);

    return atof(buf);
}

プログラムの改修手順

作業はRaspberryPi2にログインして行う。
実行時ユーザは次の通り
$ : pi
# : root

  1. 設定ファイルの退避
    # cd /etc/iotsample-raspberrypi/
    # cp -p device.cfg device.cfg.`date +%Y%m%d`_1
    ※これで、アンインストール(dpkg -P)してもフォルダとバックアップファイルが残るので安心。

  2. 必要パッケージのインストール
    # apt-get install dpkg-dev build-essential devscripts
    # apt-get install libssl-dev

  3. ソースコード一式を入手
    $ cd ~
    $ git clone https://github.com/ibm-messaging/iot-raspberrypi.git

  4. ソースコード修正・追加
    $ cd ~/iot-raspberrypi/samples/c/
    $ vi iotmain.c
    $ vi iot.h
    $ vi jsonator.c
    $ vi Makefile
    $ vi bme280.c

  5. ビルド
    $ debuild -b
    署名のエラーは無視する。

iotサービスの再インストール

  1. アンインストール(古いのを)
    # dpkg -P iot

  2. インストール
    # cd /home/pi/iot-raspberrypi/samples/
    # dpkg -i ./iot_1.0-1_armhf.deb

  3. サービスの確認
    # service iot status
    ※起動している(okが表示される)こと。

  4. 設定ファイル作成
    # cd /etc/iotsample-raspberrypi/
    # cp -p device.cfg.`date +%Y%m%d`_1 device.cfg
    ※6.でいったん削除されてしまうので、1.で退避したファイルで復元

  5. サービスの再起動
    # service iot restart
    ※起動している(okが表示される)こと。

  6. 起動モードの確認
    # service iot getdeviceid
    ※registerd mode で起動している(registerd modeが表示される)こと。

Bluemix IoT Foundationサービスで確認

IoT Foundationのダッシュボードで、センサー情報欄にて確認する。
センサーの温度データを受信できた!
BluemixでBME280の気温・気圧・湿度を表示.png

所感

BME280のデータをC言語で採取する方法が分からず、先駆者のpythonサンプルが標準出力に出力する情報をCで拾う形にした。
pythonは初めて触った。
コマンドの出力(返り値ではなく標準出力)をCで拾う方法が分かったので、できることが随分広がったと思う。

環境

Raspberry Pi 2 Model B
Raspbian
BME280搭載 温湿度・気圧センサモジュール

参考

Fritzingダウンロード
http://fritzing.org/download/

Fritzing用のBME280のパーツ
https://sites.google.com/site/takafuminakahrm1017/fritzing/
BME280 Barometric Pressure, Temperature and Humidity Sensor .fzpz
(ファイル名に空白を含む様なので注意)

はんだづけカフェ
http://handazukecafe.com/

popenでコマンドの出力を読み込む
http://kaworu.jpn.org/c/popenでコマンドの出力を読み込む

C言語アプリケーションに Pythonを組み込む
http://d.hatena.ne.jp/Wacky/20060103/1136292735

Google (検索文字列:python C言語 popen())
https://www.google.co.jp/search?q=python+C言語+popen()

Python3の文字列について。%記法とformat()記法の対応関係
http://auewe.hatenablog.com/entry/2013/10/16/083627

19
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
18