車の運転中にCO2濃度が高くなると集中力が落ち眠くなりやすくなるそうです。
そこで、車でCO2濃度が測定できるようにRaspberry Piを使って車載用にCO2濃度計を作ることにしました。
まだやりたいことが全部できたわけではないですが、個人的に使うには十分なところまでできましたので作成方法について紹介したいと思います。
機能
最終的に実装した機能は以下になります。
- 定期的にCO2濃度を測定し小型液晶に表示
- CO2濃度が閾値を超えていたら警告音を鳴らす
- webで濃度の推移グラフ(1分ごと、1時間ごと)を可視化する
- CO2濃度のログをAWSのS3に送信(とりあえず蓄積するだけ)
構成
必要部品
部品 | 数量 | 用途 | 金額(目安) |
---|---|---|---|
Raspberry Pi Zero W | 1 | 1300円 | |
MH-Z19 | 1 | CO2センサー | 3800円 |
PiOled | 1 | 表示用小型液晶 | 3800円 |
圧電スピーカ | 1 | アラーム用 | 100円 |
各部品の接続
接続図
上記接続の通り各部品を接続していきます。
CO2センサー(mh-z19)接続
CO2センサーを接続し動作確認を行います。
uartの有効化
/boot/config.txtに以下を追加してraspberry piを再起動する
enable_uart=1
モジュールのインストール
pip install getrpimodel
接続確認
以下のプログラムを適当な名前で保存し実行します。
import sys import serial import time import subprocess import getrpimodel import datetime from time import sleep import RPi.GPIO as GPIO 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' def mh_z19(): ser = serial.Serial(serial_dev, baudrate=9600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=1.0) while 1: result=ser.write("\xff\x01\x86\x00\x00\x00\x00\x00\x79") s=ser.read(9) if len(s)!=0 and s[0] == "\xff" and s[1] == "\x86": return {'co2': ord(s[2])*256 + ord(s[3])} break def main(): subprocess.call(stop_getty, stdout=subprocess.PIPE, shell=True) now = datetime.datetime.now() now_ymdhms = "{0:%Y/%m/%d %H:%M:%S}".format(now) # Get Data value = mh_z19() co2 = value["co2"] print('CO2:' + co2) subprocess.call(start_getty, stdout=subprocess.PIPE, shell=True) if __name__ == '__main__': main()
CO2の値が取得されていれば正しく接続できています。
室内だと通常400〜1000ppm程度かと思いますが、異常な値が取得されていれば以下のサイトを参考に補正してみてください。
qiita.com
液晶(PiOled)接続
PiOledを接続後、以下の設定を行います。
手順はRaspberry Pi 3 Model Bに Adafruit PiOLED を接続 – Qiitaを参考にしました。
カーネルモジュール自動ロード設定
/boot/config.txtに以下を追加してraspberry piを再起動する
dtparam=i2c_arm=on
必要ライブラリのインストール
sudo apt-get install python-dev sudo apt-get install python-imaging sudo apt-get install libffi-dev sudo pip install smbus-cffi sudo pip install RPi.GPIO
カーネルモジュールのロード
sudo modprobe i2c-dev $ dmesg | grep i2c ロードされていることの確認 cat /proc/devices | grep i2c 89 i2c
/dev/i2c-1 の作成
sudo mknod /dev/i2c-1 c 89 1 $ ls /dev/i2c-1 /dev/i2c-1
PiOledの接続確認
以下のように出力されていれば正しく接続されています。
sudo i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
サンプルの実行確認
git clone https://github.com/adafruit/Adafruit_Python_SSD1306.git cd Adafruit_Python_SSD1306 sudo python ./setup.py build sudo python ./setup.py install python ./examples/stats.py &
液晶にIPアドレス、CPU、メモリ、ディスクが表示されていればOKです。
圧電スピーカ接続
接続後に以下のプログラムを実行してスピーカーから音が鳴ればOKです。
import RPi.GPIO as GPIO import time SOUNDER = 21 GPIO.setmode(GPIO.BCM) GPIO.setup(SOUNDER, GPIO.OUT, initial = GPIO.LOW) p = GPIO.PWM(SOUNDER, 6500) p.start(50) time.sleep(0.5) p.stop() time.sleep(0.5) p.stop GPIO.cleanup()
プログラムの配置
CO2濃度取得プログラムの配置
以下の通りプログラムを取得し適当なところに配置します。(ここでは/home/pi/program/配下に配置しました。)
git clone https://github.com/cloudfish7/co2_sensor.git
cronの設定
1分ごとと1時間ごとにデータを取得するように設定します。
*/1 * * * * sudo python /home/pi/program/co2_sensor/mh-z19.py minutes 0 * * * * sudo python /home/pi/program/co2_sensor/mh-z19.py hour
表示用Webプログラムの配置
以下の通りプログラムを取得し適当なところに配置します。(ここでは/home/pi/program/配下に配置しました。)
グラフ表示についてはOpen Source Image Charts Replacement | QuickChartを利用しているためraspberry piについてはインターネット接続されている必要があります。
git clone https://github.com/cloudfish7/co2_web.git
以下コマンドで実行します。(自動起動設定してないです)
python app_co2.py
ブラウザで以下アドレスにアクセスするとweb画面が表示されます。
IPアドレスは液晶にも表示されるようになっています。
http:ip_address:8080
車載にあたっての問題
車に積んだ際に電源が問題になります。
シガーソケットからUSBで電源を取得していた場合、エンジンを切ると電源供給が止まるためRaspberry Piが突然落ちることになります。そうするとSDカードへの書き込み途中の場合、ファイルが壊れてしまい最悪OSが起動しなくなる可能性があります。
組み込み系のデバイスの場合はROM化して書き込みを無くすようなので、Raspberry PiでもROM化できないか調べてみたところoverlayfsという仕組みを使うことでSDカードへの書き込みを制御できることが分かりました。
以下の記事に設定方法が詳しく書かれていましたが、設定後システムが不安定になる場合もあるようなので今回は諦めることにしました。
qiita.com
代わりにモバイルバッテリーを電源に使うことにしました。
少し面倒ですがとりあえずは当面これで使ってみたいと思います。OSのシャットダウンについてはWebの画面にシャットダウンボタンを付けて代用しようかと考えています。
まとめ
CO2濃度計を作ってから自宅、車と両方で使っています。
大気中のCO2濃度は約400ppmくらいなので、換気が行き届いている場合は同様の数値となりますが、窓を締めるとすぐに数値が上がっていきました。
実際に車で4人が乗り、内気循環にしていると30分程度で2000ppmを超える濃度となりました。2500ppmを超えるとパフォーマンスが落ち眠気を誘うとの研究もありますので、運転中は適度に換気したほうがよさそうですね。
参考
Raspberry Pi 3 で CO2濃度を測る – Qiita
http://www.winsen-sensor.com/d/files/PDF/Infrared%20Gas%20Sensor/NDIR%20CO2%20SENSOR/MH-Z19%20CO2%20Ver1.0.pdf