树莓派实战:基于PCF8591与NTC热敏电阻的智能温控系统搭建

张开发
2026/4/12 7:24:19 15 分钟阅读

分享文章

树莓派实战:基于PCF8591与NTC热敏电阻的智能温控系统搭建
1. 智能温控系统搭建背景最近在折腾树莓派的时候发现用NTC热敏电阻做温度监测特别有意思。这种小玩意儿成本不到5块钱但灵敏度比普通温度传感器高得多。我去年给家里的鱼缸做过一个温度报警器就是用这套方案实现的实测误差可以控制在0.5℃以内。PCF8591这个模数转换器算是老演员了8位分辨率虽然比不上专业设备但对于日常监测完全够用。最关键的是它支持4路模拟输入通过I2C接口和树莓派通信接线简单到只需要4根线。记得第一次用的时候我对着电路图研究了半小时结果发现实际连接5分钟就能搞定。2. 硬件准备与电路连接2.1 必备组件清单这次项目需要准备的材料我都列在下面了大部分在某宝都能一站式购齐树莓派4B3B也行PCF8591模块注意要带排针的版本NTC热敏电阻模块推荐10K B值3950的型号面包板和杜邦线建议买彩色的方便区分40pin排线如果是树莓派4B需要这种宽排线特别提醒下买NTC模块时要看准参数。有次我贪便宜买了B值不一样的结果温度计算全乱套了后来才发现卖家标的是B值3470。现在学乖了直接买大厂出的模块贵是贵点但省心。2.2 电路连接详解接线其实就两个关键点一是PCF8591的I2C地址设置二是热敏电阻的模拟信号接入。具体连接方式如下先把PCF8591插到面包板上VCC接5VGND接地SDA和SCL分别接到树莓派的GPIO2和GPIO3热敏电阻模块的AO引脚连PCF8591的AIN0DO引脚可以空着我们这次用不到数字输出有个容易踩坑的地方PCF8591模块上可能有地址选择跳线帽。我遇到过默认地址是0x48的版本也有0x49的建议先用i2cdetect命令确认下sudo i2cdetect -y 13. 软件环境配置3.1 启用I2C接口树莓派默认是关闭I2C的需要先开启。在终端输入sudo raspi-config选择Interfacing Options - I2C - Yes重启后生效。验证是否成功可以看/dev目录下有没有i2c-1设备。3.2 安装必要库我们需要smbus库来处理I2C通信python3环境下安装命令是sudo apt-get install python3-smbus建议再装个matplotlib后面做温度曲线可视化会用到pip3 install matplotlib4. 核心代码解析4.1 PCF8591驱动封装我习惯把硬件操作封装成类这样主程序看起来更清爽。下面这个PCF8591.py可以直接复用import smbus import time class PCF8591: def __init__(self, address0x48): self.bus smbus.SMBus(1) self.address address def read(self, chn): # chn: 0-3 try: self.bus.write_byte(self.address, 0x40chn) self.bus.read_byte(self.address) # dummy read return self.bus.read_byte(self.address) except Exception as e: print(fRead error: {str(e)}) return None def write(self, val): try: self.bus.write_byte_data(self.address, 0x40, int(val)) except Exception as e: print(fWrite error: {str(e)})4.2 温度计算算法NTC的温度计算要用到Steinhart-Hart公式我把它拆解成了三步def calculate_temp(adc_value): # 第一步ADC值转电压 vr 5 * adc_value / 255 # 第二步计算热敏电阻阻值 rt 10000 * vr / (5 - vr) # 10K分压电阻 # 第三步Steinhart-Hart公式计算温度 temp_k 1 / (math.log(rt/10000)/3950 1/(273.1525)) return temp_k - 273.15 0.5 # 补偿0.5度误差实测发现这个算法在20-40℃范围内最准超出这个范围建议做分段校准。我在车库温度监测项目里就做了三组不同参数误差能控制在0.3℃以内。5. 智能温控逻辑实现5.1 基础阈值判断最简单的温控就是设置上下限阈值。我在代码里加了滞后区间防止温度在临界点反复跳变def control_logic(temp): global status if temp 33 and status ! HOT: print(温度过高启动散热) status HOT # 这里可以加GPIO控制风扇的代码 elif temp 31 and status ! COLD: print(温度正常) status COOL # 关闭散热设备5.2 进阶PID控制如果想做得更专业可以上PID算法。下面是个简化版实现class SimplePID: def __init__(self, kp, ki, kd): self.kp kp self.ki ki self.kd kd self.last_error 0 self.integral 0 def compute(self, setpoint, pv): error setpoint - pv self.integral error derivative error - self.last_error output self.kp*error self.ki*self.integral self.kd*derivative self.last_error error return output使用时先初始化PID参数需要根据系统特性调整pid SimplePID(kp2.0, ki0.5, kd1.0) output pid.compute(30, current_temp) # 30是目标温度6. 系统优化与扩展6.1 数据可视化用matplotlib可以轻松实现温度曲线展示import matplotlib.pyplot as plt def plot_temperature(temp_history): plt.figure(figsize(10,5)) plt.plot(temp_history, r-, labelTemperature) plt.axhline(y33, colorb, linestyle--, labelUpper Limit) plt.axhline(y31, colorg, linestyle--, labelLower Limit) plt.ylabel(Temperature (℃)) plt.xlabel(Time (s)) plt.legend() plt.savefig(temp_trend.png)6.2 微信报警功能通过server酱可以实现微信推送报警消息import requests def send_alert(message): url fhttps://sc.ftqq.com/YOUR_KEY.send params {text: 温度警报, desp: message} requests.get(url, paramsparams)记得把YOUR_KEY换成自己的SCKEY这个在server酱官网注册就能拿到。7. 常见问题排查上周帮网友调试时遇到几个典型问题这里分享下解决方案ADC读数不稳定检查电源是否加了滤波电容建议在VCC和GND之间加个100uF电容尝试缩短传感器到PCF8591的导线长度在代码里加个移动平均滤波def smooth_read(adc, chn, n5): return sum(adc.read(chn) for _ in range(n)) / nI2C设备找不到确认raspi-config里已启用I2C检查接线是否正确特别是SDA和SCL不要接反有些PCF8591模块需要上拉电阻可以尝试在SDA和SCL上加4.7K电阻到3.3V温度计算偏差大确认使用的NTC型号参数是否正确用万用表实测分压电阻的精确阻值在已知温度下比如冰水混合物0℃进行校准

更多文章