给机器人做环境感知,温度是最基础的一路信号。DS18B20 是玩家里用得最多的数字温度传感器:单总线通信,一根数据线就能读数,还支持多个传感器挂在同一条总线上。这次把 Random Nerd Tutorials 上 Rui Santos 那篇 ESP32 教程的骨架理顺,接线、装库、代码、串口结果一次讲全,新手照着做就能出数。
先认识 DS18B20:单总线、可并联、有防水款
DS18B20 是单总线数字温度传感器,只需要一根数据线(加地线)就能和 ESP32 通信。它可以直接外部供电,也能从数据线上"偷电"工作,这种叫寄生模式,省掉一根电源线。每个传感器出厂自带唯一的 64 位序列号,所以多个传感器可以并联在同一根数据线上,用同一个 GPIO 分别读出各自温度。
按官方数据手册的标称:供电范围 3.0V 到 5.5V,测温范围零下 55 度到正 125 度,在零下 10 到 85 度区间精度正负 0.5 度。做机器人本体温度监测、水箱水温、机箱散热这些场景完全够用。它还有不锈钢探头包裹的防水款,线长可到 1 米以上,丢进鱼缸测水温是经典玩法。
接线:一根数据线加一颗 4.7k 上拉电阻
需要的材料:ESP32 开发板、DS18B20 传感器(普通三脚或防水款都行)、一颗 4.7k 欧电阻、杜邦线和面包板。

接法很简单:传感器 VCC 接 ESP32 的 3V3,GND 接 GND,数据线接 GPIO 4。关键点是 VCC 和数据线之间必须接一颗 4.7k 欧的上拉电阻,没有这颗电阻,单总线拉不起来,读数会一直失败。普通三脚款平面朝自己,从左到右是 GND、数据、VCC;防水款按线的颜色分:红线接 VCC,黑线接 GND,黄线是数据。数据线接 GPIO 4 是这篇教程的约定,换别的 GPIO 也行,代码里改一个数字就好。
装两个库:OneWire 和 DallasTemperature
打开 Arduino IDE,先确认已经装好 ESP32 开发板支持包,然后在 Sketch > Include Library > Manage Libraries 里搜 "onewire",安装 Paul Stoffregen 的 OneWire 库;再搜 "Dallas",安装 Miles Burton 的 DallasTemperature 库。装完重启一次 IDE。
单传感器:十几行代码读出温度
单传感器场景下最省事的写法是按索引取值,代码如下(头文件按平台兼容写法用双引号包含):
/*********
Rui Santos
Complete project details at https://RandomNerdTutorials.com
*********/
#include "OneWire.h"
#include "DallasTemperature.h"
// GPIO where the DS18B20 is connected to
const int oneWireBus = 4;
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(oneWireBus);
// Pass our oneWire reference to Dallas Temperature sensor
DallasTemperature sensors(&oneWire);
void setup() {
// Start the Serial Monitor
Serial.begin(115200);
// Start the DS18B20 sensor
sensors.begin();
}
void loop() {
sensors.requestTemperatures();
float temperatureC = sensors.getTempCByIndex(0);
float temperatureF = sensors.getTempFByIndex(0);
Serial.print(temperatureC);
Serial.println("ºC");
Serial.print(temperatureF);
Serial.println("ºF");
delay(5000);
}
逻辑拆开看:先建一个 OneWire 实例绑在 GPIO 4 上,再把它的引用交给 DallasTemperature。loop 里每次先调 requestTemperatures() 让传感器发起一次转换,然后用 getTempCByIndex(0) 取总线上第一个设备的摄氏温度。选开发板和串口后上传,打开串口监视器,波特率 115200,每 5 秒刷新一次读数。

多传感器:靠序列号区分,一根线挂多个点
想在一根总线上挂多个 DS18B20,单靠索引就不够了,需要先枚举总线上每个设备的 64 位地址,再按地址取温度。官方示例的思路是:setup 里用 getDeviceCount() 拿到设备数量,逐个用 getAddress() 取出地址并打印;loop 里先 requestTemperatures(),然后遍历地址用 getTempC(地址) 读各自的温度。地址是一个 8 字节的 DeviceAddress 数组,打印出来形如 28 FF 77 62 40 17 04 31,头一个字节 0x28 就是 DS18B20 的家族码。把每个传感器的地址抄下来贴标签,后面就能固定"几号探头是哪里"。
两个常见坑提前说:一是读数返回 -127 度,基本就是上拉电阻没接或数据线接错引脚,先查 4.7k 那颗电阻;二是串口报 "Found ghost device",多半是杜邦线接触不良或者并联的线太长,把接线压紧、缩短总线一般就解决。读取失败时 getTempC 会返回 -127,代码里可以拿这个值做异常判断,别把 -127 当真实温度写进日志。
再进一步:网页端看温度
串口看数只是第一步,这篇教程的进阶部分是用 ESPAsyncWebServer 和 AsyncTCP 两个库把温度做成网页:ESP32 起一个 80 端口的异步服务器,路由根路径返回带温度占位符的 HTML,/temperaturec 和 /temperaturef 两个路由返回纯文本温度,网页端用 JavaScript 每 10 秒拉一次新值,不用刷新页面。loop 里用 millis() 定时每 30 秒更新一次温度变量。把代码里的 SSID 和密码换成自己的 Wi-Fi,上传后串口会打印 IP 地址,浏览器访问就能看到实时温度页。对做机器人监控面板的人来说,这一步几乎是现成的模板。
总结
DS18B20 加 ESP32 是成本最低的温度感知方案:接线只要一颗 4.7k 电阻,库装好之后十几行代码出数,多传感器还能共用一根数据线。先在串口把读数调通,再考虑上防水探头和网页展示,节奏别反过来。手头有 ESP32 的,一个下午就能把这套东西跑起来。











Waterproof 版测鱼缸水温yyds,就是线接头一定做好防水
这个 4.7k 上拉电阻真的是新手的生死线,我当年就是漏了它,串口死活读不出数,还以为板子坏了。后来按单总线的原理一想才明白,数据线没人拉高的话总线根本起不来。文章里把 -127 当异常值的提醒也很实用,建议直接写进判断代码里。
一根线挂好几个探头这个点好玩,机箱里外各来一个刚好
getTempCByIndex(0) 这个写法对单传感器确实最省事,不过挂多个之后就得老老实实按地址读了,教程衔接得挺顺