RaspberryPiでCO2濃度を測定してみた
最近会社で頭がぼーっとしたり体調が悪くなったりする機会が多かったので、いろいろ調べてみたら執務室のCO2濃度が高いのが原因なのでは?と思い、RaspberryPiでCO2濃度を測ってみようと思いました。インターネットにたくさん情報が転がっていたのでほぼ素人の私でも割と簡単に測定できました。備忘として残しておきます。
ハード情報
RaspberryPi 3 Model B
測定基盤。元から持ってたものを使用。 OSはraspbian buster lite。
$ lsb_release -a No LSB modules are available. Distributor ID: Raspbian Description: Raspbian GNU/Linux 10 (buster) Release: 10 Codename: buster
MH-Z19
CO2濃度測定センサ。AliExpressで購入。到着まで1ヶ月程度かかりましたが、1500円程度と安価で購入できました。 ja.aliexpress.com
ブレッドボード EIC−801
ラズパイとMH-Z19Bをつなぐためのボード。秋月電子通商で購入。 akizukidenshi.com
キャラクタ液晶ディスプレイモジュール完成品
CO2濃度を表示するディスプレイ。秋月電子通商で購入。 akizukidenshi.com
ブレッドボード・ジャンパーワイヤ(オス−メス) 15cm(黒) (10本入)
ラズパイとMH-Z19をつなぐワイヤー。秋月電子通商で購入。
ラズパイとMH-Z19B・キャラクタディスプレイの接続
ラズパイのGPIOの構成は以下公式サイトの通り。あまりよくわかっていないが、いろいろなサイトに情報が転がっている。
ラズパイとMH-Z19Bの接続
以下のサイトを参考に接続。
一様MH-Z19Bのデータシートは以下を参照。 https://www.winsen-sensor.com/d/files/MH-Z19B.pdf
ラズパイとキャラクタディスプレイの接続
完成品を購入したので、GPIOの3,5,7,9に刺すだけ。簡単。
全部接続したものは以下の画像を参照。
CO2濃度測定
pythonにコマンドラインからMH-Z19Bを使用してCO濃度を測定できるライブラリが用意されているのでそれを利用。まずは、pipでライブラリをインストール。
$ pip install mh-z19
以下のコマンドを実行するとCO2濃度を測定できる。
$ sudo python3 -m mh_z19 {"co2": 569}
測定結果の表示
測定結果を表示するために、ラズパイのi2Cインタフェースを有効にする必要がある。 以下のコマンドを打つとラズパイの設定画面が表示されるので、設定画面からi2cを有効にする。
# sudo raspi-config
5 Interfacing Optionsを選択 → P5 I2Cを選択 →
次に、i2ctoolsをインストールする。
$ sudo apt-get install i2ctools
以下の通りi2cdetectコマンドを打って出力されればおけ。
$ i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 3e -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
次に、pythonからディスプレイに文字を打てるようにSMBusライブラリをインストールする。
$ pip install smbus2
これで測定結果を表示する準備ができたので、pythonでスクリプトを書いていく。自分が最終的に作ったのは以下のコード。
from smbus import SMBus import time import datetime import subprocess import re import sys # i2c constant i2c = SMBus(1) addr02 = 0x3e _command = 0x00 _data = 0x40 _clear = 0x01 _home = 0x02 display_on = 0x0f LCD_1stline = 0x00 LCD_2ndline = 0x40+0x80 # program constant _pattern = r'[0-9][0-9]:[0-5]0' base_dir = '/home/pi/co2/csv/' def command(code): i2c.write_byte_data(addr02, _command, code) time.sleep(0.1) def writeLCD(message): mojilist = [] for moji in message: mojilist.append(ord(moji)) i2c.write_i2c_block_data(addr02, _data, mojilist) time.sleep(0.1) def init(): command(0x38) command(0x39) command(0x14) command(0x73) command(0x56) command(0x6c) command(0x38) command(_clear) command(display_on) def getCO2(): out = subprocess.check_output(['sudo', 'python3', '-m', 'mh_z19']) co2 = eval(out)['co2'] return str(co2) if __name__ == '__main__': dt_now = datetime.datetime.now() now_time = dt_now.strftime('%H:%M') co2 = getCO2() # init LCD display init() command(_clear) command(LCD_1stline) # write now time to LCD display writeLCD(now_time) command(LCD_2ndline) # write co2 to LCD display print(co2 + "ppm") writeLCD(co2 + "ppm") # write co2 to file every one hour(**:00) if re.fullmatch(_pattern, now_time) is not None: today = dt_now.strftime('%Y%m%d') line = now_time + ',' + co2 + '\n' file_name = base_dir + today + '.csv' with open(file_name, mode='a') as f: f.write(line)
上記のファイルを実行すると、ディスプレイにCO2濃度の測定結果が表示される。
$ sudo python3 /home/pi/co2/i2c_co2_display.py
無事にCO2濃度を測定でき、ディスプレイに表示することができました。
困ったこと
購入したブレッドボードが小さかったので、MH-Z19Bを斜めにして無理やりジャンパワイヤーで繋いでおり、ここが一番大変でした。。。pin付き?のMH-Z19Bがあるようなのでそちらを購入すればもっと簡単だったのかも。 pythonを使用してSMBus経由でディスプレイに表示するところでもっと詰まったところがあったと思うのですが(主にpython2とpython3が混在している影響等々で)、これをつくったのは少し前であまり覚えていません。思い出したら追記します。
参考にさせていただいたサイト
GPIO - Raspberry Pi Documentation
窓を開けて新鮮な空気をいれよう!Raspberry Pi でCO2 濃度を測ろう - Qiita