はじめに
空気清浄機の謳い文句で「PM2.5を除去」といったものを見かけることがありませんか?
今回はESP32とPMS5003を使ってPM0.3~PM10を一挙に測定してみました.
PMS5003について
PMS5003は粒子状物質(Particulate Matter)を測定することができるセンサで,いわゆるPM○○の濃度がわかります.正確には,単位体積あたりの粒子を直径ごとに個数単位で取得できる優れものです.
上の図はPMS5003のデータシートから引用した内部の仕組みの構成図です.PMS5003には5Vで動作するファンが内蔵されていて,そこから外気を取り込んでいます.そして取り込んだ外気をレーザー光で照射し,その散乱光の時間変化から粒子の個数を特定しているみたいです.(cf. MIE散乱)
回路
PMS5003はシリアルインターフェースとしてUARTを採用しているため,一般的なUARTのクロス結線に基づいて回路を作成しました.
また,ファンを稼働させるために5Vの電圧が必要なので,PMS5003のVCCをESP32の5V電圧のピンと接続しています.
ピン | 役割 | 説明 |
---|---|---|
PIN1 | VCC | Positive power 5V |
PIN2 | GND | Negative power |
PIN3 | SET | Set pin /TTL level@3.3V,high level or suspending is normal working status, while low level is sleeping mode. |
PIN4 | RX | Serial port receiving pin/TTL level@3.3V |
PIN5 | TX | Serial port sending pin/TTL level@3.3V |
PIN6 | RESET | Module reset signal /TTL level@3.3V,low reset. |
PIN7/8 | NC |
ソースコード(ESP32)
ソースコードはmartonz氏のpms5003.pyを参考にさせていただきました.
一分間隔で10回取得してます.
import utime
try:
import struct
except ImportError:
import ustruct as struct
from machine import UART
ACQ_NUM = 10
SLEEP_TIME = 60
uart = UART(1, baudrate=9600, tx=1, rx=3, timeout=2000)
buffer = []
for i in range(ACQ_NUM):
data = uart.read(32)
data = list(data)
buffer += data
while buffer and buffer[0] != 0x42:
buffer.pop(0)
if len(buffer) > 200:
buffer = []
if len(buffer) < 32:
continue
if buffer[1] != 0x4d:
buffer.pop(0)
continue
frame_len = struct.unpack(">H", bytes(buffer[2:4]))[0]
if frame_len != 28:
buffer = []
continue
frame = struct.unpack(">HHHHHHHHHHHHHH", bytes(buffer[4:]))
pm10_standard, pm25_standard, pm100_standard, pm10_env, \
pm25_env, pm100_env, particles_03um, particles_05um, particles_10um, \
particles_25um, particles_50um, particles_100um, skip, checksum = frame
check = sum(buffer[0:30])
if check != checksum:
buffer = []
continue
print("---------------------------------------")
print("Particles > 0.3um / 0.1L air:", particles_03um)
print("Particles > 0.5um / 0.1L air:", particles_05um)
print("Particles > 1.0um / 0.1L air:", particles_10um)
print("Particles > 2.5um / 0.1L air:", particles_25um)
print("Particles > 5.0um / 0.1L air:", particles_50um)
print("Particles > 10 um / 0.1L air:", particles_100um)
print("---------------------------------------")
utime.sleep(SLEEP_TIME)
print("DONE!")
実行結果
#おわりに
今回はESP32とPMS5003を使って空気中のPMを測定してみました.
どちらも比較的安価なので皆さんも試してみてはいかがでしょうか.