ラズパイとPPD42NJダストセンサー 自宅PM2.5値を自作で計測

スポンサーリンク

PM2.5をラズパイで計測するために海外通販BanggoodでPM2.5 PPD42NJを買ってウチのPM2.5を計測してみました。XiaomiのPM2.5計測器も持っているので比較してみます。

計測したデータはラズパイのInfluxDBに登録して、Grafanaで表示させています。

だいぶ前に完成していましたが、ちゃんと計測しない時があって・・・ちょっと使いづらいダストセンサーです。

BanggoodでPM2.5 PPD42NJを買った

こちらBanggoodで579円で売っていたので送料無料で買って送ってもらいました。

DC 5V XYS PM2.5 PPD42NJ PPD42NS Dust Smoke Particle Sensor Module Air Quality Monitor/Purifier With Cable

DC 5V XYS PM2.5 PPD42NJ PPD42NS Dust Smoke Particle Sensor Module Air Quality Monitor/Purifier With Cable

センサーの仕様

ちょっと違う?ようですが同じようなセンサーの仕様がありました。

Grove - Dust Sensor - Seeed Wiki
Seeed Product Document

ラズパイ・InfluxDB・Grafana構築・使い方

ラズパイ構築やInfluxDB・Grafanaの使い方インストールは以下の別サイトを参考にしてください。

ラズパイの簡単インストール方法3種+OSまるごとバックアップ
自宅のIot化でLED照明オンオフ(Xiaomi LED)や玄関鍵の開閉(セサミ スマートロック)、壁スイッチのオンオフ、部屋の空気の状態を表示させたりしていますが、不満点は専用のアプリでないと操作できないこと。それと同じメーカーでないと他
Beヨンド
ガジェットおすすめランキング
【Iot環境センシング下準備】InfluxDB設定+Grafana+telegrafでラズパイデータ可視化 カッコいいグラフを作ろう
自宅環境センシングの2回目の記事として今回はラズパイ(Raspberry Pi)にデータベースのInfluxDBを入れて将来的にセンシングしたデータをInfluxDB保存していきます。そして次回は、GrafanaというデータをWebで美しく

以下、Raspi・InfluxDB・Grafanaのシステムができていること前提で書いていきます。

WxBeacon2を使った記事も書きました。↓

WxBeacon2で温度・湿度・気圧・照度・騒音・紫外線・不快指数・熱中症危険度の8つをセンシングしてグラフ表示
前回まででラズパイを母艦にしてセンシングしたデータをデータベース(InfluxDB)に保存してGrafanaでグラフ表示することができたので、今後は少しずつセンシングデータを増やしていく作業です。今のところセンサーで取得できているデータは温

完成図

分かりづらいのですが↓ラズパイに各種センサーを付けて温度・湿度・明るさなども一緒に計測してInfluxDBにあげてGrafanaでグラフにしてます。

PM2.5 PPD42NJ

真ん中の黒いのがPM2.5 PPD42NJ

本当は風を送ってホコリを計測するのですが、今のところファンは付けてない。

PM2.5 PPD42NJ

窓際の棚の裏に磁石でくっつけています。

ラズパイとダストセンサーをつないでPM2.5を計測してみる

参考にしたソース

こちらを参考にさせていただきました。ありがとうございますm(_ _)m

【ラズベリーパイ3】ダストセンサーでPM2.5測定
この記事では、ラズベリーパイ3とPython、ホコリセンサー(Groveダストセンサー)でPM2.5をμg/m^3単位で測定する方法をソースコード付きで解説します。

PIN

4PINにGPIO18さしたら反応しました。

PM2.5 PPD42NJ Raspberry Pi
1:GND GND
2:?
3:5V 5V
4:PIN GPIO18
5:?

下準備

$ sudo apt-get update && sudo apt-get upgrade -y

bluepyなど必要なライブラリをインストールします。

$ sudo apt-get install libglib2.0-dev
$ sudo pip install bluepy
$ sudo apt-get install -y git openssl libssl-dev libbz2-dev libreadline-dev libsqlite3-dev
$ sudo pip install timeout-decorator

Pythonファイル

しばらくWhileしてデータを取得するので数十秒かかる。

改良点は1回実行時に1回だけデータを取得して、定期的にCronでpm2.5.pyを実行するようにしました。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
import time

import binascii
import base64
import requests
from bluepy.btle import UUID, Peripheral, ADDR_TYPE_PUBLIC, DefaultDelegate

from influxdb import InfluxDBClient
client = InfluxDBClient(host='192.168.31.53', port=8086, username='root', password='xxxxxxx', database='sensor')
measurement = 'air5'
tags = {'place': 'raspi-pm2.5','host': 'raspi3B+'}

# HIGH or LOWの時計測
def pulseIn(PIN, start=1, end=0):
		if start==0: end = 1
		t_start = 0
		t_end = 0
		# ECHO_PINがHIGHである時間を計測
		while GPIO.input(PIN) == end:
				t_start = time.time()
				
		while GPIO.input(PIN) == start:
				t_end = time.time()
		return t_end - t_start

# 単位をμg/m^3に変換
def pcs2ugm3 (pcs):
	pi = 3.14159
	# 全粒子密度(1.65E12μg/ m3)
	density = 1.65 * pow (10, 12)
	# PM2.5粒子の半径(0.44μm)
	r25 = 0.44 * pow (10, -6)
	vol25 = (4/3) * pi * pow (r25, 3)
	mass25 = density * vol25 # μg
	K = 3531.5 # per m^3 
	# μg/m^3に変換して返す
	return pcs * K * mass25

# pm2.5計測
def get_pm25(PIN):
		t0 = time.time()
		t = 0
		ts = 30 # サンプリング時間
		while(1):
				# LOW状態の時間tを求める
				dt = pulseIn(PIN, 0)
				if dt<1: t = t + dt
				
				if ((time.time() - t0) > ts):
						# LOWの割合[0-100%]
						ratio = (100*t)/ts
						# ほこりの濃度を算出
						concent = 1.1 * pow(ratio,3) - 3.8 * pow(ratio,2) + 520 * ratio + 0.62
						print(t, "[sec]")
						print(ratio, " [%]")
						print(concent, " [pcs/0.01cf]")
						print(pcs2ugm3(concent), " [ug/m^3]")
						pm25 = round(pcs2ugm3(concent))
						json_body = [
							{
								'measurement': measurement,
								'tags': tags,
								'fields': {'aqi': pm25}
							}
						]
						print(json_body)
						client.write_points(json_body)
						break

PIN = 18
# ピン番号をGPIOで指定
GPIO.setmode(GPIO.BCM)
# TRIG_PINを出力, ECHO_PINを入力
GPIO.setup(PIN,GPIO.IN)
GPIO.setwarnings(False)

if __name__ == '__main__':
		get_pm25(PIN)

# ピン設定解除
GPIO.cleanup()

試してみるとエラーが出る

エラー?が出ているけどちゃんと計測できてる??

 $ python pm2.5.py
pm2.5.py:58: RuntimeWarning: This channel is already in use, continuing anyway.  Use GPIO.setwarnings(False) to disable warnings.
  GPIO.setup(PIN,GPIO.IN)
(0.8397605419158936, '[sec]')
(2.799201806386312, ' [%]')
(1450.5564774811437, ' [pcs/0.01cf]')
(2.2619621467487887, ' [ug/m^3]')
-------------------
(1.7081043720245361, '[sec]')
(5.693681240081787, ' [%]')
(3041.18139406269, ' [pcs/0.01cf]')
(4.742343577488136, ' [ug/m^3]')
-------------------
(0.9526140689849854, '[sec]')
(3.175380229949951, ' [%]')
(1648.7214021565205, ' [pcs/0.01cf]')
(2.570975663552621, ' [ug/m^3]')
-------------------

最初はGPIO15に誤ってさしていて、他のセンサーが使ってたのでエラーになったみたい。

Cronで定期的に実行

最後にCronで定期的にpm2.5.pyを実行します。

3-58/3 * * * * /usr/bin/python /home/pi/script/pm2.5.py

:GPIOを接続しないまま、Cronで定期的にこのプログラムを実行するとCronが溜まっていってCPU使用率100%近くになって温度が急上昇してラズパイがハングアップします。ご注意ください。

Grafanaの設定

Grafanaをご利用の方はPM2.5.jsonを用意しました。Xiaomi PM2.5測定器も一緒に表示するようになっているので必要なければ削除してください。

こちら↓のJsonファイルを右クリックしてダウンロード後、Grafanaにコピペもしくはアップロードしてみてください。

https://densi.biz/wp-content/uploads/file/pm2.5.json

jsonファイルのインサート方法は以下で書きました。

【Iot環境センシング下準備】InfluxDB設定+Grafana+telegrafでラズパイデータ可視化 カッコいいグラフを作ろう
自宅環境センシングの2回目の記事として今回はラズパイ(Raspberry Pi)にデータベースのInfluxDBを入れて将来的にセンシングしたデータをInfluxDB保存していきます。そして次回は、GrafanaというデータをWebで美しく

PM2.5の値が正確ではないのかもしれない

高い数値が出る

グラフの緑の線が洗面所に置いたXiaomiのPM2.5測定器ですが、通常は9~12くらいをウロウロしてますが、ラズパイで作ったPPD42NJ のほうは40~80くらいの高い数値。で、たまに120μg/m3も行くので、もしかしたら?正確ではないのかもしれません。

PM2.5

ラズパイ+PPD42NJ の設置場所は窓際の棚の裏に磁石でくっつけています。ファンで風を起こさないと正確ではないのかもしれませんね。

洗面所でデオドラントスプレーやヘアスプレーを使うとPM2.5の数値が高くなります。

PM2.5

4月ごろのデータと値が違う

2019/4頃に調子が良かった時は、10~15くらいだったので、今とちょっと違うようです。

PM2.5

このダストセンサーあまり当てにならないかな?

XiaomiのPM2.5測定器

洗面所に置いたXiaomiのPM2.5測定器↓こちらはハックしてデータをInfluxDBに登録したので、その設定方法など後ほど書いていきます。

Xiaomi Smart Air Quality Monitor PM2.5 Detector

Xiaomi PM2.5 AQI測定器

こちら↓でレビューしました。

Beヨンド
ガジェットおすすめランキング

 

 

以下のトラブルはメモです。読み飛ばしてください。

トラブル・ESP32ではうまくいかなかった

以下ちょっとしたトラブルと、現状ではESP32でやってもうまくいきませんでした。

ラズパイで18番接続しているはずだけど?「0」になってる・・・?

$ gpio readall
 +-----+-----+---------+------+---+---Pi 3B+-+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 |     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
 |   2 |   8 |   SDA.1 | ALT0 | 1 |  3 || 4  |   |      | 5v      |     |     |
 |   3 |   9 |   SCL.1 | ALT0 | 1 |  5 || 6  |   |      | 0v      |     |     |
 |   4 |   7 | GPIO. 7 |   IN | 1 |  7 || 8  | 1 | ALT5 | TxD     | 15  | 14  |
 |     |     |      0v |      |   |  9 || 10 | 1 | ALT5 | RxD     | 16  | 15  |
 |  17 |   0 | GPIO. 0 |   IN | 0 | 11 || 12 | 0 | IN   | GPIO. 1 | 1   | 18  |
 |  27 |   2 | GPIO. 2 |   IN | 0 | 13 || 14 |   |      | 0v      |     |     |
 |  22 |   3 | GPIO. 3 |   IN | 0 | 15 || 16 | 0 | IN   | GPIO. 4 | 4   | 23  |
 |     |     |    3.3v |      |   | 17 || 18 | 0 | IN   | GPIO. 5 | 5   | 24  |
 |  10 |  12 |    MOSI | ALT0 | 0 | 19 || 20 |   |      | 0v      |     |     |
 |   9 |  13 |    MISO | ALT0 | 0 | 21 || 22 | 0 | IN   | GPIO. 6 | 6   | 25  |
 |  11 |  14 |    SCLK | ALT0 | 0 | 23 || 24 | 1 | OUT  | CE0     | 10  | 8   |
 |     |     |      0v |      |   | 25 || 26 | 1 | OUT  | CE1     | 11  | 7   |
 |   0 |  30 |   SDA.0 |   IN | 1 | 27 || 28 | 1 | IN   | SCL.0   | 31  | 1   |
 |   5 |  21 | GPIO.21 |   IN | 1 | 29 || 30 |   |      | 0v      |     |     |
 |   6 |  22 | GPIO.22 |   IN | 1 | 31 || 32 | 0 | IN   | GPIO.26 | 26  | 12  |
 |  13 |  23 | GPIO.23 |   IN | 0 | 33 || 34 |   |      | 0v      |     |     |
 |  19 |  24 | GPIO.24 |   IN | 0 | 35 || 36 | 0 | IN   | GPIO.27 | 27  | 16  |
 |  26 |  25 | GPIO.25 |   IN | 0 | 37 || 38 | 0 | IN   | GPIO.28 | 28  | 20  |
 |     |     |      0v |      |   | 39 || 40 | 0 | IN   | GPIO.29 | 29  | 21  |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+---Pi 3B+-+---+------+---------+-----+-----+

PINがちゃんとハマってないだけだったみたい・・・違うジャンパピンに変えたら動いた。

ESP32で試したけどうまくいかなかったが、Arduino UNOだとうまくいくみたい。

コメント

タイトルとURLをコピーしました