Arduino温度传感器实战:从LM35到DS18B20的硬件连接与数据采集

发布时间:2026/8/1 18:50:45
Arduino温度传感器实战:从LM35到DS18B20的硬件连接与数据采集 1. 项目概述从“感知温度”到“数据世界”的第一步温度传感器听起来是个简单的小玩意儿不就是测个温度吗但如果你玩过Arduino、树莓派或者任何单片机你就会知道这个小东西是你连接物理世界和数字世界最经典、也最关键的入口之一。它不像控制一个LED灯那样直观也不像驱动一个舵机那样有直接的物理反馈。温度传感器的魅力在于它悄无声息地将我们身边最普遍的环境参数——热量转化成了单片机能够理解和处理的电信号一串串数字。这个过程就是“模拟信号采集”的生动课堂。无论是想做一个智能恒温花房一个提醒你咖啡温度的杯垫还是一个简易的室内环境监测站温度传感器都是你绕不开的第一个“感知器官”。这个项目我们就以最普及的Arduino平台和最常见的模拟温度传感器如热敏电阻或LM35为例手把手带你走通从硬件连接到数据读取、再到串口可视化的完整流程让你不仅知其然更知其所以然。2. 核心硬件选型与原理浅析2.1 常见温度传感器类型与选择面对琳琅满目的温度传感器新手最容易犯晕。我们主要接触的有三大类模拟传感器、数字传感器和集成模块。模拟温度传感器比如热敏电阻NTC和LM35是入门首选。它们的输出是连续的电压值需要接入单片机的模拟输入引脚Analog Input 如Arduino的A0-A5。热敏电阻的电阻值随温度变化而非线性变化价格极低但需要搭配一个固定电阻组成分压电路并通过公式计算才能得到温度值精度一般适合对成本敏感、精度要求不高的场景。LM35则友好得多它直接输出电压每摄氏度对应10mV在0°C时输出0V读取电压后简单乘上100就能得到摄氏温度线性度好使用简单。注意选择热敏电阻时要关注它的标称阻值如10kΩ和B值一个描述其电阻-温度曲线特性的常数不同B值的元件计算公式中的参数也不同不能混用。数字温度传感器比如鼎鼎大名的DS18B20。它通过单总线1-Wire协议与单片机通信只需要一根数据线外加电源和地线就能工作并且支持在一条总线上挂载多个传感器每个都有全球唯一的64位地址非常适合需要多点测温的场合。它直接将温度值以数字形式传给单片机精度高典型±0.5°C抗干扰能力强但驱动稍复杂需要对应的库文件支持。集成模块比如Grove - Temperature Sensor。这类产品通常已经将传感器可能是热敏电阻或数字芯片和必要的电路如分压电阻、信号调理电路集成在一块小板上并配备了标准的连接器如Grove的4针接口。它的最大优点是即插即用省去了搭建外围电路的麻烦特别适合快速原型开发和学生实验。我们这次会以最基础的模拟传感器LM35和便捷的Grove模块两种方式并行讲解让你理解底层原理的同时也能享受模块化开发的便利。2.2 核心电路原理模拟信号是如何产生的我们以最经典的热敏电阻固定电阻分压电路为例拆解一下模拟信号的产生过程。假设我们有一个10kΩ的NTC热敏电阻在25°C时阻值为10kΩ和一个10kΩ的固定电阻。我们将它们串联接在Arduino的5V引脚和GND之间。热敏电阻和固定电阻的连接点我们引出一根线接到模拟输入引脚A0。这个电路就是一个简单的分压器。根据欧姆定律A0引脚检测到的电压V_sensor等于V_sensor 5V * (R_fixed / (R_ntc R_fixed))。这里R_fixed是固定电阻10kΩR_ntc是热敏电阻的实时阻值。当温度升高时NTC热敏电阻的阻值R_ntc下降导致V_sensor电压升高温度降低时则相反。于是温度的变化就被转换成了A0引脚上0-5V之间的一个电压变化。Arduino的模拟输入引脚内部有一个模数转换器ADC它负责将这个连续的电压值量化为一个离散的数字值。对于Arduino Uno它的ADC是10位精度的意味着它可以将0-5V的电压范围划分为2^10 1024个等级。所以当A0引脚电压为0V时读到的模拟值analogRead(A0)是0电压为5V时读到的值是1023。我们读到的这个0-1023之间的整数就是温度信息的“数字影子”。对于LM35原理更直接它的输出电压与摄氏温度成线性正比10mV/°C。我们同样将其输出接到A0读取电压值Voltage (analogRead(A0) * 5.0) / 1023.0那么温度Temperature Voltage * 100。这里乘以5.0是因为参考电压是5V除以1023.0是将ADC读数转换为电压。3. 硬件连接与电路搭建实操3.1 方案一使用分立元件LM35这是最“硬核”也最能理解原理的方式。你需要准备Arduino Uno开发板一块、LM35温度传感器一个、面包板一块、若干杜邦线。连接步骤供电将Arduino的5V引脚用杜邦线连接到面包板的电源正极排孔将GND引脚连接到电源负极排孔。放置LM35将LM35芯片跨坐在面包板的中缝上确保三只引脚分别位于不同的行。LM35有字的一面朝向自己从左至右引脚依次为VCC电源正极、Vout信号输出、GND电源负极。连接线路VCC引脚用杜邦线连接到面包板的5V正极排。GND引脚用杜邦线连接到面包板的GND负极排。Vout引脚用杜邦线连接到Arduino的模拟输入引脚A0。检查确保连接牢固没有短路特别是正负极短接。LM35不需要任何额外的电阻或电容。实操心得LM35的引脚比较细插入面包板时要小心避免弯折过度导致断裂。如果读取的温度值跳动很大可以在LM35的Vout和GND之间并联一个0.1uF的瓷片电容用于滤除电源噪声这是数据手册上推荐的用法实测能显著稳定读数。3.2 方案二使用Grove模块如果你有Grove系列的LM35模块或热敏电阻模块过程就简单多了。你需要Arduino Uno、Grove Base Shield扩展板、Grove温度传感器模块、一根Grove连接线。连接步骤安装扩展板将Grove Base Shield直接插在Arduino Uno的引脚上确保方向正确引脚对应。连接模块将Grove连接线的一端插入温度传感器模块另一端插入Base Shield上标有“A0”的模拟接口通常是黄色标识。完成无需额外接线。Grove系统已经内部集成了分压电路和标准接口供电和信号传输都通过这一根四芯线完成。两种方案对比特性分立元件 (LM35)Grove模块学习价值高能透彻理解传感器原理、ADC转换过程一般侧重于应用和快速实现搭建复杂度中需要手动接线有出错风险低即插即用几乎零错误灵活性高可以自由设计外围电路低电路固定不可更改成本低中适合场景教学、深入理解、定制化电路快速原型、项目集成、初学者体验4. 软件编程与数据读取4.1 基础代码实现读取与串口打印无论使用哪种硬件方案在Arduino IDE中的代码逻辑是相通的。我们以LM35为例编写基础代码。// 项目七 - 温度传感器 (基于LM35) // 定义传感器连接的模拟引脚 const int sensorPin A0; void setup() { // 初始化串口通信设置波特率为9600 // 波特率是数据传输速率发送和接收端必须一致 Serial.begin(9600); // 可以打印一个开始提示信息 Serial.println(LM35 Temperature Sensor Start...); } void loop() { // 1. 读取模拟值 int sensorValue analogRead(sensorPin); // 此时sensorValue是一个0-1023之间的整数 // 2. 将模拟值转换为电压值 (参考电压为5V) float voltage sensorValue * (5.0 / 1023.0); // 使用5.0和1023.0是为了进行浮点数计算提高精度 // 3. 将电压值转换为温度值 (LM35: 10mV/°C) float temperatureC voltage * 100.0; // 4. 通过串口打印结果 Serial.print(Sensor Value: ); Serial.print(sensorValue); Serial.print( | Voltage: ); Serial.print(voltage, 2); // 保留两位小数 Serial.print(V | Temperature: ); Serial.print(temperatureC, 1); // 保留一位小数 Serial.println(°C); // 延时1秒避免串口输出过快导致刷屏 delay(1000); }代码关键点解析analogRead(pin)这是核心函数读取指定模拟引脚上的电压并返回10位精度的整数值0-1023。(5.0 / 1023.0)这是ADC的分辨率即每个数字单位代表的电压值约为4.9mV。这个计算是模拟信号数字化的核心。voltage * 100.0这是LM35特有的转换公式源于其10mV/°C的灵敏度。Serial.print()用于向串口监视器发送数据是调试和查看数据的生命线。4.2 使用串口监视器查看数据上传代码后打开Arduino IDE的串口监视器工具 - 串口监视器或快捷键CtrlShiftM。确保右下角的波特率设置为9600与代码中Serial.begin(9600)一致。你将看到每秒一行数据输出显示了原始的ADC读数、计算出的电压和最终的摄氏温度。注意事项串口监视器是单向的主要接收来自Arduino的数据。如果你发现没有数据请依次检查1) 代码是否上传成功2) 开发板型号和端口选择是否正确3) 串口监视器波特率是否匹配4) 硬件连接是否可靠。4.3 代码优化滤波与精度提升直接读取的值可能会因为电源噪声、电磁干扰等有微小跳动。我们可以通过软件滤波来获得更稳定、平滑的读数。最简单有效的方法是移动平均滤波。const int sensorPin A0; const int numReadings 10; // 平均滤波的采样次数 int readings[numReadings]; // 存储采样值的数组 int readIndex 0; // 当前读数的索引 int total 0; // 采样值的总和 int average 0; // 平均值 void setup() { Serial.begin(9600); // 初始化数组全部置零 for (int thisReading 0; thisReading numReadings; thisReading) { readings[thisReading] 0; } } void loop() { // 减去最早的读数加上最新的读数 total total - readings[readIndex]; readings[readIndex] analogRead(sensorPin); total total readings[readIndex]; readIndex readIndex 1; // 如果到达数组末尾则回到开头 if (readIndex numReadings) { readIndex 0; } // 计算平均值 average total / numReadings; // 使用滤波后的平均值进行计算 float voltage average * (5.0 / 1023.0); float temperatureC voltage * 100.0; Serial.print(Filtered Temperature: ); Serial.print(temperatureC, 2); Serial.println(°C); delay(100); // 可以缩短采样间隔因为滤波本身有延时效果 }这段代码维护了一个包含最近10次采样值的数组每次循环都计算这10个值的平均数作为最终采样值。这种方法能有效抑制随机干扰使温度读数非常平稳。numReadings的值越大曲线越平滑但对温度变化的响应也越慢需要根据实际应用权衡。5. 深入应用与功能扩展5.1 实现温度报警功能单纯的读取和显示只是第一步让系统能根据温度做出反应才是自动化的开始。我们可以添加一个LED作为报警指示灯。硬件添加在原有电路基础上将一个LED的正极长脚通过一个220Ω的限流电阻连接到Arduino的数字引脚13负极短脚连接到GND。代码修改const int sensorPin A0; const int ledPin 13; // 报警LED引脚 float highTempThreshold 30.0; // 高温报警阈值单位°C void setup() { Serial.begin(9600); pinMode(ledPin, OUTPUT); // 将LED引脚设置为输出模式 digitalWrite(ledPin, LOW); // 初始状态关闭LED } void loop() { int sensorValue analogRead(sensorPin); float voltage sensorValue * (5.0 / 1023.0); float temperatureC voltage * 100.0; Serial.print(Temperature: ); Serial.print(temperatureC, 1); Serial.println(°C); // 判断逻辑如果温度超过阈值则点亮LED否则熄灭 if (temperatureC highTempThreshold) { digitalWrite(ledPin, HIGH); // 点亮LED Serial.println(ALERT: Temperature too HIGH!); } else { digitalWrite(ledPin, LOW); // 熄灭LED } delay(1000); }这个简单的“如果-那么”逻辑就构成了一个最基本的自动控制系统。你可以将LED换成蜂鸣器、继电器控制风扇或加热器就变成了一个实用的温控装置。5.2 制作一个简单的温度数据记录仪我们可以让Arduino不仅显示当前温度还能记录一段时间内的最高温和最低温。const int sensorPin A0; float maxTemp -100.0; // 初始化为一个极低值 float minTemp 200.0; // 初始化为一个极高值 void setup() { Serial.begin(9600); } void loop() { int sensorValue analogRead(sensorPin); float voltage sensorValue * (5.0 / 1023.0); float temperatureC voltage * 100.0; // 更新最高和最低温度记录 if (temperatureC maxTemp) { maxTemp temperatureC; } if (temperatureC minTemp) { minTemp temperatureC; } // 打印当前温度及历史记录 Serial.print(Current: ); Serial.print(temperatureC, 1); Serial.print(°C | Max: ); Serial.print(maxTemp, 1); Serial.print(°C | Min: ); Serial.print(minTemp, 1); Serial.println(°C); delay(5000); // 每5秒记录一次 }这段代码在每次循环时都更新maxTemp和minTemp变量。由于Arduino断电后变量会丢失这只是一个运行期间的记录。如果想永久保存就需要引入EEPROM单片机内部的小容量非易失存储器或者外接的SD卡模块。5.3 进阶探索使用DS18B20数字传感器当你的项目需要更高的精度、更远的传输距离或多点测温时DS18B20是更好的选择。它需要OneWire和DallasTemperature这两个库的支持。安装库在Arduino IDE中点击“工具” - “管理库”搜索“OneWire”和“DallasTemperature”并安装。硬件连接DS18B20有三根线VCC DQ GND。DQ数据线需要接一个4.7kΩ的上拉电阻到VCC然后连接到Arduino的某个数字引脚如引脚2。编写代码#include OneWire.h #include DallasTemperature.h #define ONE_WIRE_BUS 2 // 数据线连接的引脚 OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(oneWire); void setup() { Serial.begin(9600); sensors.begin(); // 初始化传感器总线 } void loop() { sensors.requestTemperatures(); // 发送命令请求所有传感器转换温度 float tempC sensors.getTempCByIndex(0); // 获取总线上第一个传感器的摄氏温度值 Serial.print(Temperature: ); Serial.print(tempC); Serial.println(°C); delay(1000); }使用库之后代码变得异常简洁。sensors.getTempCByIndex(0)中的0代表总线上第一个传感器。如果挂载多个可以通过改变索引来读取不同传感器。DS18B20的精度和抗干扰能力在复杂环境中优势明显。6. 常见问题排查与调试心得在实际操作中你肯定会遇到各种“坑”。下面是我总结的一些典型问题及解决方法。问题现象可能原因排查步骤与解决方案串口监视器无任何输出1. 代码未上传成功2. 串口未正确打开或波特率不匹配3. 硬件连接错误特别是电源1. 检查IDE右下角开发板和端口选择重新上传。2. 关闭再打开串口监视器确认波特率为9600。3. 用万用表测量传感器VCC和GND之间是否有5V电压。温度读数始终为0或接近01. 传感器信号线未接或接触不良2. 传感器损坏3. (LM35)参考电压计算错误1. 检查A0引脚连接重新插拔。2. 更换一个传感器试试。3. 检查代码中(5.0 / 1023.0)计算是否正确确认Arduino供电是否为5V。温度读数异常高如几百摄氏度1. 传感器短路或接反2. 模拟引脚悬空未接任何信号3. 分压电路计算错误热敏电阻1. 断电检查电路确认LM35引脚连接顺序。2. 确保信号线牢固连接。3. 对于热敏电阻复核分压公式和电阻值。温度读数跳动剧烈1. 电源噪声2. 接线过长或接触电阻大3. 电磁干扰1. 在传感器电源引脚附近并联一个0.1uF电容到地。2. 缩短导线使用质量好的杜邦线。3. 采用上文介绍的移动平均滤波软件算法。DS18B20读取失败返回-127°C1. 上拉电阻未接或阻值不对2. 接线错误3. 库未正确安装或引脚定义错误1. 确保在数据线和VCC间连接了4.7kΩ电阻。2. 仔细检查VCC DQ GND三线连接。3. 重新安装库检查代码中ONE_WIRE_BUS的引脚号。调试心得分享分步调试法不要一次性写完全部代码。先写一段只读取analogRead并打印原始值的代码确认硬件通路是通的。再加上电压转换看电压值是否在合理范围LM35在室温下大约0.2-0.3V。最后做温度转换。这样一旦出错你能快速定位问题阶段。善用串口Serial.print()是你最好的朋友。除了打印最终结果可以把中间变量如sensorValue,voltage都打印出来观察数据流是否合乎逻辑。理解“地”的重要性所有GND必须连接在一起构成共同的参考点。如果传感器和Arduino的“地”没连好读数会完全不准。这是新手最容易忽略的隐形问题。供电要干净USB口供电有时会因为电脑负载变化而有微小波动。如果对精度要求高可以考虑使用外部稳定的5V电源给Arduino供电或者使用板载的3.3V输出作为ADC参考电压需修改代码中的参考电压值并调用analogReference(EXTERNAL)或INTERNAL。温度传感器的响应时间传感器本身和其封装都有热惰性。不要期望它像电子信号一样瞬间变化。测量液体或固体温度时需要一定时间才能达到平衡。快速移动传感器会导致读数滞后。温度传感器项目虽然基础但它完美串联了模拟电路、数字采集、软件处理和系统控制等多个嵌入式开发的核心概念。从读取一个稳定的温度值开始到实现报警、记录、甚至通过网络上报数据这条路径清晰地展示了一个物联网感知节点是如何构建的。我个人的体会是把这个项目吃透后面再接触光照传感器、声音传感器、气体传感器等你会发现原理都是相通的——无非是感知物理量转换为电信号模拟或数字再由单片机处理。最重要的不是记住LM35的公式而是掌握“传感器单片机”这套解决问题的通用方法论。当你下次看到一个新的传感器时能自信地去翻它的数据手册看懂它的电气特性、接口协议然后把它用起来那这个项目的目标就真正达到了。