树莓派+多个DS18B20+Yeelink,全天候监测多个点的温度

时间:2013年08月08日 14:01 星期四 栏目:未分类 作者: 评论:24 点击: 8,149 次

更新:在树莓派系统某次更新之后,突然读不到 w1_bus_master1 了,

解决方法是:在/boot/config.txt配置文件的最后添加如下内容: dtoverlay=w1-gpio-pullup,gpiopin=4
====================================

终于淘了几个温度传感器DS18B20,关于这个传感器的特点就不多说了,可以用一个IO口挂多个传感器,就可以监测多个点的温度。用树莓派可以全天候工作,功耗低,再配合Yeelink,可以定时把数据传到网上,随时可以查看温度状态。

 

多个DS18B20接到树莓派上去是这样接的(如下图):

把传感器并连起来,VDD脚接3.3V电压,GND脚接地,DQ脚接到pi的GPIO接口的 GPIO4# pin脚。VDD脚与DQ脚之间挂4.7KΩ的电阻。

如果不想自己焊电阻的话,在买DS18B20(4、5元)的同时可以跟店家买DS18B20的电路模块(1、2元)。

树莓派+多个DS18B20电路简图

树莓派+多个DS18B20电路简图

实物接起来如下(点击看大图):

 

树莓派+多个DS18B20实物图

树莓派+多个DS18B20实物图

 

然后就是用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

 

参考文章:
http://blog.sina.com.cn/s/blog_3cb6a78c0101a46w.html
http://www.cnblogs.com/qtsharp/archive/2013/06/25/3154300.html

相关文章

树莓派+多个DS18B20+Yeelink,全天候监测多个点的温度:目前有24 条留言

  1. 经过测试,用 –data-binary “{“value”:120}” 这种格式可以成功提交,用变量构造这种格式就可以不成生成文件,直接提交。

    2014-08-04 12:51
  2. 7楼
    陈景熙:

    为什么要接在GPIO4才有反应 接在其它引脚没反应呢

    2014-03-23 20:11
  3. 6楼
    关子:

    我想问一下 ,为什么我总是找不到传感器,ls出来没有传感器的名字,,求帮助 ,很紧急 0.0

    2014-03-16 11:22
    • 预计你的没有加载w1的驱动

      2014-03-16 21:11
      • 大尖说得有道理。加载了W1还不行,那就只能回头再排除是否接错,或物理接连不牢靠。

        2014-03-17 08:13
        • 我把这两句指令都加载了sudo modprobe w1-gpiosudo modprobe w1-therm。但是我的传感器没有外接一个电阻,是不是可能关这个问题。

          2014-03-23 14:03
      • DS18B20有没有分类型的?我淘宝买回来的,但是我没有外接4.77KΩ的电阻或模块,是不是关这个问题?

        2014-03-23 14:08
        • 做个试验吧,我没试过这个 。上回把pi装成rascbm之后可以看电影,就是corn有问题,没自动提交温度。也懒得去弄它了。

          2014-03-25 21:23
  4. 5楼
    李大尖:

    奇怪,我的一起良好,但是数据只上传一段时间就上传了

    2014-03-15 20:47
  5. 4楼
    aloading:

    终于找到 DS18B20 读取温度频繁出现-0.062°C的原因了

    2013-11-22 11:49
  6. 地板
    MakGP:

    好郁闷,我两个传感器,有一个在室外的,有时候会出现85度的数值

    2013-09-04 11:03
    • 我也出现过85度的值,而且校验也可以通过,经过观察,貌似传感器第一次上电的时候才会出现这种情况,那就每回读两次,丢掉第一次的值就OK。如果是测试室温的,也可以加个条件,大于80度的就重读。

      2013-09-04 11:28
      • MakGP:

        具体怎么改?我不太懂,我都是全抄你的代码的

        2013-09-04 13:51
        • 在“flag = False”这一行的前面加上这三行:tfile = open(“/sys/bus/w1/devices/%s/w1_slave” %name)text = tfile.read()tfile.close()就是先读一次值,然后直接丢掉不做处理。

          2013-09-05 11:32
          • MakGP:

            如果大于80度丢掉要怎么写?

            2013-09-05 21:10
          • MakGP:

            今天感觉应该是第一次做的线路有点问题,今天重新做了一次,换了旧的电线,估计会好转,如果大于80度丢掉要怎么写?

            2013-09-05 21:11
  7. 板凳
    NO:

    每个传感器只能触发一条微博?有没有办法整合多个传感器的数据就发一条微博?

    2013-08-25 20:40
  8. 沙发
    恋雪如霜:

    感觉好棒的样子

    2013-08-22 08:43

发表评论

您必须 [ 登录 ] 才能发表留言!

Baidu提供的广告

最近访客

    最新评论