终于淘了几个温度传感器DS18B20,关于这个传感器的特点就不多说了,可以用一个IO口挂多个传感器,就可以监测多个点的温度。用树莓派可以全天候工作,功耗低,再配合Yeelink,可以定时把数据传到网上,随时可以查看温度状态。
多个DS18B20接到树莓派上去是这样接的(如下图):
把传感器并连起来,VDD脚接3.3V电压,GND脚接地,DQ脚接到pi的GPIO接口的 GPIO4# pin脚。VDD脚与DQ脚之间挂4.7KΩ的电阻。
如果不想自己焊电阻的话,在买DS18B20(4、5元)的同时可以跟店家买DS18B20的电路模块(1、2元)。
实物接起来如下(点击看大图):
然后就是用python代码及sh脚本来实现剩下的事情。
正确连接好DS18B20之后,运行以下命令添加W1模块
1 2 |
sudo modprobe w1-gpio sudo modprobe w1-therm |
然后进入下面的目录查看,
1 |
cd /sys/bus/w1/devices/ |
就可以得到类似的结果:
1 2 |
pi@raspberrypi /sys/bus/w1/devices $ ls 28-000004d00992 28-000004d085aa 28-000004d12e94 w1_bus_master1 |
那三个28开头的文件就是我挂上去的三个DS18B20设备,每个18B20的代号是唯一的,都不一样,像我这样情况,可以通过这三条命令读取传感器的值:
1 2 3 |
cat /sys/bus/w1/devices/28-000004d085aa/w1_slave cat /sys/bus/w1/devices/28-000004d12e94/w1_slave cat /sys/bus/w1/devices/28-000004d00992/w1_slave |
读出来的结果类似下面:
1 2 |
70 01 4b 46 7f ff 10 10 e1 : crc=e1 YES 70 01 4b 46 7f ff 10 10 e1 t=23000 |
第一行最后为“YES”表示校验正确,为“NO”则代表校验出错,或读不到温度值。
第二行最后的数据为温度值,除以1000就是摄氏度。
接下来新建py文件:
1 |
nano temperature.py
|
输入以下代码,注意三个name变量的值要根据实际情况修改,然后Ctrl+X保存退出。
我把读到的温度值以JSON格式的TXT文件保存到 /mnt/tmp下面,注意先创建这个目录。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
#temperature.py #coding=utf8 #!/usr/bin/env python name3="28-000004d00992" name1="28-000004d085aa" name2="28-000004d12e94" def DS18B20(name): #循环10次,如果读到检验值为YES,就取值退循环,如果10次都出错,暂不处理。 flag = False for i in range(1, 10): tfile = open("/sys/bus/w1/devices/%s/w1_slave" %name) #读取文件所有内容 text = tfile.read() #关闭文件 tfile.close() #取第一行的最后一个词,即检验结果 YES/NO firstline = text.split("\n")[0] strCRC = firstline.split(" ")[11] if strCRC == 'YES': flag = True #用换行符分割字符串成数组,并取第二行 secondline = text.split("\n")[1] #用空格分割字符串成数组,并取最后一个,即t=23000 temperaturedata = secondline.split(" ")[9] #取t=后面的数值,并转换为浮点型 temperature = float(temperaturedata[2:]) #转换单位为摄氏度 temperature = temperature / 1000 res = '{"value":%.1f}' %temperature #保存到/mnt/tmp/$name.txt output = open( "/mnt/tmp/"+name+".txt", 'w') output.write(res) output.close #结束循环 break DS18B20(name1) DS18B20(name2) DS18B20(name3) |
然后新建temperature.sh,用于把温度值传到Yeelink上去。
1 |
nano temperature.sh
|
输入下面代码,U-ApiKey及传感器的URL根据你在Yeelink帐号的实际情况而不同。
1 2 3 4 5 |
sudo python /mnt/tmp/temperature.py #注意我的py文件放在这个目录 /mnt/tmp/temperature.py curl --request POST --data-binary @"/mnt/tmp/28-000004d085aa.txt" --header "U-ApiKey:XXXXXXXX" --verbose http://api.yeelink.net/v1.0/device/XXXX/sensor/XXXA/datapoints curl --request POST --data-binary @"/mnt/tmp/28-000004d12e94.txt" --header "U-ApiKey:XXXXXXXX" --verbose http://api.yeelink.net/v1.0/device/XXXX/sensor/XXXB/datapoints curl --request POST --data-binary @"/mnt/tmp/28-000004d00992.txt" --header "U-ApiKey:XXXXXXXX" --verbose http://api.yeelink.net/v1.0/device/XXXX/sensor/XXXC/datapoints |
保存退出之后要给sh文件加可执行属性:
1 |
sudo chmod +x temperature.sh |
后面的开机启动及定时执行可参考我的另一篇文章:《用物联网记录树莓派的工作温度》
1 |
sudo nano /etc/rc.local |
在exit 0这行之上写上
1 2 |
modprobe w1-gpio modprobe w1-therm |
这样就可以开机自动加载W1模块。
其它说明:那个py文件里读温度时之所以要循环10次,遇到校验正确的值就结束循环,是由于偶尔会读出一些不正确的值,实测中有时会读到一个-62的值,转换后四舍五入就是-0.1℃,这个错误的值也被传到Yeelink上去了。所以采用这个方式,校验码错了就重读,同时避免一直读不到正确的值出现死循环,连续10次出错的概率可以认为是零,除非传感器坏了或线路没接好。
Yeelink还可以添加触自动发微博,这样搞个小号,当温度值符合触发条件时就发一条微博@一下微博大号。
有兴趣可以到我的Yeelink页面围观:http://www.yeelink.net/devices/3908