概述

        在物联网和嵌入式系统开发中,温度监测是一项基础而重要的功能。DS18B20作为一款高精度、应用于环境监控、智能家居、支持单总线通信的数字温度传感器,因其布线简单、可多点组网、测温范围广等优点,被广泛农业大棚等多种场景。本文将结合硬件设计与软件实现,详细介绍如何在ESP32平台上使用MicroPython驱动单个DS18B20温度传感器,并通过轮询机制稳定读取温度数据。


一、DS18B20传感器特性简介

        DS18B20是一款数字温度传感器,其核心优势在于采用单总线(1-Wire)协议,仅需一根数据线即可完成供电(可选寄生供电)和通信。主要技术参数如下:

  • 测温范围:-55°C ~ +125°C
  • 精度:±0.5°C(在-10°C ~ +85°C范围内)
  • 分辨率可调:9~12位(默认12位)
  • 转换时间:最长约750ms(12位精度)
  • 支持多设备挂载:每个设备具有唯一64位ROM地址

本文聚焦于单个DS18B20的应用场景,因此无需复杂设备寻址逻辑,简化了系统设计。


二、硬件连接与电路原理图设计

在ESP32与DS18B20的连接中,需确保单总线协议的电气特性满足要求。以下是推荐的硬件连接方式:

 1. 原理图

此连接方式适用于大多数开发板,如ESP32等。若使用面包板搭建,请确保接线牢固,避免接触不良导致通信异常。

2. 引脚连接说明
DS18B20引脚 功能说明 连接至ESP32
VDD 电源正极 3.3V
GND 电源地 GND
DQ 数据输入/输出 GPIO22(或其他GPIO)
3. 关于上拉电阻

由于单总线协议依赖于总线空闲时的高电平状态,必须在DQ与VDD之间接入一个4.7kΩ的上拉电阻。该电阻确保在无设备驱动总线时,信号线保持高电平,避免通信失败。


三、MicroPython代码实现

以下代码实现了对单个DS18B20的温度采集,重点在于非阻塞式轮询读取机制的设计,避免因频繁读取或等待转换造成系统卡顿。

from ds18x20 import DS18X20
from onewire import OneWire
from machine import Pin
import time

class TimeMs:
    '''时间控制器'''
    def __init__(self, val: int ,start=0):
        '''
        :param val: 时间间隔 毫秒
        :param start: 开始时间的起始位置-start 毫秒
        '''
        self._interval = val  # 时间间隔
        self._start = time.ticks_ms() -start  # 开始时间
    def change(self, val: int):
        '''改变时间间隔'''
        self._interval = val
    def reset(self):
        '''重置计时'''
        self._start = time.ticks_ms()  # 开始时间
    def update(self):
        '''更新时间'''
        t1 = time.ticks_ms()
        if t1 - self._start >= self._interval:
            self._start = t1
            return True
        return False

class DS18B20:
    def __init__(self, pin=22):
        self.ds = DS18X20(OneWire(Pin(pin)))
        self._timeMs = TimeMs(800)
        self.roms = self.ds.scan()[0]
    def scan(self):
        '''扫描设备'''
        if self._timeMs.update():
            self.ds.convert_temp()
            return True
        return False
        
    def get(self):
        """获取温度(摄氏度)"""
        if self.scan():
            return self.ds.read_temp(self.roms)
        return None
1.使用示例
# 使用示例
ds18b20 = DS18B20()
while True:
    temp = ds18b20.get()
    if not temp is None:
        print(temp)
    time.sleep_ms(1)

输出数据:

五、代码实现与核心逻辑解析

        整个代码结构,采用了非阻塞式定时轮询机制,避免了传统 time.sleep() 带来的程序阻塞问题,提升了系统的响应性和可扩展性。

from ds18x20 import DS18X20
from onewire import OneWire
from machine import Pin
import time
  • OneWire:实现单总线协议的基础类,用于在指定 GPIO 引脚上模拟 1-Wire 通信时序。
  • DS18X20:封装了对 DS18B20 芯片的操作指令,如启动温度转换和读取结果。
  • Pin:用于配置和控制 ESP32 的 GPIO 引脚。
  • time:提供时间相关函数,如 ticks_ms() 用于获取毫秒级时间戳。

2. 自定义时间控制器:TimeMs 类

        为了实现精确且非阻塞的时间控制,代码中定义了一个 TimeMs 类,用于管理周期性任务的执行时机。

class TimeMs:
    '''时间控制器'''
功能说明:
  • __init__(val, start):初始化一个时间控制器,val 为触发间隔(毫秒),start 可用于偏移初始时间,实现“延迟首次触发”。
  • update():核心方法,判断距离上次触发是否已超过设定间隔。如果是,则更新起始时间并返回 True,否则返回 False
  • 使用 time.ticks_ms() 而非 time.sleep(),实现了非阻塞延时,非常适合在主循环中与其他任务并行运行。

✅ 优势:避免使用 time.sleep(0.8) 这类阻塞调用,允许系统在等待期间处理其他任务(如 Wi-Fi 通信、按键检测等)。


3. DS18B20 驱动类实现
class DS18B20:
    def __init__(self, pin=22):
        self.ds = DS18X20(OneWire(Pin(pin)))
        self._timeMs = TimeMs(800)
        self.roms = self.ds.scan()[0]
  • OneWire(Pin(pin)):在指定引脚(默认 GPIO22)上创建单总线通信接口。
  • DS18X20(...):包装 OneWire 接口,提供高级操作。
  • self.ds.scan():扫描总线上所有 DS18B20 设备,返回 ROM 地址列表。由于本文使用单个传感器,直接取第一个地址 self.roms = ...[0]

⚠️ 注意:若总线上无设备或连接异常,scan() 可能返回空列表。

    def scan(self):
        '''启动温度转换(轮询触发)'''
        if self._timeMs.update():
            self.ds.convert_temp()
            return True
        return False
    • scan() 方法名虽为“扫描”,实则用于定时启动温度转换
    • 每隔 800ms 触发一次 convert_temp(),符合 DS18B20 在 12 位精度下约 750ms 的转换时间要求。
    • 启动转换后立即返回 True,表示“已更新”,为下一步读取做准备。
        def get(self):
            """获取温度(摄氏度)"""
            if self.scan():
                return self.ds.read_temp(self.roms)
            return None
    • get() 是对外提供的温度读取接口。
    • 每次调用时,先通过 scan() 判断是否该启动新一轮转换。
    • 若是,则启动转换并立即读取上一次的转换结果(MicroPython 的 read_temp() 会自动等待完成)。
    • 若未到周期,则跳过本次读取,返回 None,避免重复或无效读取。

    🔄 工作流程:

    1. 第 0ms:调用 get() → 启动转换 A,返回 None(尚无数据)
    2. 第 800ms:调用 get() → 启动转换 B,读取转换 A 的结果
    3. 第 1600ms:启动转换 C,读取转换 B 的结果 ……
      实现了“启动与读取”交错进行的高效机制。

    五、设计亮点总结

    特性 说明
    非阻塞设计 使用 TimeMs 替代 sleep,系统可并行处理其他任务
    精准定时 800ms 周期匹配 DS18B20 转换时间,确保数据有效性
    简洁接口 get() 一键获取温度,内部自动管理转换流程
    可扩展性强 易于修改为多传感器支持或集成到 Web 服务中

    六、结语

    本文通过一个简洁而高效的代码实现,展示了如何在 ESP32 的 MicroPython 环境下驱动 DS18B20 温度传感器。借助自定义的 TimeMs 时间控制器,实现了稳定、非阻塞、周期性的温度采集机制,为后续构建环境监控系统、物联网终端等应用打下坚实基础。代码结构清晰,易于理解与复用,非常适合初学者入门和项目集成。

    Logo

    openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

    更多推荐