← 返回传感器图鉴

DS18B20 防水温度传感器

最后更新 2026-06-20
⏱ 约 6 分钟 🟡 涉接线/强电
🛒 器材清单
器材数量参考
DS18B20 防水探头1
4.7kΩ 电阻1

价格随渠道波动,以购买页实时为准。

要测一缸鱼的水温,或者堆肥箱里深浅三个点同时测温——这时候 DHT22 帮不上忙:它是裸露的塑料栅格,沾水就废,而且一颗只能测一个地方。DS18B20 正相反。它有一根金属探头用环氧或不锈钢封死,整根泡进液体里没问题;更妙的是一根数据线能串好几颗,每颗各报各的温度。水温、土温、3D 打印热床、锅炉管壁,这些场景几乎是它的主场。

工作原理

DS18B20 用的是 Dallas 的 1-Wire 单总线协议。名字里的"单"指的是:除了电源和地,真正传数据只用一根线。这一根线既负责主控(如 ESP32)发命令下去,也负责芯片把温度数据传上来,靠时序分时复用。

它能一根线挂多颗的关键,在于每颗芯片出厂时都烧死了一个全球唯一的 64 位 ROM 地址。这 64 位里前 8 位是家族码(DS18B20 固定是 0x28),中间 48 位是序列号,没有两颗重复,末尾 8 位是 CRC 校验。主控在总线上喊话时,先用"匹配 ROM"命令点名某个地址,只有地址对上的那颗芯片才会应答。所以哪怕十颗芯片并排挂在同一根线上,也能被一颗一颗精确点名、分别读温——这就是单线挂多点的全部秘密。

另一个省事的地方:它内部直接做好了温度到数字的转换,输出的就是数字量,不像热敏电阻那种模拟量还得接 ADC、写查表公式、做校准。数字进数字出,没有 ADC 误差这回事。模拟和数字传感器的区别,可以看 模数转换 这篇。

它还支持一种"寄生供电"模式,可以省掉 VDD 那根线、只用数据线取电,但接线讲究多、稳定性差,新手直接用三线正常供电即可,这里不展开。

接线

标准三线接法(以 ESP32 GPIO4 为例)。防水探头通常是三根色线:

DS18B20 探头线 接到 说明
VDD(红) 3.3V 也兼容 5V
DATA(黄/白) GPIO4 数据线,需上拉
GND(黑) GND 公共地
—— 4.7kΩ 电阻 跨接在 DATA 与 VDD 之间

关键就是那只 4.7kΩ 上拉电阻,一端接 DATA、一端接 VDD。单总线平时靠上拉保持高电平,没有它总线浮空,读出来全是乱码或 -127。上拉的道理见 上拉电阻,GPIO 本身怎么回事见 GPIO 是什么。有些现成的 DS18B20 模块板上已经焊了这只电阻,裸探头则一定要自己加。

完整代码

用 OneWire 和 DallasTemperature 两个库(Arduino 库管理器里都能搜到)。下面这段会先扫描总线上有几颗芯片,再逐颗读温:

#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 4          // DATA 接 GPIO4

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

void setup() {
  Serial.begin(115200);
  sensors.begin();

  int count = sensors.getDeviceCount();   // 扫描总线上的设备数
  Serial.print("找到 ");
  Serial.print(count);
  Serial.println(" 颗 DS18B20");
}

void loop() {
  sensors.requestTemperatures();           // 命令全部芯片开始转换

  int count = sensors.getDeviceCount();
  for (int i = 0; i < count; i++) {
    float c = sensors.getTempCByIndex(i);  // 按索引读第 i 颗
    if (c == DEVICE_DISCONNECTED_C) {      // 即 -127,没读到
      Serial.print("芯片 ");
      Serial.print(i);
      Serial.println(" 断线");
    } else {
      Serial.print("芯片 ");
      Serial.print(i);
      Serial.print(": ");
      Serial.print(c);
      Serial.println(" °C");
    }
  }
  delay(2000);
}

requestTemperatures() 是一条广播命令,让总线上所有芯片同时启动一次温度转换;12 位精度下这次转换最久要 750ms,所以读数前别催太急。

你应该看到什么

串口监视器(115200 波特率)正常会刷出:

找到 2 颗 DS18B20
芯片 0: 23.50 °C
芯片 1: 24.31 °C
芯片 0: 23.56 °C
芯片 1: 24.25 °C

如果看到 找到 0 颗 或者温度是 -127.00,先别怀疑代码,八成是上拉电阻或接线的问题(见下方故障表)。

多点测温与读数解读

上面的代码用 getTempCByIndex(i) 按索引读,简单,但索引顺序由扫描决定、换个芯片可能就乱。要稳定区分"哪根探头在哪个位置",应该按 64 位地址读:先用 sensors.getAddress(addr, i) 把每颗的地址抓出来记下,之后用 sensors.getTempC(addr) 指定地址读温。这样哪怕加减芯片,每个监测点对应哪颗都不会错位——这正是 1-Wire 唯一地址的用处。

几个该记住的数:

  • 量程:-55 ~ +125°C。家用水温、土温、热床都在范围内。
  • 精度:-10 ~ +85°C 区间内约 ±0.5°C,是个相当不错的数字温度传感器。
  • 分辨率:可设 9 / 10 / 11 / 12 位,对应 0.5 / 0.25 / 0.125 / 0.0625°C。位数越高越细,但转换越慢(12 位约 750ms)。库默认通常是 12 位。

选型与避坑

什么时候用 DS18B20、什么时候用别的:

  • 要防水、要远距离、要一根线测多个点 → DS18B20。探头泡水里、埋土里都行,多点阵列是它的强项。
  • 只想测室内空气温度,还想顺带测湿度DHT22 或入门的 DHT11。它们能给湿度,但不防水、单点、精度一般。两者的上手可看 DHT11 入门实验
  • 要高精度温湿度:那是 SHT30/SHT40 一类 I²C 传感器的活,不在本页。
🚧 避坑

读到 -127 几乎一定是没连上:上拉电阻没接、线断了、GPIO 接错。读到固定 85 则多半是上电后还没完成第一次转换就去读了——85°C 是芯片寄存器的上电默认值,意味着"我还没测出来"。遇到 85,检查是不是 requestTemperatures() 没调用、或者读得太急没等够转换时间。

故障排查

现象 可能原因 处理
找到 0 颗 / 读到 -127 没接 4.7kΩ 上拉、或接错位置 在 DATA 与 VDD 间补上 4.7kΩ
读到固定 85 没等转换完成就读 确认调了 requestTemperatures(),读前留够延时
多颗只认出 1 颗 长线 + 多颗导致总线驱动不足 上拉换 3.3kΩ 或缩短总线、改星形为链形
温度乱跳 接触不良、电源不稳 检查焊点,电源就近加 0.1µF 退耦
完全无反应 GPIO 引脚号写错 核对 ONE_WIRE_BUS 与实际接线一致

进阶与变体

把多颗 DS18B20 都并在同一根 DATA 线上(各自地址唯一),就组成了一条温度阵列:一个 GPIO 就能监测一长串点位,省引脚又省线。比如发酵罐从顶到底插三四颗看温度梯度、温室不同高度布点、地暖回路逐段测温,都是这种玩法。总线拉长(几米到十几米)时,把上拉从 4.7kΩ 适当减小(如 3.3kΩ)、走链形而非星形布线,能更稳。

更进一步,多点温度数据采上来后交给模型做异常检测或趋势预测,是常见的下一步,可参考 让 AI 帮你处理传感器数据

典型应用

  • 鱼缸 / 泳池 / 热水器水温监测
  • 土壤、堆肥、发酵罐温度(探头直接插进去)
  • 3D 打印机热床、挤出机温度
  • 冰箱 / 冷链多点温度记录
  • 沿管路布一串探头做温度阵列

小结 · 相关

DS18B20 = 数字输出 + 防水探头 + 一根线挂多颗(靠 64 位唯一地址点名)。记住两件事就能少踩坑:DATA 对 VDD 必须有 4.7kΩ 上拉-127 是没连上、85 是还没测好。要测水/土/多点选它,只测室内空气湿度选 DHT 系列。

相关阅读:DHT22 · DHT11 · 上拉电阻 · 模数转换 · 回到 传感器总览原理总览

参数以 datasheet 为准;本页公开资料整理,接线与代码请结合实物验证。

📄 来源 / 自校链接

本文为公开资料整理,非亲测。关键参数与代码请结合实物与下列官方来源验证。

内容有错、看不懂、或想看下一期?告诉我们 →

本文为公开资料的学习整理,非亲测。涉接线/花钱/合规的步骤请结合实物与官方最新资料验证,风险自负。见免责声明