3. 读取DS18B20温度传感器数据

读取DS18B20温度传感器数据 学习卡片

任务说明

本案例在树莓派上通过1-Wire协议连接DS18B20数字温度传感器,读取环境温度并显示在终端。DS18B20采用单总线通信,树莓派内核已内置驱动支持,只需在配置中启用1-Wire接口,然后从sysfs文件系统读取温度值即可。

硬件连接

DS18B20有三个引脚:VDD(红线)接3.3V,GND(黑线)接地,DQ(黄线)接GPIO4(BCM编号,物理引脚7)。DQ与VDD之间需连接4.7kΩ上拉电阻。连接完成后,在终端执行sudo raspi-config,选择Interface Options → 1-Wire → Enable,重启生效;或直接编辑/boot/config.txt添加dtoverlay=w1-gpio后重启。

树莓派 GPIO Pin 1 (3.3V) Pin 6 (GND) Pin 7 (GPIO4) DS18B20 VDD (红线) GND (黑线) DQ (黄线) 4.7kΩ 上拉电阻连接 DQ 与 VDD

实现代码

创建文件 ds18b20_read.py,代码如下:


import os
import glob
import time

# 加载1-Wire设备驱动
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

# 查找DS18B20设备地址
base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'

def read_temp_raw():
    """读取原始温度数据文件"""
    with open(device_file, 'r') as f:
        lines = f.readlines()
    return lines

def read_temp():
    """解析并返回摄氏温度值"""
    lines = read_temp_raw()
    # 等待数据校验位变为YES
    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
        return temp_c

try:
    while True:
        temperature = read_temp()
        print(f"当前温度: {temperature:.2f} °C")
        time.sleep(1)
except KeyboardInterrupt:
    print("\n程序已退出")

运行与验证

执行以下命令运行程序:

python3 ds18b20_read.py

验证方法:

  1. 程序启动后,终端每秒输出一行温度读数,格式为当前温度: XX.XX °C。
  2. 用手握住传感器探头,观察温度值应逐渐上升;松开后温度应回落至室温附近。
  3. 若提示IndexError或找不到设备,先执行ls /sys/bus/w1/devices/确认是否存在以28-开头的目录;若不存在,检查硬件连接及1-Wire是否已启用。

预期输出示例(温度值随环境变化,非固定值):


当前温度: 23.56 °C
当前温度: 23.56 °C
当前温度: 23.62 °C

判定标准:终端能持续输出合理的温度读数(通常在0~50°C范围内),且温度随传感器实际温度变化而波动,即视为案例通过。程序通过Ctrl+C可正常终止。