きっかけ
・大学の研究室にて部屋の人口密度が高く、室内環境(CO2濃度等)が気になっていた
後輩「CO2の濃度が測れる何かがあるといいっすね!」
・ラズパイのGPIOを使って何かを作ったことが今まであまり無かった
僕「勉強になるからやってみるか」
使ったもの
・Raspberry Pi 3 model B+
・CO2センサーモジュール(MH-Z14A)
・ジャンパワイヤ(オス-メス)
・ピンソケット(メス、2.54 mm)
CO2センサー(MH-Z14A)はこんな感じのやつ。通電させると中央の白い四角の四隅が赤く点滅する。
おそらくこの部分からCO2を取り込んでCO2濃度を測定していると思われる。
測定原理はNDIR方式というものらしい(CO2の赤外吸収を利用して測定?)
マニュアルによると5000 ppmまで測れるらしい
マニュアルのリンク↓
https://www.openhacks.com/uploadsproductos/mh-z14_co2.pdf
手順
Raspbianをインストール
これはまあ適当に
CO2センサーとラズパイを接続
CO2センサー側
MHZ-14AはCO2の値をUART、PWM、アナログ電圧等色々な方法で取得できるらしい
→今回はUART方式で
UARTでは16-19ピンを使うようなのでで4本分のジャンパワイヤ&ピンソケットがあれば良いね
マニュアルから抜粋↓
実際に接続するとこんな感じ
ピン | 割当て | ジャンパワイヤの色 |
---|---|---|
17 | Vin(5 V) | 赤 |
16 | GND | 黒 |
18 | UART(RXD) | 青 |
19 | UART(TXD) | 黄 |
ラズパイ側
ラズパイ側はこんな感じで接続する
ラズパイ側の設定
###UARTの有効化
まず、ラズパイ(Bluetooth搭載モデル)でのUARTでは以下の特徴があるようである
・ラズパイの場合、UARTのポートが二種類あり、初期設定ではメインのものはBluetoothに、サブの物はシリアル通信(GPIO)に割り当てられているらしい
・また、サブの方は送受信のデータ長に制限がある、クロックがラズパイCPUに依存しているためボーレートもそれに合わせて変化してしまう
そこでメインのポートをシリアル通信側に割り当てる設定を行う
lsで/dev/serial*を参照すると以下の通りになっている
root@raspberrypi:/home/pi# ls -l /dev/serial*
lrwxrwxrwx 1 root root 7 10月 4 18:28 /dev/serial0 -> ttyS0
lrwxrwxrwx 1 root root 5 10月 4 18:28 /dev/serial1 -> ttyAMA0
メインのポート(serial0)はコンソール(ttyS0)に割り当てられているのでシリアル通信(ttyAMA0)に割り当てられるように設定する
root@raspberrypi:/home/pi# vi /boot/cmdline.txt
cmdline.txt
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/mmcblk0p7 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
↓修正↓
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p7 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
要するにconsole=serial0,115200を削除する
次にBluetoothの無効化を行う
root@raspberrypi:/home/pi# vi /boot/config.txt
・
・
・
dtoverlay=pi3-disable-bt ←追記する
Bluetoothの設定を初期化するサービスを無効化する
root@raspberrypi:/home/pi# systemctl disable hciuart
Removed /etc/systemd/system/multi-user.target.wants/hciuart.service.
ここで再起動
root@raspberrypi:/home/pi# reboot
この時点で/dev/serial*を参照するとserial0とserial1の割り当てが逆になっている
root@raspberrypi:/home/pi# ls -l /dev/serial*
lrwxrwxrwx 1 root root 7 10月 4 18:28 /dev/serial0 -> ttyAMA0
lrwxrwxrwx 1 root root 5 10月 4 18:28 /dev/serial1 -> ttyS0
##Pythonによるセンサーの制御
PythonでUART制御が行えるようにライブラリをインストールする
root@raspberrypi:/home/pi# apt install python-serial
実際にセンサーに値を取得させるコマンドを送り、値を取得するプログラムを作成する
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import serial
import time
import datetime
s = None
def setup():
global s
s = serial.Serial('/dev/ttyAMA0',baudrate=9600,bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,timeout=1.0)
print ("start setup")
time.sleep(60)
print ("end setup")
def readdata():
now = datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")
print ("send")
b = bytearray([0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79])
s.write(b)
time.sleep(5)
result = s.read(9)
checksum = (0xFF - ((ord(result[1])+ord(result[2])+ord(result[3])+ord(result[4])+ord(result[5])+ord(result[6])+ord(result[7]))% 256))+ 0x01
checksumok = 'FAIL'
if checksum == ord(result[8]):
checksumok = 'PASS'
data = now + "," + str((ord(result[2])*256)+ord(result[3]))+ "," + checksumok+"\n"
filename = datetime.datetime.now().strftime("%Y%m") + 'CO2data.txt'
file_data = open(filename , "a" )
file_data.write(data)
print (data)
file_data.close()
if __name__ == '__main__':
setup()
while True:
readdata()
print ("read")
実際にプログラムを実行すると以下の通りになる
root@raspberrypi:/home/pi/mh-z14a# python co2.py
start setup
end setup
send
2019/10/13 00:44:27,620,PASS
CO2濃度が620 ppmとして取得された
追記:
こちらに取得したCO2濃度によって光らせるLEDの色を変えてみた記事を書きました
CO2濃度センサーで取得した値に応じて光らせるLEDの色を変える
#参考にしたサイト
・UART有効化
https://www.ingenious.jp/raspberry-pi/2019/03/gpio-uart/
・センサー・ラズパイ間の接続、プログラム
https://www.ishikawa-lab.com/RasPi_CO2_MHZ19.html
https://qiita.com/watiko/items/5cfa2aedd5a67619add0
有用な情報ありがとうございました