前几天发现我的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'} >>>
哈哈哈够用就好
结语
- 放在角落里吃灰,先不弄InfluxDB+Grafana了。这玩意有啥用啊……真是的😂浪费钱浪费精力,熬了两个晚上哦。
- 等我的CFe到了,我会再搞一波。不过CH SN530是奇葩的PCIe 4.0x2,竟然只有两个通道,并且国外有小哥测试过PCIe 4.0x4和3.0x4的都不行。CH SN530主控是PS5019-E19。也许等微软开放了限制就可以了?谁知道他们有没有签什么独家协议以及如果有,什么时候到期……