土豆不好吃

在树莓派上使用ZPH01监测PM2.5和VOC

文章目录[显示]
这篇文章在 2022年03月05日11:54:55 更新了哦~

前几天发现我的Xbox内置存储空间不足了,希捷的Xbox Expansion Card又太贵了,发现bilibili有人发了一篇文章可以DIY这个扩展卡《【全站首发?】自制次世代XBOX专用存储卡(扩容)》。技术原理并不复杂,就是一个CFe到NVMe的转接器+微软定制CH SN530。

但是这个转接器又太贵了,海鲜市场都要100元,在网上搜到了有开源的设计,https://github.com/neg2led/cfxsx,恰巧国内的嘉立创可以免费给打样,于是我就去打了一个,顺便买了点电子元件回来玩。

这么好的东西,既能检测PM2.5还能检测VOC(可挥发性有机物),当然要留给树莓派啊

了解ZPH01

ZPH01有两种输出,PWM和UART,先不管这是什么……

有5个针脚,如下表所示

PIN1 控制脚,悬空为PWM,接地为UART
PIN2 输出脚 OUT2/RXD/PM2.5
PIN3 电源正(VCC)
PIN4 输出脚 OUT1/TXD/VOC 等级
PIN5 电源地(GND)

接线

于是我就把用杜邦线接上了,两个输出分别接到了16号GPIO23和18号GPIO24

获取数据

import RPi.GPIO as GPIO

# BOARD是树莓派上的编号,比如我接的是GPIO23,编号是16。也可以用BCM,那么编号就是23了。
GPIO.setmode(GPIO.BOARD)

GPIO.setup(16, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.input(16) # 获取输入,如果想要输出高电压,那就GPIO.OUTPUT(16,GPIO.HIGH)

GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.input(18)

这样就能够获取到GPIO针脚的输入,要么是0,要么是1,在我看来这玩意就有点随机变化的感觉了。

然后呢?で?

PWM

脉冲宽度调制(英语:Pulse-width modulation,缩写:PWM),简称脉宽调制,是将模拟信号变换为脉冲的一种技术。

emm咋说呢,举例来看,说明书里有这样一个波形,当我从GPIO中读到0度时候,那么就是低脉冲(低电压),读到1的时候,那么就是高脉冲(高电压)。

这个设备的脉冲周期是1秒,也就是说,如果我在1秒的时间范围内,读到了200ms读低脉冲,那么低脉冲率就是20%。那么这个低脉冲率有什么用?

继续往下看手册,发现了这么一个图

哟呵,这不是初中学过的一次函数吗?低脉冲率为10%,差不多意味着平均有6000个PM2.5颗粒。

同理,颗粒物浓度也是有一个一次函数图表,可以根据低脉冲率计算出颗粒物浓度。

再次同理,VOC的输出也可以计算低脉冲率,根据说明书10%的低脉冲率就是VOC1级,20%就是2级,也就分别对应优和良。这个设备会输出四个等级,可惜的是无法辨别化合物的类别。

那么也就是说,写一个算法,一秒钟取样,就能拿到环境中的数据了。

emmm我不会写,我太菜了。

UART

通用异步收发传输器(Universal Asynchronous Receiver/Transmitter,通常称为UART)是一种异步收发传输器,是电脑硬件的一部分,将数据透过串列通信进行传输。

emm就是一种串口啦,恰巧树莓派上的8和10就是UART的TX和RX。TX是发送数据,RX是接收数据。

ZPH01在控制口接地的时候,输出模式会变成UART,1秒输出一次。连接参数是这样的

波特率 9600
数据位 8
停止位 1
校验位

数据格式是这样的

0 1 2 3 4 5 6 7 8
起始位 检测类型编码 单位(低脉冲率) 低脉冲率整数部分 低脉冲率小数部分 预留 模式 VOC登记 校验值
0xFF 0x18 0x00 0x00-0x63 0x00-0x63 0x00 0x01 0x00-0x03 0x00-0xFF

树莓派使用串口

树莓派有两个串口,一个是模拟的ttyS0,一个是硬件的ttyAMA0。硬件的那个更靠谱,波特率不会受到CPU频率的影响。

我用的是Ubuntu,启用串口大概可以参考这篇问答,简单摘抄如下:

sudo systemctl stop serial-getty@ttyS0.service
sudo systemctl disable serial-getty@ttyS0.service
sudo systemctl mask serial-getty@ttyS0.service

# /etc/udev/rules.d/10-local.rules
KERNEL=="ttyS0", SYMLINK+="serial0" GROUP="tty" MODE="0660"
KERNEL=="ttyAMA0", SYMLINK+="serial1" GROUP="tty" MODE="0660"

sudo udevadm control --reload-rules && sudo udevadm trigger
sudo adduser $USER tty

# remove console=serial0,115200 from /boot/firmware/cmdline.txt
# add newline dtoverlay=disable-bt to /boot/firmware/config.txt

重启之后就可以了,ls可以看到串口

lrwxrwxrwx 1 root root 5 Jan 10 04:56 /dev/serial0 -> ttyS0
lrwxrwxrwx 1 root root 7 Jan 10 04:56 /dev/serial1 -> ttyAMA0

此时我们可以把ZPH01的TXD也就是PIN4接到树莓派的10号口GPIO15

然后打开minicom看下有没有数据:

sudo minicom

Ctrl+A+Z然后再按O可以设置串口

波特率9600,数据位校验位根据上面的图标设置,8N1就对了

在screen and keyboard中按S可以显示hex(十六进制)

保存退出之后就会发现,屏幕上出现了神奇的16进制数字,每到一组ff意味着出现了新的一组数据,也就是说ff 18 00 02 3a 00 01 00 ab这便是一组数据了。

同时用Python也可以读得到这些数据的

那么VOC等级是7,也就是00,那么就是优;撒点酒精到传感器旁边,

诚不欺我!

PM2.5的低脉冲率,根据数据格式,是3和4,0x00+0x39/100,也就是

>>> int(data[3], 16) + int(data[4], 16) / 100
0.57

0.57%,再根据图标计算出一次方程的……公式,就可以得出来值了。

为方便自己搞事情,我写了个简单的library,可以用来处理这些数据,同时加上了PM2.5的欧盟标准

具体使用方法如下,先安装 pip install zph01

>>> from zph01 import ZPH01
>>> zph = ZPH01()
>>> zph.output()
{'VOC status': 'Good', 'PM 2.5 percent': 1.6, 'PM 2.5 count': 960.0, 'PM 2.5 level': 32.0, 'PM 2.5 status': 'Poor'}
>>>

哈哈哈够用就好

结语


文章版权归原作者所有丨本站默认采用CC-BY-NC-SA 4.0协议进行授权|
转载必须包含本声明,并以超链接形式注明原作者和本文原始地址:
https://dmesg.app/zph01-pm25-voc.html
退出移动版