树莓派打造的家庭环境监控 | iOS开发和七七八八

标签: 树莓派 家庭 环境 | 发表时间:2017-09-28 18:04 | 作者:
出处:http://conanwhf.github.io

最近空气质量又有下降的趋势,想想手头的RPI2B,干脆拿来改造成一个环境监控系统吧,放在客厅随时可以看到,情况不对马上开净化器😊。传感器部分都是以前就买了的,平时拿来偶尔玩一下。主要是三个:一个空气质量检测的激光传感器,一个温湿度的DHT22,一个凑数的带光感的数模转换。屏幕是一块5寸的HDMI破电阻屏,用来搭建本体的是两包白色塑料小积木,所有东西均购自淘宝,包括树莓派物料成本大约500+。说起来这个成本很高了,主要是树莓派本身加一个屏幕,光用来做这个有点浪费。好在我本来也是要放在那边当小服务器用,跑个定时脚本,偶尔看个kernel什么的。

硬件部分

因为传感器都是做好了的,树莓派自己也引出了两排Pin脚,硬件其实就是连几根线而已。只有一个问题需要考虑就是传感器都是上电即工作的,如果一直通电的话,过不了多久估计就烧了。所以我决定用GPIO当作开关来控制sensor的电源,只在需要获得数据时打开。这样一来那两个只需要3.3V的sensor还好,直接用GPIO给电即可,空气质量那个传感器需要5V的就麻烦了。还有LCD屏幕,也是要求5V,并且本身是USB供电,只好把原有的拨动开关拆了,小改电路,使用一个接入的5V电源来解决。

最终的硬件连线图如下:

你看到的是非授权版本!爬虫凶猛,请尊重知识产权!

转载请注明出处:http://conanwhf.github.io/2017/09/16/EnvMonitor/

访问原文「树莓派打造的家庭环境监控」获取最佳阅读体验并参与讨论





图中的空气质量sensor和屏幕的电源都外接了一个场效应管,用来决定5V电源Pin的通断,由一个GPIO接入来控制。空气质量的数据是UART传输,PCF8591的接口是I2C,而DHT11则直接使用GPIO的一个Pin来传输数据(总感觉有点不靠谱的),另外添加了三个LED灯来实时反应空气质量的等级。

软件部分

软件语言使用的是Python3,一个不在乎速度的上上之选。我虽然是那种一边百度一边写python的超级新手,但用过以后就再也不想换回繁琐的C了,更别说在树莓派上有那么多现成的库可以给你用。

整体结构

软件方面只有三个主要的线程,两个负责拿数据,一个负责UI:



程序跑起来后除了UI,会自己开两个线程进行循环,在循环中获取系统、sensor的状态并刷新在UI上。运行的模式有两种:实时和日常。实时模式主要是给需要迅速获得状态的时候使用,例如刚刚打开净化器想看看质量是否在持续改善,或者是网络有问题的时候看看能否ping通google;而日常模式则是无人关注的日常行为。主界面有一个按钮可以切换这两种模式,线程内部会根据切换后的状态判断自己应该睡眠多久再进行下一轮状态更新。

在日常模式中,系统每个循环会获取所有传感器的数据并更新上报至Yeelink,以及根据空气质量调整相对应的LED灯。而在实时模式,每个循环内则会另外获取一些操作系统状态来显示,并刷新ping服务器(Google)的结果。除了日常和实时两个模式中获取的状态,还有一个单独的线程用来刷新开机时间和公网IP。这两个数据对实时的要求不高,更新频率也很低,就直接固定为30分钟一次了。

传感器数据获取

传感器方面,以前都是用过的,底层的库也很成熟,所以代码量很小,主要是封装一下变成类库。要说重新写的部分,就是自己写了个Power的类,免得分散在GPIO的相关代码里面,很难看。以前用的DHT11,这次换成DHT22,懒得再自己写程序了,直接用的官方库。

UI设计

UI部分我用的Python自带的tkinter,虽然是头一次用,但毕竟是Python,随便看看文档就搞定了,API简单得不得了。当然,主要是因为我的UI很简单:显示label,button,监听点击和关闭事件就是所有需求了。而这些对于任何一个语言的UI来说,用法基本都是通用的。唯一有点不同的是它对于控件的排列方式,使用了个叫grid的方法,实际上是将整个界面划分为N*M的小方格,再通过对控件所占用方格的位置、大小、对齐属性,来决定控件的具体位置。

另外一个小问题是在调试时发生的,我发现在SSH的状态下,无法从命令行启动UI,报错的具体内容我忘了,大概意思是找不到具体设备。网上搜了一下有人遇到同样的问题,年代久远,且无人回答。后来看了下API的文档,发现窗口的初始化函数Tk是可以带参数的:

  1. 在有UI的桌面环境下打开终端,运行export
  2. 在输出结果中找到DISPLAY=XXXX的部分,比如说我的是DISPLAY=":0.0"
  3. 在代码中添加参数:tk.Tk(screenName=":0.0")

    问题解决。

数据上传

Yeelink是一个对个人用户免费的物联网服务,你可以将自己的数据上传,并在Web端查看。虽然时常抽风,但既然是免费的我还能抱怨什么呢?感谢天感谢地,感谢Yeelink让我和家人可以随时随地用手机查看家里的环境数据😜。系统每次获取到sensor的数据后会自动上报给Yeelink,让我奇怪的是官方好像只有接口文档而没有给出范例代码,网上的也大都有点过时了,害得我想偷个懒都不成。虽然GitHub上有,但我还是占用一些篇幅放出这部份代码,以造福想用搜索引擎偷懒的小朋友们吧:

#!/usr/bin/python3
import time
import json
import requests

#yeelink api配置
apiUrl='http://api.yeelink.net/v1.1/device/%s/sensor/%s/datapoints'
apiKey='123456' #请填入专属的api key
apiHeaders={'U-ApiKey':apiKey,'content-type': 'application/json'}
deviceID = 1232312
sensorID = {'pm25':123, 'pm10': 456,'temperature':789, 'humidity':111}

#上传sensor数据到yeelink
def upload_to_yeelink(name, value):
    url= apiUrl % (deviceID,sensorID[name])
    strftime=time.strftime("%Y-%m-%dT%H:%M:%S")
    #print(url, strftime)
    data={"timestamp":strftime , "value": value}
    try:
        res=requests.post(url,headers=apiHeaders,json=data, timeout=3.0)
        if res.status_code!=200:
            print("status_code:",res.status_code)
        else:
            pass
    except:
        print("report to yeelink fail")

if __name__ == "__main__":
    upload_to_yeelink('pm25', 100)

从哪里获取deviceID、sensorID我就不多说了,注册和新建的时候自然都知道了。值得一提的是其中的timeout参数(3.0那个),是因为我发现即使网络没问题,有时候也会无限卡死在等response的地方,不知道是不是服务器会抽风。

使用这段代码需要先装requests库,原因?自然是为了偷懒。不然原生的http api处理什么json, error,timeout要多写好几行呢!

其他

软件方面的其他内容还有三个小地方值得注意:

  1. 桌面图标。要想完全脱离键盘用UI来操作,一个桌面的打开快捷方式必不可少。原来我以为直接放一个main的软链接就行了,结果人家直接不显示,原来需要固定格式的桌面图标文件才行。我以chrome的图标为基准修改了一个,还能自己定义ico,挺好玩。
  2. 循环睡眠的代码。之前我想当然地在日常模式中直接写了sleep(600),结果发现这个bug太蠢了:在UI上切换入实时模式时根本无法实时响应变化,非要等10分钟后睡醒了才知道。后来就改成了无论那种模式都是每次睡一秒,醒来看看状态是否变为实时模式,以决定是否要继续睡。
  3. 循环时间。在循环中,每个cycle的时间并不真的是1秒或者10分钟,那个只是睡眠的时间;整个cycle还包括了获取数据的时间、上报数据的时间、以及其他开销。

碰到的问题

改造系统的过程中碰到了不少问题,记得起来的写一下。

电压问题

我的树莓派上除了接这些sensor和屏幕,还有一个蓝牙、一个USB WIFI、一个摄像头,可想而知耗电量是相当大的了。如果只提供5V1A的供电,系统则会在屏幕右上角显示一个黄色的闪电符号,提醒你电量不足。但即使是电量不足,程序也都是能运行的,只是……会影响sensor的读数。

刚开始放到电视柜上的时候,发现空气质量的读数突然变得巨大,完全不正常,而拿去书房debug又降下来很多(依然不正常),百思不得其解,直到把屏幕拿掉读数完全正常,才发现是给电的问题。最后我用了两个5V2A的USB供电(一个专供显示屏),才算解决了这个问题。

DHT22的官方库

说起来虽然DHT系列的sensor本身质量不怎么样,公司还不错,能提供python的库直接用,而且同时支持DHT22和DHT11。DHT11之前我是自己写的,拿一个GPIO Pin来发命令、收数据,该说这想法很👍呢还是很😫呢?其实用C还好,用python就总觉的太不……专业。DHT11的数据特别是湿度实在是太不准了,差了十万八千里,有个Pin脚好像也有点问题,于是打算换个DHT22试试。结果嘛,虽然比原来准了一点但依然有25%-40%的误差🙄,并且这个官方给的库坑得我不轻。

首先是无响应问题。在硬件都正常的情况下,API很偶尔会无响应,估计是因为timming的问题miss掉了某个状态之类的。其实timeout是有的,但是那时间长得令人发指,直接可以当作死循环了。这个问题我也懒得去搞什么花样来解决了,死等就死等吧,别真死就行。

然后是返回值的问题。返回值一般是float的,比如35.4这类,坑的是如果它是35.0,就会直接给你个int的35,害得我用.1f输出就死了,需要自己强制转换下类型;这还不够奇葩,奇葩的是如果有什么问题拿不到数据,它直接给你个NULL,害得我在转换类型时又死了😳……心累!

散热问题

除了电压,散热也是会影响sensor工作的。而最直接的影响,就是温度检测了。机器跑了两天后,我突然发现上报的温度太高,比普通温度计测量的结果高差不多4度。而同样的,当我拿去书房debug,一切又恢复了正常😓……这次我没那么傻了,估计是散热问题,之前做的积木壳,只留出一面开口用来插数据线和通风,确实散热太差,CPU长期保持在59℃也是挺吓人的。于是我将外壳加高了两层,让里面的各种线和元器件不要那么拥挤,又在侧面加了个小风扇,果然解决问题,CPU降到了45℃,温度测量也正常了。

值得一提的是这个风扇是当初买rpi亚克力壳子送的,接上之后持续发出我无法忍受的高频噪音,我这才想起来为什么当初被我扔到角落里了😌。想来想去,采取了折中的手段:将原本需要5V的风扇电源接到3.3V上,风扇转速降低,但是一点都不响了。CPU这次大概在48℃左右还可以接受,温度的sensor也读数正常。

最终效果

整个项目中,组装其实是最大的挑战:用那个小积木拼东西手太疼了啊!拼了我整整一天,手指头都脱皮了,才搞定整个造型。

这是没有盖上屏幕的样子:



以及最终成品:



项目源码已上传至GitHub:Rpi-envMonitor,欢迎Star!

相关 [树莓派 家庭 环境] 推荐:

树莓派打造的家庭环境监控 | iOS开发和七七八八

- -
最近空气质量又有下降的趋势,想想手头的RPI2B,干脆拿来改造成一个环境监控系统吧,放在客厅随时可以看到,情况不对马上开净化器😊. 传感器部分都是以前就买了的,平时拿来偶尔玩一下. 主要是三个:一个空气质量检测的激光传感器,一个温湿度的DHT22,一个凑数的带光感的数模转换. 屏幕是一块5寸的HDMI破电阻屏,用来搭建本体的是两包白色塑料小积木,所有东西均购自淘宝,包括树莓派物料成本大约500+.

树莓派NCNN环境搭建 | 异构 AI

- -
前言镜像已经做好了,传到百度网盘中了(请大家及时保存,不定期删除. https://pan.baidu.com/s/1fhiX86L8iL8tsLbsiVa6Wg密码: e64s. SD卡要求:至少16GB,板卡型号为树莓派3B+(其他型号未知). 本系列教程采用树莓派3B+开发板:. 1.4GHz 64位4核 ARM Cortex-A53 CPU.

基于「树莓派」的家庭网络服务

- - 無標題文檔
当初组建家庭网络的时候,就考虑到自己的需求:主要是网络存储、以及跑部分比较耗时的「定时任务」,例如爬虫和下载还有部分的数据处理等. 本来考虑部署一台性能相对比较好的服务器去处理,但这样子考虑到部署太过中心化不好管理,同时硬件的成本有些高而且占地的面积太大,因此就暂时被我搁置了. 后来想到 空帷 的朋友圈,使用「树莓派」这个方案相对比较轻量,同时多出来的「树莓派」还可以用来它用,因此考虑使用「树莓派」搭建自己的家庭网络服务.

从零开始搭建树莓派 + intel movidius 神经元计算棒2代深度学习环境 - Mingyong_Zhuang的技术博客 - CSDN博客

- -
从零开始搭建树莓派+intel movidius 神经元计算棒2代深度学习环境. 下载OpenVINO toolkit for Raspbian安装包:. Opencv + python api调用方法:. 本文从零开始搭建,从烧写树莓派的系统开始,到最后用计算棒跑人脸检测. 本教程适用二代的计算棒,不适合一代的计算棒.

树莓派初级折腾

- - 极客范 - GeekFan.net
前些天在网上买了一个二手的树莓派 裸板子190包邮 (新品套装280 360什么的太贵了啊岂可修). 到手目测没有问题 主IC还有一个铜质散热片 不错. 电源就用买移动电源送的充电器(标称5v 1000mA输出 )和数据线. SD卡么… 把很久没玩的PSP掏出来 把马甲卡中的东西倒到记忆棒里 记忆棒插回PSP TF卡装到转接卡上 (话说还是个class10的呢).

安装树莓派 Raspberry PI

- - CSDN博客综合推荐文章
树莓派终于到货了,是这个样子的. 上面有一行日期是 Raspberry PI (c) 2011.12. 选择这个镜像: RASPBIAN Debian 2014-01-07. 780M的压缩包,很大的样子. 似乎还有个NOOBS的安装方式,完全无感. 顺便展示一下SD卡,通过查阅可用SD卡列表,似乎是支持个别的64G Class10的卡的,就像这个,编号是 Transcend SDXC 64G Class10 TS64GSDXC10.

树莓派 1602A显示屏

- - 编程语言 - ITeye博客
树莓派 1602A显示屏. 下面代码本人测试过没有问题,开始运行完屏幕上什么也没有显示出来,后来调整了下电位器可以了,所以大家如果按着下面的做出来之后运行什么也没有显示的话,记得调整下电位器. VO,液晶对比度调节,接电位器中间的引脚,电位器两边的引脚分别接5V和接地. RS,寄存器选择,接GPIO14.

在树莓派上用python控制LED

- - 极客范 - GeekFan.net
初步学习RPi.GPIO模块的过程中写了一个控制8个LED的模块,基本上只是一个对RPi.GPIO的一个封装. 一个已经安装配置好了的树莓派. 连接控制树莓派所用的其他必须设备. 按照电路图所示,在面包板上进行连接. 首先得确定RPi.GPIO已安装. 最新的系统已经自带了,如果没有的可以使用命令.

PiLarm: 便携式树莓派警报器

- - 极客范 - GeekFan.net
我一直在寻找一些能给自己孩子带来教益的瞬间. 当我五岁的儿子来寻求我的帮助,别再让他的弟弟偷偷溜进他的房间的时候,我突然灵光一现,发现这是教他关于输入、输出和其他一些编程知识的绝佳时机. 而且让他在解决自己实际问题中学习这些也会相对容易. 我本来可以用很多不同的方法来建立一个简单的警报系统,但是我想要让这个系统是一体化的并且在功能上不止能满足我儿子最初的原始需求.

树莓派的10个最佳资源

- - 极客范 - GeekFan.net
如果还没有找到答案,你是时候要从线上或者线下的资源寻找一些想法和项目,来帮助你将树莓派的潜能完全发掘出来. 树莓派没有内置的操作系统,也经常甚至连存储设备都没有. 但树莓派已经被证明了是一个非常成功的小型计算设备. 而很多学校(树莓派的目标用户),狂热爱好者,和那些想要打造一个小型家庭影音中心(包括其他设备)的用户都将树莓派作为他们的一个选择.