Hobby Science&Experiment

愛と工作の日々

趣味でやっている工作や勉強したことのメモ書きです。

BlynkでRaspberry Pi3+のCO2センサー測定値を取得

Blynkは各種IoTデバイスに対してスマホ等外部のデバイスから相互に通信を行えるシステムのことです。今回はBlynkを利用して、Raspberry Pi3+にアクセスしCO2センサー測定値を取得します。Lチカでも大変お世話になったこちらの記事を参考にし手順を進めました。
blog.livedoor.jp

難易度:☆★★★★
新規性:☆★★★★
有用性:☆☆☆★★

準備

Blynkスマホアプリ側の準備

Blynkアプリをスマホにインストールし、新規プロジェクトを作成しトークンを入手しておきます。
BlynkのRaspberry Piへのインストールに関してはこちらの記事にまとめました。

配線

ラズパイとCO2センサー(MH-Z19B)のRXとTXをクロスにして接続します。詳細はこちらの記事にまとめました。

CO2センサー側 ラズパイ側
GND
GND
VCC
5VO
RX
TXD0(14pin)
TX
RXD0(15pin)

※pinはGPIO番号です。

main.cppの書換え

main.cppはBlynkライブラリに含まれるソースファイルです。vimでmain.cppの中身を書き換えます。cppとはC++固有の拡張子らしいです。

pi@raspberrypi:~ $ cd blynk
pi@raspberrypi:~/blynk $ cd blynk-library/linux
pi@raspberrypi:~/blynk/blynk-library/linux $ sudo vi main.cpp

この中で次の行を探し出し、

BLYNK_WRITE(V1)
{
  printf("Got a value: %s\n", param[0].asStr());
}

次のコードに置き換えます。参考記事のまんまで使用させて頂いてます。

void blynk_read_exec(int pin) {
  char command[256] = "";
  char buff[256] = "";
  FILE *fp;
  sprintf(command, "/home/pi/blynk/BLYNK_READ_V%d.sh", pin);
  if((fp=popen(command,"r")) != NULL) {
    if(fgets(buff, 255, fp) != NULL) strtok(buff, "\n\0");
  }
  pclose(fp);
  Blynk.virtualWrite(pin, buff);
  BLYNK_LOG("Command: %s -> %s", command, buff);
}

void blynk_write_exec(int pin, const BlynkParam& param) {
  char command[256] = "";
  char buff[256] = "";
  sprintf(command, "/home/pi/blynk/BLYNK_WRITE_V%d.sh", pin);
  for (int i=0; i<3; i++) {
    if(! param[i].isValid()) break;
    sprintf(buff, " %d", param[i].asInt());
    strcat(command, buff);
  }
  BLYNK_LOG("Command: %s", command);
  system(command);
}

BLYNK_READ(V0) { blynk_read_exec(V0); }
BLYNK_READ(V1) { blynk_read_exec(V1); }
BLYNK_READ(V2) { blynk_read_exec(V2); }
BLYNK_READ(V3) { blynk_read_exec(V3); }
BLYNK_READ(V4) { blynk_read_exec(V4); }
BLYNK_READ(V5) { blynk_read_exec(V5); }
BLYNK_READ(V6) { blynk_read_exec(V6); }
BLYNK_READ(V7) { blynk_read_exec(V7); }
BLYNK_READ(V8) { blynk_read_exec(V8); }
BLYNK_READ(V9) { blynk_read_exec(V9); }
BLYNK_WRITE(V10) { blynk_write_exec(V10,param); }
BLYNK_WRITE(V11) { blynk_write_exec(V11,param); }
BLYNK_WRITE(V12) { blynk_write_exec(V12,param); }
BLYNK_WRITE(V13) { blynk_write_exec(V13,param); }
BLYNK_WRITE(V14) { blynk_write_exec(V14,param); }
BLYNK_WRITE(V15) { blynk_write_exec(V15,param); }
BLYNK_WRITE(V16) { blynk_write_exec(V16,param); }
BLYNK_WRITE(V17) { blynk_write_exec(V17,param); }
BLYNK_WRITE(V18) { blynk_write_exec(V18,param); }
BLYNK_WRITE(V19) { blynk_write_exec(V19,param); }

vimへコピペすると先頭行が消えたりしたのですが、テキストエディタ等に一度張り付けてダミーの行を加えてやりました。

この書き換え操作によりBlynkでバーチャルピンのX番をONにした際に、"/home/pi/blynk/BLYNK_WRITE_VX.sh"シェルスクリプトファイルが実行されることになります。今後新しいバーチャルピンに機能をアサインする際、main.cppを弄る必要がなくなりました。凄い!
もう一つ私にとって大いに助かる点は、間接的にpythonファイルを扱えるようになったということですね。

動作確認

今までの操作に問題がなかったかを確認してみます。参考記事に載っているCPU温度取得を試してみます。
blynkディレクトリにBLYNK_READ_V0.shを作成します。

pi@raspberrypi:~ $ cd blynk
pi@raspberrypi:~/blynk $ sudo vi BLYNK_READ_V0.sh

次のように記入し保存します。

#!/bin/sh
data=`cat /sys/class/thermal/thermal_zone0/temp | awk '{printf($1/1000)}'`
printf "%3.1f" $data

作成したシェルスクリプトファイルに権限を与えます。Linuxでのshファイル実行にはこの操作が必要なようです(参考)。

pi@raspberrypi:~/blynk $ chmod 700 BLYNK_READ_V0.sh

BLYNK_READ_V0.shを作成しましたので、アプリ側でV0ピンをONにすればこのファイルが実行されるはずです。
LXTerminalでBlynkを起動します。

$ cd blynk
$ cd blynk-library/linux
$ sudo ./blynk --token=<トークン>

スマホのBlynkアプリでプロジェクトを開き、Widget BoxからValue Displayを選択します。
Value Displayのセッティング画面でINPUTをVirtualピンの0番、すなわちV0を選択し、READING RATEを適当な値に設定します。
プロットする場合はSuperChartを選択し、+Add Datastream→INPUTをV0に設定します。
▷ボタンを押せばBlynkサーバーとの通信が始まります。成功すればCPUの温度がスマホで確認できるはずです。

CO2センサーの値を取得する

以前の記事pythonスクリプトでCO2センサーの値を取得したので、こちらを流用したいと思います。
co2.pyという名前で、任意の場所に次の内容のファイルを保存します。

import mh_z19
co2 = mh_z19.read_all()["co2"]
print(co2)

次にBlynkディレクトリに以下の内容のファイルを保存します。

python3 /home/pi/co2.py

ここではファイル名をBLYNK_READ_V1.shとしました。パス部分はco2.pyの保存場所に合わせて適宜変更してください。
最後に作成したシェルスクリプトに権限を付与します。

pi@raspberrypi:~/blynk $ chmod 700 BLYNK_READ_V1.sh

これで準備は完了です。BlynkアプリでV1ピンをONにすればCO2濃度が取得できます。
f:id:tara-chang:20200509214328p:plain