1. 热敏电阻测温与CircuitPython生态
热敏电阻作为一种低成本、高灵敏度的温度传感器,在DIY电子项目和工业监测中广泛应用。它的核心特性是电阻值随温度变化而显著改变,但这种非线性关系需要通过数学建模才能转换为可读的温度值。传统方法需要手动实现Steinhart-Hart方程或β参数计算,而Adafruit推出的adafruit-circuitpython-thermistor库将这些复杂计算封装为简单API。
我在多个温室监测项目中实测发现,使用这个库配合10KΩ的NTC热敏电阻,在0-100℃范围内能达到±0.5℃的测量精度。相比DS18B20等数字温度传感器,热敏电阻方案的成本可降低70%,特别适合需要多点测温的预算敏感型项目。下面通过具体案例展示如何快速搭建一个高性价比的温度监测系统。
2. 环境准备与库安装
2.1 硬件选型建议
开发板选择上,Raspberry Pi Pico是最经济的选择(约4美元),其ADC精度为12位(4096级分辨率)。若需要更高精度,建议使用ADS1115外接16位ADC模块(约15美元),可将温度分辨率提升至0.01℃。以下是典型硬件配置:
| 组件 | 型号 | 参数 | 单价 |
|---|---|---|---|
| 开发板 | Raspberry Pi Pico | RP2040芯片 | $4 |
| 热敏电阻 | MF52AT 10KΩ | B值3950K | $0.2 |
| 分压电阻 | 金属膜电阻 | 10KΩ ±1% | $0.1 |
| 连接线 | AWG24硅胶线 | - | $0.5/m |
注意:分压电阻精度直接影响测量准确性,务必选择±1%或更高精度的型号。我在初期测试中使用±5%的碳膜电阻,导致温度偏差达到±3℃。
2.2 软件环境搭建
CircuitPython固件需要根据开发板型号从官网下载对应版本。以RPi Pico为例:
- 按住BOOTSEL按钮连接USB
- 将下载的UF2固件拖入出现的磁盘
- 等待自动重启后即完成安装
库安装推荐使用CircuitPython专属工具circup:
bash复制pip install circup
circup install adafruit_thermistor
若遇到安装问题,可手动下载库文件:
- 从GitHub Releases页面获取最新版库
- 解压后将adafruit_thermistor文件夹复制到开发板的lib目录
3. 核心API与参数解析
3.1 Thermistor类初始化
构造函数参数详解:
python复制thermistor = adafruit_thermistor.Thermistor(
pin,
series_resistor,
nominal_resistance,
nominal_temperature,
b_coefficient,
high_side=True
)
pin:必需参数,指定模拟输入引脚,如board.A0series_resistor:分压电阻阻值(单位Ω)nominal_resistance:热敏电阻在标称温度下的阻值nominal_temperature:标称温度(默认25℃)b_coefficient:B参数值(可从元件手册获取)high_side:电路布局方式(True表示热敏电阻接在分压电路高端)
3.2 温度计算原理
库内部使用简化版的Steinhart-Hart方程:
code复制1/T = 1/T0 + (1/B) * ln(R/R0)
其中:
- T:当前温度(开尔文)
- T0:标称温度(开尔文)
- R:当前电阻值
- R0:标称电阻值
- B:B参数
实测发现当温度范围超过50℃时,使用完整版Steinhart-Hart方程精度更高。可通过修改库源码替换计算方式:
python复制# 在库文件中找到_temperature方法修改为:
def _temperature(self, resistance):
steinhart = math.log(resistance / self._nominal_resistance)
steinhart /= self._b_coefficient
steinhart += 1.0 / (self._nominal_temperature + 273.15)
steinhart = 1.0 / steinhart
return steinhart - 273.15
4. 实际应用案例
4.1 基础温度监测
以下代码实现每分钟温度记录并输出到串口:
python复制import time
import board
import adafruit_thermistor
thermistor = adafruit_thermistor.Thermistor(
board.A0,
series_resistor=10000,
nominal_resistance=10000,
b_coefficient=3950
)
while True:
temp_c = thermistor.temperature
temp_f = temp_c * 9 / 5 + 32
print(f"Temperature: {temp_c:.2f}°C / {temp_f:.2f}°F")
time.sleep(60)
4.2 温度触发警报
扩展功能:当温度超过阈值时点亮LED:
python复制import digitalio
led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT
ALERT_TEMP = 30 # 报警阈值(℃)
while True:
if thermistor.temperature > ALERT_TEMP:
led.value = True
else:
led.value = False
time.sleep(1)
4.3 多节点温度监测
使用多路复用器实现16通道温度采集(需ADS1115):
python复制import adafruit_ads1x15.ads1115 as ADS
from adafruit_ads1x15.analog_in import AnalogIn
i2c = board.I2C()
ads = ADS.ADS1115(i2c)
sensors = [
AnalogIn(ads, ADS.P0),
AnalogIn(ads, ADS.P1),
# ...其他通道
]
for i, sensor in enumerate(sensors):
thermistor = adafruit_thermistor.Thermistor(
sensor,
series_resistor=10000,
nominal_resistance=10000,
b_coefficient=3950
)
print(f"Sensor {i}: {thermistor.temperature:.2f}°C")
5. 性能优化与误差处理
5.1 软件滤波算法
原始ADC读数存在噪声,可采用移动平均滤波:
python复制from collections import deque
readings = deque(maxlen=10) # 保留最近10次读数
def filtered_temperature():
readings.append(thermistor.temperature)
return sum(readings) / len(readings)
5.2 硬件校准方法
使用冰水混合物(0℃)和沸水(100℃)进行两点校准:
- 将传感器浸入冰水中,记录电阻值R_cold
- 将传感器浸入沸水中,记录电阻值R_hot
- 重新计算B参数:
python复制B = math.log(R_cold/R_hot) / (1/(273.15+0) - 1/(273.15+100))
5.3 常见问题排查
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 温度读数跳变 | 电源噪声 | 增加0.1μF去耦电容 |
| 读数始终为0 | 引脚接触不良 | 检查电路连接 |
| 负温度值 | 高低端配置错误 | 调整high_side参数 |
| 超范围值 | 电阻值不匹配 | 检查nominal_resistance设置 |
6. 高级应用:物联网温度监测站
结合WiFi模块将数据上传到MQTT服务器:
python复制import socketpool
import wifi
import adafruit_minimqtt.adafruit_minimqtt as MQTT
wifi.radio.connect("SSID", "PASSWORD")
pool = socketpool.SocketPool(wifi.radio)
mqtt = MQTT.MQTT(
broker="io.adafruit.com",
port=1883,
username="AIO_USER",
password="AIO_KEY",
socket_pool=pool
)
mqtt.connect()
while True:
mqtt.publish("temperature", str(thermistor.temperature))
time.sleep(300) # 每5分钟上报
在长期户外测试中,建议采取以下防护措施:
- 使用防水型热敏电阻(如环氧树脂封装)
- 开发板加装防潮箱
- 配置看门狗定时器防死机