Overview

DS18B20是一个比较常用的温度传感器,采用单总线控制,以前用单片机编程控制时严格按照单总线的时序控制,今天来看看在树莓派Raspbian系统下如何控制DS18B20,体验一下在linux世界,一切都是文件。读取DS18B20温度也是对文件的操作。

DSC_5465

Parts

为了完成本项目需要用到如下器件

PI
Pi3 x1
EASM100100
DS18B20 x1
EACW100500
杜邦线 x3

Hardware

将DS18B20温度传感器模块的”S”引脚接到树莓派的4脚(BCM编码方式);”-“接到树莓派的GND引脚;DS18B20中间应交接到树莓派5V电源处。如图

ds18b20_python

加载内核单总线模块

Raspbian支持单总线协议,能挂接如DS18B20之类的单总线设备,并读取其数据。但是需要加载这个模块

在命令行输入如下命令

sudo nano /boot/config.txt

将光标移动到最后添加下面一句话

dtoverlay=w1-gpio

按下键盘上的Ctrl X后按照提示保存退出

查看模块是否启动

重启树莓派是上面的配置生效

sudo reboot

待树莓派启动起来后,命令行输入

lsmod

如果如发现红色方框所示说明模块已启动。

2017-03-20-075235_1824x984_scrot

如果没有发现,也可以运行如下命令加载模块

sudo modprobe w1-gpio
sudo modprobe w1-therm

读取温度

如果一切顺利,在/sys/bus/w1/devices中发现一个28-XXXX开头的文件夹,这个就是DS18B20的ROM,每个DS18B20都一样,在这个文件夹中读取w1_slave文件则会返回当前温度值。

sudo modprobe w1-gpio
sudo modprobe w1-therm
cd /sys/bus/w1/devices
cd /28-xxxxxx
cat w1_slave

Software

用nano编辑器新建一个temp.py文件,并输入如下代码

sudo nano temp.py
import os
import glob
import time

os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'

def read_temp_raw():
    f = open(device_file, 'r')
    lines = f.readlines()
    f.close()
    return lines

def read_temp():
    lines = read_temp_raw()
    while lines[0].strip()[-3:] != 'YES':
        time.sleep(0.2)
        lines = read_temp_raw()
    equals_pos = lines[1].find('t=')
    if equals_pos != -1:
        temp_string = lines[1][equals_pos+2:]
        temp_c = float(temp_string) / 1000.0
        temp_f = temp_c * 9.0 / 5.0 + 32.0
        return temp_c, temp_f
  
while True:
  print('C =%3.3f F = %3.3f'% read_temp())  
  time.sleep(1)

上面的代码将每隔1秒钟以摄氏温度和华氏温度的格式打印一次温度值。

2017-03-20-084757_1824x984_scrot

注解:1)os.system(‘modprobe w1-gpio’)os.system(‘modprobe w1-therm’)两句在程序的开头运行了一下modprobe命令

2)base_dir = ‘/sys/bus/w1/devices/’和device_folder = glob.glob(base_dir + ’28*’)[0] 是获取/sys/bus/w1/devices/下面所有以28开头的目录文件

 

3)device_file = device_folder + ‘/w1_slave’ 打开文件并读取数据

 

4)while lines[0].strip()[3:] != ‘YES’: 判断所读取文件的第一行的末尾三个字符是否等于YES

5)equals_pos = lines[1].find(‘t=’) 查找所读取文件中第二行中t=开始的位置,如果查找失败返回-1