树莓派使用DS18B20读取室内温度并语音播报

树莓派 杨博, 卫 967次浏览 0个评论

感觉测量温度蛮实用的,做物联网嘛,不测量温度怎么能自己开电风扇和空调?

一、材料

1、树莓派(Raspberry Pi)一个
2、DS18B20温度传感器一个(淘宝大概5元左右)
3、4.7kΩ—10kΩ电阻一个 或 DS18B20模块一个(淘宝1.5元一个,其实就是店家帮忙把电阻焊好了,接线稍好看些)。
4、杜邦线三根(双头母)

二、接线方式

如图所示,重点就是DS18B20的DATA脚要加上拉电阻,这个电阻理论上4.7kΩ—10kΩ都行,我用的是4.7kΩ。
20131003214031676

 

三、开机自动加载模块

首先要在/boot/config.txt中加入dtoverlay=w1-gpio-pullup,gpiopin=4。但是要先解锁/boot。

sudo mount /boot -o remount,rw
sudo vi /boot/config.txt

然后在文件末尾另起一行,添加(图上我的DATA口接在GPIO4上,按照你的情况修改下面代码中的gpiopin的值)

dtoverlay=w1-gpio-pullup,gpiopin=4

保存并退出。
然后编辑/etc/modules

sudo vi /etc/modules

文件末尾另起一行,添加下面的内容

w1-gpio
w1-therm

保存,退出并重启树莓派。

四、测试模块

cd /sys/bus/w1/devices/
ls

已经加载的总线模块会出现在在这里,DS18B20模块都是28-开头的文件夹,如果没找到,可以执行lsmod查看已经加载的模块,来查看是否正确加载。

下图我的目录结构
QQ截图20160821170646
cd进那个28-xxxxxxxxxxxx文件夹,然后

cat w1_slave

看到上图最后t=28250就是当前的温度值,要换算成摄氏度,除以1000,即当前温度为28250/1000=28.250摄氏度。

五、C语言获取当前温度

原帖在此:http://bradsrpi.blogspot.jp/2013/12/c-program-to-read-temperature-from-1.html
我直接copy下来了

#include 
#include 
#include 
#include 
#include 
#include 
     
int main (void) {
 DIR *dir;
 struct dirent *dirent;
 char dev[16];      // Dev ID
 char devPath[128]; // Path to device
 char buf[256];     // Data from device
 char tmpData[6];   // Temp C * 1000 reported by device 
 char path[] = "/sys/bus/w1/devices"; 
 ssize_t numRead;
 
 dir = opendir (path);
 if (dir != NULL)
 {
  while ((dirent = readdir (dir)))
   // 1-wire devices are links beginning with 28-
   if (dirent->d_type == DT_LNK && 
     strstr(dirent->d_name, "28-") != NULL) { 
    strcpy(dev, dirent->d_name);
    printf("\nDevice: %s\n", dev);
   }
        (void) closedir (dir);
        }
 else
 {
  perror ("Couldn't open the w1 devices directory");
  return 1;
 }

        // Assemble path to OneWire device
 sprintf(devPath, "%s/%s/w1_slave", path, dev);
 // Read temp continuously
 // Opening the device's file triggers new reading
 while(1) {
  int fd = open(devPath, O_RDONLY);
  if(fd == -1)
  {
   perror ("Couldn't open the w1 device.");
   return 1;   
  }
  while((numRead = read(fd, buf, 256)) > 0) 
  {
   strncpy(tmpData, strstr(buf, "t=") + 2, 5); 
   float tempC = strtof(tmpData, NULL);
   printf("Device: %s  - ", dev); 
   printf("Temp: %.3f C  ", tempC / 1000);
   printf("%.3f F\n\n", (tempC / 1000) * 9 / 5 + 32);
  }
  close(fd);
 } 
        /* return 0; --never called due to loop */
}

你可以保存为w1.c,用下面语句编译。

gcc -Wall -std=gnu99 w1.c -o w1

直接运行w1即可。这个代码就是我现在用的,什么都不用改,直接运行就可以出结果。

六、Python获取当前温度

代码来源:http://shumeipai.nxez.com/2013/10/03/raspberry-pi-temperature-sensor-monitors.html

#打开温度传感器文件,注意更改下面红色的文件夹名称
tfile = open("/sys/bus/w1/devices/28-00000494cb79/w1_slave")
#读取文件所有内容
text = tfile.read()
#关闭文件
tfile.close()
#用换行符分割字符串成数组,并取第二行
secondline = text.split("\n")[1]
#用空格分割字符串成数组,并取最后一个,即t=23000
temperaturedata = secondline.split(" ")[9]
#取t=后面的数值,并转换为浮点型
temperature = float(temperaturedata[2:])
#转换单位为摄氏度
temperature = temperature / 1000
#打印值
print temperature

文件存放:/home/pi/temperature.py
在命令行运行,即可得出结果数值:

python /home/pi/temperature.py

我对Python一窍不通,这个代码我也没有测试过,大家有兴趣自行测试啊。

七、用Shell脚本获取当前温度

千行代码不如一行Shell,让你们见识一下Shell的威力吧。

#! /bin/bash
#注意替换文件夹的名称!
roomtemp=$(cat /sys/bus/w1/devices/28-00000801796e/w1_slave | grep  -E -o ".{0,0}t=.{0,5}" | cut -c 3-)
echo -n "Temperature:"
echo "scale=3;$roomtemp/1000"|bc

保存为tempture.sh并退出,运行之前注意加权限啊:

chmod +x ./tempture.sh

八、语音播报当前温度

这个可以和我之前的语音报时脚本结合起来。运行之前先要安装Mplayer。

#!/bin/sh
#注意替换文件夹的名称!
rawtemp=`cat /sys/bus/w1/devices/28-00000801796e/w1_slave | grep  -E -o ".{0,0}t=.{0,5}" | cut -c 3-`
temp=`echo "scale=1;$rawtemp/1000"|bc`
time=`date +%R`
mplayer "http://tts.baidu.com/text2audio?lan=zh&ie=UTF-8&text=现在时间是$time,室内温度为$temp度&spd=4"

保存为tts.sh,注意加权限:

chmod +x ./tts.sh

把音响开到合适的音量,然后运行吧!

 

 

 


本文版权:霜之哀伤 转载请注明树莓派使用DS18B20读取室内温度并语音播报
喜欢 (3)or分享 (0)
杨博, 卫
关于作者:
喜欢折腾路由器,懂一点Linux,最近正在学习树莓派...
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址