0x00 动机

本来是因为家里装了一个天然气取暖炉,所以准备买个米家的天然气报警器,不过我发现那个东西要联网的话还需要一个网关,因为报警器本身是只有 Zigbee 协议的。所以干脆自己做一个,并且加入一氧化碳的浓度检测和温湿度显示。

0x01 传感器选择

温湿度传感器比较好选,直接选用奥松的 AM2302 ,在淘宝上找的话需要搜索 DHT22 。这种传感器出厂的时候已经校准,并且使用单总线通信,直接输出数字信号。但是值得注意的是这个传感器比较脆弱,一定不要反接电源,我接反过几秒,瞬间发热到60多度。

气体传感器淘宝上最多也是最便宜的是 MQ 系列,生产厂家是炜盛科技,我买了3个这个系列的传感器分别是 MQ-2 烟雾传感器,MQ-4 天然器传感器,MQ-7 一氧化碳传感器。但是我买到之后看厂家手册发现,这个系列的传感器都是二氧化锡(SnO2)半导体传感器。也就是说他们确实可以检测到对应的气体,但是其他很多都可以对其造成干扰,例如在我测试发现 MQ-7 一氧化碳传感器对甲烷和丁烷的敏感度与 MQ-4 天然器传感器基本相同,只是零点不同。所以买这个系列的传感器只需要买一个就可以了。淘宝上的模组是帮你封装好并且加上了一个电压比较器的,气体浓度超过临界值就会直接将 DO 口置位,你也可以直接用 ADC 采样 AO 口的电压数据,得到浓度信息。不过通过厂家的文档,这个传感器没办法计算出比较精确的浓度信息,一是因为能干扰它的气体太多,二是阻抗不是线性的,三就是零点漂移比较严重。所以只能计算一个参考值,具体报警的触发浓度需要自己调试。(要想计算比较精确浓度可能需要催化燃烧式的可燃气体传感器)

一氧化碳传感器我之前说买过 MQ-7,但是我觉得无法满足要求,所以了解了一下电化学方式的一氧化碳传感器。这种比较出名的就是霍尼韦尔旗下英国 CITY 的传感器,不过太贵几乎不用考虑。还有一个就是生产 MQ 系列的厂家炜盛科技制造的 ME2-CO 电化学传感器,这个厂家封装了一个模组 ZE07-CO 出厂校准,5-12V供电,输出串行数字信号。我直接从厂家的淘宝店买的,发货比较慢,后来才知道是你买了之后发货前进行了测试,还给了检验报告。需要注意的是,这个模组的引脚插针间距是 2mm ,常用的间距是 2.54mm ,如果需要打 PCB 的要注意一下。

0x02 其他元件

MCU 使用的是 STC15W4K 系列,也可以使用 STM32 ,没什么影响。

屏幕是买的一块单色 0.96寸 12864 OLED,可以使用IIC或SPI通信,我这里选用SPI通信。

WIFI模块我看了一圈,几乎都是基于乐鑫 ESP8266 的,用不了多高级的功能,所以买安信可 ESP8266-01 。ESP8266 使用的是串口通信,并且直接用 AT 指令控制。支持微信的 AIRKISS 和 ESP-TOUCH 配网。ESP8266-01出厂的波特率是115200。上电之前要按照手册中的指示,将CH_PD(EN)脚使用上拉电阻拉高才能工作。

高分贝蜂鸣器记得买有源的,不为什么,主要是简单,上电就开始叫。

因为 STC15 自带的 ADC 对 MQ-4 传感器进行采样的时候受到当前系统电压的影响,所以使用一只 TL431 作为采样基准,输出精确 2.5V 电压,交给第二个 ADC 通道采样。

TL431电路

TL431的电路可以按照这个做,但是其中的电阻要根据实际电压取值,因为采样不需要太大的电流,因此电阻要尽量的大,但是必须保证电流在 TL431 的死区电流 1mA 以上。

0x03 软件方面

显示屏的 SPI 代码有淘宝卖家给的示例,没必要自己再写一遍了。因为没有字库,所以需要显示的汉字通过软件取模。

DHT22的通信方式跟大多数温度传感器一样,主机先把总线拉低 800μs 再释放,传感器也会拉低总线并释放,表示准备传送,之后低电平保持 50μs 后,高电平保持 26μs 为“0”,低电平保持 50μs 后,高电平保持 70μs 为“1”。传感器会连续传送5个8位数据,分别是湿度高8位,湿度低8位,温度高8位,温度低8位,8位校验位。温湿度数据都是10倍于实际值。

可燃气体传感器使用 ADC 读取电压信息,同时读取 TL431 输出的标准 2.5V 电压,使得读数稳定。具体浓度值计算就不说明了,反正都是参考。报警的浓度要自己试试,每个传感器差异比较大。同时记得软件预热延时,传感器需要预热之后读取的数值才是准确数值,不然每次冷启动的时候可能会误报。

一氧化碳传感器就比较容易了,串行口提供两种数据发送方式,一种是主动上传,一秒一次,另外一种是查询方式。我直接使用主动上传方式,单片机使用串行中断接收数据就可以了。为了节约一个定时器,所以把 WIFI 模块的波特率改成跟一氧化碳模组一样的9600就行了,节约一点是一点。

报警之后肯定要做个消音,接一个按钮到P3.2上面,开一个外部中断,平时外部拉高,当按钮按下的时候被拉低,触发中断消音,并且将一个静音标志位置1,此时不允许报警,等气体浓度降到正常值之后才将静音标志位置0,这时候才允许报警。WIFI配网我也是用这个做的,等上电运行的时候如果按钮被长按,给WIFI模块发送开始配网的信息。

0x04

ESP8266 使用的是AT指令进行通讯,内建 TCP 协议。第一次使用的时候建议更新下固件,不然你会发现很多东西跟手册不一样。AT指令的格式是AT+{}={}\r\n其中的\r\n是换行符,有些串口助手调试的时候会帮你自动发换行符,所以指令写入代码的时候需要注意。实装之前先确认模块的波特率,我为了和一氧化碳传感器波特率相同,都设置为9600,在STC15里面可以共用一个定时器。

这个模块配网需要先设置为 STATION 模式

AT+CWMODE_DEF=1\r\n

然后开启 SmartConfig (参数3为同时开始微信AirKiss和ESP-TOUCH配网)

AT+CWSTARTSMART=3\r\n

这个模式下可以使用 ESP-TOUCH(乐鑫官网有Android源码可以自己编译,Google Play 也有第三方编译好的),或者微信的 AirKiss(如果你有微信公众号可以用微信的SDK自己搭建一个,没有的话可以用“安信可科技”公众号里面的“WIFI配置”)
这种 WIFI 配置的原理都差不多,通过手机广播发送封装了 WIFI SSID 和密码的 UDP 包,在 SmartConfig 模式下的 ESP8266 模块会捕获这组 UDP 包并且释出 SSID 和密码信息,之后自行连接相关 AP。安全性嘛,可以自己考虑下。

报警消息推送,我使用的是 Server酱,发送一个 GET 消息就可以直接推送到微信。

在AT指令里面实现就是

AT+CIPMODE=1\r\n        //允许透传
AT+CIPSTART="TCP","sc.ftqq.com",80\r\n      //建立TCP连接
AT+CIPSEND\r\n      //开始TCP传输

准备好开始 TCP 传输之后,ESP8266 会发送一个">"表示已经准备好传输。
然后开始构造 HTTP 消息,HTTP 消息是 使用\r\n分隔请求字段,连续发送两个\r\n表示 HTTP 请求发送结束。(构造好的 HTTP 消息存放在数组中记得使用Code来修饰,表示存放在代码空间,如果有中文记得先编码成 UTF-8 不然无法识别)

GET /[Server酱提供的SCKEY].send?text=[消息标题]&desp[消息内容,可为空] HTTP/1.1\r\nUser-Agent: Mozilla/5.0\r\nHost: sc.ftqq.com\r\n\r\n

发送完成后会接收到 HTTP 的响应。完成后发送连续的三个“+”,退出透传。

+++

然后关闭 TCP 连接

AT+CIPCLOSE\r\n

虽然感觉 AT 指令挺方便的,不过有时候他发出的数据在 C51 里面不好界定结束,比如它的发送的数据是使用\r\n作结束的,但是例如AT+CIPSTART建立 TCP 连接之后发回的数据是CONNECT\r\n\r\nOK\r\n。并且对于51来说用数组去储存一个 HTTP 响应有点过于庞大了,我的做法是直接不管 HTTP 是否成功,只要没有设定为静音的情况下,设定一个时间,比如两分钟发送一次消息,不过有想到好的办法可以告诉我一下。

0x05 最终

因为快过年了,在淘宝上打 PCB 时间应该不够了,所以就用 STC15W 的最小系统板和洞洞板将就了一下,丑是丑了点,能用就行。

显示

传感器电路

成品

然后是微信推送的效果

微信推送

0x06 资料们

0xFF

可燃气体传感器可以用打火机测试,一氧化碳传感器不要自己作死测试。