屋内環境を手軽にモニタリングする~④MH-Z19BからCO2濃度をJavaで取得する(シリアル通信 / jSerialComm)~


はじめに

CO2濃度を測定するセンサーとして、安価なMH-Z19Bを使用します。これはシリアル通信でデータを取得することができます。本記事では、Javaによるシリアル通信モジュールのjSerialCommを使用して、MH-Z19BからCO2濃度を取得するために作成したJavaライブラリmh-z19b-driverの概要を紹介します。といっても、Githubの内容そのままです。実装の詳細や使い方のサンプルは、Githubのコードを参照して下さい。

MH-Z19BとRaspberry Pi 3Bの接続

5V、GND、Tx、Rxを以下の通り接続します。なお、相互にTx⇔Rxで接続して下さい。

  • 6. Pins of MH-Z19B
    • Vin
    • GND
    • Tx
    • Rx
  • GPIO of Raspberry Pi 3B
    • Vin --> (2) or (4)
    • GND --> (6), (9), (14), (20), (25), (30), (34) or (39)
    • Tx --> (8) GPIO14
    • Rx --> (10) GPIO15

なお、Raspberry Pi 3BのGPIO端子の代わりに、USB接続のシリアル通信アダプタ(SH-U09C)をRaspberry Pi 3Bに挿して、これとMH-Z19Bを接続して使用することもできます。その場合、シリアル通信のポート名は、/dev/ttyUSB0になると思います。

OSの設定

Bluetoothとシリアル通信(UART)を同時に使えるようにするために、Raspbian Buster Lite OSを以下のように設定します。

  • /boot/cmdline.txt
console=serial0,115200 --> 削除します。
  • /boot/config.txt
    以下の通りに追記します。
@@ -45,7 +45,7 @@
 # Uncomment some or all of these to enable the optional hardware interfaces
 #dtparam=i2c_arm=on
 #dtparam=i2s=on
-#dtparam=spi=on
+dtparam=spi=on

 # Uncomment this to enable the lirc-rpi module
 #dtoverlay=lirc-rpi
@@ -55,6 +55,10 @@
 # Enable audio (loads snd_bcm2835)
 dtparam=audio=on

+enable_uart=1
+dtoverlay=pi3-miniuart-bt
+core_freq=250
+
 [pi4]
 # Enable DRM VC4 V3D driver on top of the dispmanx display stack
 dtoverlay=vc4-fkms-v3d

サンプルコード

mh-z19b-driverの使い方のサンプルは以下の通りです。注意点として、初回読み出しのセンサーデータは、変な値が返りますが、二回目以降は適切な値が返ります。

import io.github.s5uishida.iot.device.mhz19b.driver.MHZ19BDriver;

public class MyMHZ19B {
    private static final Logger LOG = LoggerFactory.getLogger(MyMHZ19B.class);

    public static void main(String[] args) throws IOException {
        MHZ19BDriver mhz19b = null;
        try {
            mhz19b = MHZ19BDriver.getInstance("/dev/ttyAMA0");
            mhz19b.open();
            mhz19b.setDetectionRange5000();

            while (true) {
                int value = mhz19b.getGasConcentration();
                LOG.info("co2:" + value);

                Thread.sleep(10000);
            }
        } catch (InterruptedException e) {
            LOG.warn("caught - {}", e.toString());
        } catch (IOException e) {
            LOG.warn("caught - {}", e.toString());
        } finally {
            if (mhz19b != null) {
                mhz19b.close();
            }
        }
    }
}

一連の記事

このシリーズは、以下の記事から構成されます。
1. 動機とコンセプト
2. Bluetooth LEアドバタイズ信号をJavaでキャッチする(Bluetooth LE / bluez-dbus)
 関連するGithubはこちら
3. TI SensorTag CC2650から温度/湿度/照度などをJavaで取得する(Bluetooth LE / bluez-dbus)
 関連するGithubはこちら
4. MH-Z19BからCO2濃度をJavaで取得する(シリアル通信 / jSerialComm)(今回)
 関連するGithubはこちら
5. PPD42NSからPM2.5濃度をJavaで取得する(GPIO / Pi4J)
 関連するGithubはこちら
6. 産業オートメーション機器の稼動情報をJavaで取得する(OPC-UA / Eclipse Milo)
 関連するGithubはこちら
7. 簡易ツールにまとめる
 関連するGithubはこちら
8. 後記

追記

[2019.11.16]
簡易ツールの最新情報は、こちらをご参照下さい。