当乐高遇见Arduino:乐高PM2.5 探测仪
上周文章探讨了如何通过Bricktronics实现Arduino对乐高的控制,为Arduino和乐高搭建了一座沟通的桥梁。通过这种沟通机制,我们可以将Arduino丰富的外设探测器纳入到我们的应用体系中,为我们的创意实现插上翅膀。
上周写文章时,正值雾霾,但伴随着“如约而至”寒潮大雪而来的“不正经的风”将雾霾吹的一干二净,周一北京不少地方PM2.5的浓度甚至低至个位数,蓝蓝的天,白白的雪,朋友圈中的北京也一夜之间回到了北平。
令人惊呆的空气质量
可惜“不正经的风”不常有,雾霾却常有。
生活在“苍穹之下”的我们,时刻关注着空气质量,近几年各种净化器、检测器满天飞,价格不一而足。作为前文延续,我们这期文章将以PM2.5检测模块为例,实现“传感器+Arduino+Lego”三者的联动。
按照霾的定义,是大量极细微的干尘微粒均匀漂浮在空中,使水平能见度小于10km的空气浑浊现象。而雾霾检测的核心是检测空气中这些微小颗粒态物质的尺寸和数量,比如我们最关心的“PM2.5”数值,就是检测空气中尺寸小于2.5微米的微粒的数量。所以雾霾检测设备的核心器件就是雾霾检测传感器。雾霾检测传感器大多数都是利用光散射原理来实现空气颗粒测量。我们会一个“番外篇”来详细介绍光散射法与雾霾检测。
本着“易于获取、价格经济、语言简便且迁移性强的解决方案”的原则,我们选取了市面上曝(jia)光(ge)率(zui)最(pian)高(yi)的GP2Y1010AU0F作为试验元件。
GP2Y1010套件,GP2Y1010光源种类为红外灯珠IRED(为与说明书对应,以下称LED),是一款红外光源的微尘粒径粒度检测器。
本次案例的实现流程有如下几个步骤:
1. 硬件连接
要让传感器发挥作用,第一步要实现检测器与Arduino板子的连接,GP2Y1010检测器采用6线接口:
电路接线图
1、6分别为LED、放大器电路的供电,5V
2、4为GND;
3为二极管开关,数字接口;
5为数据输出接口,模拟接口;
需要注意的是LED正极与Arduino板子相连时要加150Ω上位电阻,灯珠正负引脚间增加220μF的电容。Arduino板子上选取模拟接口A04作为检测器数据读取端口,与检测器5线(黑色)相连;选取数字接口7作为红外灯珠的开关控制端口。
面包板及Arduino连线
2. 模-压转换
探测器的检测步骤是:照射—测定—输出:
参照官方手册,一次标准的数据采集过程耗时10ms,但所有动作在前0.32ms内完成,led开启后模拟端口即有输出,并在0.28ms时达到稳定输出状态,可以读取数值,0.04ms后数据读取完成,LED关闭。
3. 浓度计算
Arduino模拟端口A04读取的数值Val为0~1025的模拟数值,对应0~5V的电压,
我们需要将模拟数值对应成为电压值:
dustVal=Val/1024*5
4. 数据标定
模拟数据转换出来的电压值并不是我们需要的雾霾微尘浓度值,我们还需要标定操作:
上图为说明书中的电压与粉尘浓度的对应曲线,我们需要找寻到电压与浓度之间的对应关系,我们发现这条曲线在雾霾浓度0~0.55mg/m³即PM2.5值在0~550之间时呈近似线性关系,雾霾浓度大于550时电压值趋于稳定。换句话说,该款检测器雾霾测定最大值就到550mg/m³左右(如果你手里PM2.5检测器到550就爆表了,那八成用的就是这款)。
在标定过程中需要注意,上图中无尘时电压输出值为0.6V左右,竟然不是手册中的标准数值0.9V:注1
注1:关于这个数值的偏差,我又找到其他GP2Y1010的手册对比,发现有一版手册中给出的电压-浓度关系是无尘0.9V的,这款检测器,夏普的第二代产品在第一代的基础上做过标定,更加精准,因未找到更进一步的资料,只能推测这种差异是因不同带标定的差异造成的,网上有说这款设备数值跳跃,有可能是网友直接将网上的程序照搬,0.3V的标定差会对检测数值产生。
那么到底应该是0.9V还是0.6V呢,我觉得这个要以检测器实际输出为准,比如我现在用的这款,输出电压值一直在0.6左右(不正经的风让全北京城PM2.5徘徊在10左右),那很明显无尘电压就不能照0.9标定。
所以遇到这类问题时,一定要具体设备具体分析,千万不要从网上直接照搬代码(否则换算完成的雾霾值会出现负值)。
要想知其然,还要知其所以然,学会自己独立分析与思考是最关键的。
那么如何根据已有的函数图像抽象出数学函数,这就变成了一个代数问题:
已知F(x)=aX+b
读图可以得到(0.4,3)和(0.5,3.5)两个点:
解方程得:a=6,b=0.6
即f(x)=6x+0.6,解得雾霾浓度:x=f(x)/6-0.1≈0.167V-0.1,此时的浓度单位为mg/m³,而PM2.5的浓度单位为μg/m³,所以要乘上换算系数1000mg/g。
这种近似会有误差,要想精准一些,还需要将检测值与已经标定精准的检测设备数值相比较,再返回来微调a、b的数值。在没有专业设备定标的前提下,个人计算出的结果会有差异,也就造成了检测数值的偏差。目前的激光光源的检测器大多直接返回雾霾浓度值,标定过程由厂家完成并写入固件,结果会更加的精准。我们之所以选用这种两年前的主流产品,更多的是体验这种标定过程中思考的乐趣。
我们再回到雾霾浓度x=0.167V-0.1这个方程式中,说明书中告诉我们无尘时电压最小可以取到0的,也就意味着检测器有可能输出小于0.6V的电压,那么为了避免检测雾霾数值为负的情况出现,我们需要在程序设计中将小于0.6V的输入作为错误输入而筛出。所以仔细的理解产品说明书可以帮我们设计出更合理更强壮的程序。
至此Arduino端的程序就算编写完成了。接下来是乐高的控制。
5. 乐高控制
获取了雾霾的浓度,需要一个指示牌来显示数值,我们顺手用乐高做了一个:
传动结构用到了轮组传动,可以实现转动距离的放大。
轮组传动及变速轮组
两级轮组半径比例为1:4,则采用小轮带大轮的方式,两者线速度相同,则按照圆周长公式L=2πR,经一组轮组变速,乐高电机转动量增加4倍,两级变速,指示牌要到达原有指定的位置,乐高舵机的转动量会增加为原有的16倍。乐高舵机控制精度可以达到1°,但经过轮组的放大,理论上控制精度可以达到1/16°。
乐高舵机的标定过程也比较简单,就是看下让指针从刻度0转到刻度500需要多少转动量,之后将转动量除以500,即可得到雾霾变化与转动量的换算比例,在我们这个例子中,这个比例为1:29.5。
传感器10ms即可完成一次测量,但乐高的舵机却无法10ms完成一次驱动。同样传感器的单次测量会存在误差,而多次测量取平均则可以消除测量误差。所以在程序中,我们设定1s/次的测量频度,取10s平均值作为乐高指示盘的显示度量,并以此控制乐高舵机调整指针位置。
雾霾严重到一定程度时,就需要戴口罩了,我们在程序中设定当PM2.5大于120时,口罩就会由托架旋出,低于120时自动收回。
我们拍摄视频时,北京刚刚发布了雾霾预警,此时朝阳区室外PM2.5浓度为175,室内按照我们乐高探测仪的指示也在150以上,口罩直接弹出,估计今晚是收不回去了...
于是我们点上一枝香,给它助助力:
未完待续,下期更精彩。
科技学堂
科技辅导员在线学习平台
微信号:sciclass