こんにちは、今年最後の虎の穴開発室ブログ執筆者の虎の穴ラボのH.Yです。
今回は、CO2の濃度を安めのCO2センサーとRaspberry Piを使って測ってみたという内容です。
昼過ぎに眠くなるのは一体。
お昼過ぎに何故か眠くなるので、はじめは常に高い血糖値がさらに高くなって云々で眠くなると考えていたのですが、
同僚からSlackでこんな記事を紹介されました。
全く同じ事象がTeamLabさんでも起きていたということ。
記事を見ると、CO2濃度が眠気の原因で、換気したらよくなったという
とりあえず、現状を把握するために、Raspberry Piを使ってCO2濃度測定器を作ることに。
ハードウェア部分
必要なものは2つ
・CO2センサー(MH-Z19B)
Amazon CAPTCHA
比較的安めで、UARTでデータが取れます。
・Raspberry Pi(Raspberry Pi 3 Model B)
https://www.yodobashi.com/product/100000001004207792/
最近Raspberry Pi4が出てるけど、作ったときは日本未発売だったので、3Bを使用。
CO2センサーとRaspberry PiをUARTで接続します。
ソフトウェア部分
今回のアプリでは、以下2点の機能を作りました。
・CO2濃度を測定すること
・DBにデータを蓄積すること
まず、Raspberry PiでUARTを有効にする設定を行います。
vi /boot/config.txt
以下の内容を追記
enable_uart=1
追記したら再起動して設定を反映にします。
シリアル通信部分の実装はよくわからなかったので↓の記事を参考にしました。
Raspberry Pi 3 で CO2濃度を測る - Qiita
(じつは諸々書いてあります)
ついでに、何かで使うかもしれないので、SQLiteにデータを挿入していきます。(申し訳程度のオリジナル要素)
今回使用するpythonのバージョンは3.7.3を使用します。 使用するライブラリを追加します。
pip install pyserial pip install redis pip install sqlalchemy pip install getrpimodel
co2_measure.py(ここの部分を実行することで、CO2濃度の出力とDBに挿入を行います。)
import serial import getrpimodel import subprocess from insert_record import insert_co2 #Raspberry Piのモデルごとの初期設定 if getrpimodel.model() == "3 Model B": serial_dev = '/dev/ttyS0' stop_getty = 'sudo systemctl stop serial-getty@ttyS0.service' start_getty = 'sudo systemctl start serial-getty@ttyS0.service' else: serial_dev = '/dev/ttyAMA0' stop_getty = 'sudo systemctl stop serial-getty@ttyAMA0.service' start_getty = 'sudo systemctl start serial-getty@ttyAMA0.service' #CO2センサーからデータを取得するところ def read(): try: ser = serial.Serial(serial_dev, baudrate=9600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=1.0) #CO2濃度を取得するコマンド送信 result=ser.write(b'\xff\x01\x86\x00\x00\x00\x00\x00\x79') s=ser.read(9) #取得した形式が正しければCO2濃度を10進法に変換してretrun if len(s) >= 4 and s[0] == int('ff',16) and s[1] == int('86',16): return s[2]*256 + s[3] except IOError: print('IOエラー') except: print('その他エラー') p = subprocess.call(stop_getty, stdout=subprocess.PIPE, shell=True) co2_concentration = read() p = subprocess.call(start_getty, stdout=subprocess.PIPE, shell=True) if co2_concentration is not None: #CO2濃度が取得できていればCO2濃度の標準出力 print('CO2濃度:',co2_concentration,'ppm', flush=True) #CO2濃度をDBに挿入 insert_co2( co2_concentration )
insert_record.py(CO2を挿入する部分)
from models.co2_records import Base, Co2Records from database.database import session,engine from datetime import datetime #現在日付とCO2濃度を記録するメソッド def insert_co2( co2_concentration ): Base.metadata.create_all(engine) dt_now = datetime.now() record = Co2Records(dt_now, co2_concentration) session.add(record) session.commit() session.close()
database.py
from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine #SQLite用の接続設定 engine = create_engine('sqlite:///data.sqlite') Session = sessionmaker(bind=engine) session = Session()
co2_records.py
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String, DateTime import datetime Base = declarative_base() #DBのCO2濃度のモデルクラス class Co2Records(Base): __tablename__ = 'co2_records' create_datetime = Column(DateTime, primary_key=True) co2_concentration = Column(Integer) def __init__(self, create_datetime, co2_concentration): self.create_datetime = create_datetime self.co2_concentration = co2_concentration def __repr__(self): return "<Co2_record(create_datetime='%s', co2_concentration='%s')>" % ( self.create_datetime, self.co2_concentration)
このソースを使い、CO2濃度を表示していくには、
watch -n 1 python co2_measure.py
で行います(ゴリ押し)
Raspberry Piの設置場所が、割と目立つところがあるので、結構確認しやすいので、これでよし!
運用してみると、Slackで通知するよりも常に表示したほうが直感的にCO2濃度が高いとわかります。
若干適当な感じがしますが、一旦このまま運用しています。
昼過ぎぐらいに1000ppmを超えることがあったので、
上のように濃度関係なしに、定期的に換気促すようにbotを動かしました。
5分ぐらい換気すると、問題なさそうなぐらいまで下がりました。
あとがき
こころなしか、昼過ぎでもスッキリしたような感じがします(プラシーボかも・・・
大体毎秒、DBにCO2濃度を書き込んでいるので、1日のグラフとかを作ってみたい気がします。
続きは、技術同人誌を書くことがあれば、そこに書いてみたいと思います。
P.S.
虎の穴では一緒に働く仲間を絶賛募集中です! 興味のある方は是非採用サイトを御覧ください! yumenosora.co.jp