热敏电阻模块对环境较高温度很敏感,一般用来检测周围环境的较高温,通过对电位器的调节,可以改变高温度的检测阀值(即控制高温值),比如需要控温度为60度时,则模块在相应环境温度调到绿灯熄灭,DO此时输出高电平,如果高于此温度时,输出低电平绿灯亮。DO输出端可以与树莓派和单片机直接相连,通过单片机来检测高低电平,由此来检测环境的高温阈值,DO输出端还可以驱动5V继电器模块,由此可以组成一个温控开关,控制相关设备的工作温度,用于水温,水箱等的控制,也可以接风扇用来实现自动散热等,热敏电阻传感器温度检测范围为50-100摄氏度左右。
该模块基于热敏电阻的原理,其电阻随环境温度变化很大,当环境温度升高时热敏电阻的电阻降低,当环境温度降低时它的电阻增加。它可以实时检测周围的温度变化。
| 树莓派主板 | 热敏电阻传感器 |
| 5V | VCC |
| GND | GND |
| DO | GPIO1(BCM18) |

import RPi.GPIO as GPIO
import time
# 配置GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO_PIN = 18
# 初始化引脚为输入模式,启用下拉电阻
GPIO.setup(GPIO_PIN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
try:
print("实时监测高温...")
last_status = None # 记录上次状态
while True:
# 读取当前引脚状态
current_status = GPIO.input(GPIO_PIN)
# 只在状态变化时更新显示
if current_status != last_status:
if current_status == GPIO.HIGH:
print("\r当前状态:正常", end="", flush=True)
else:
print("\r当前状态:高温", end="", flush=True)
last_status = current_status
time.sleep(0.1) # 降低CPU占用率
except KeyboardInterrupt:
print("\n监测已终止")
finally:
GPIO.cleanup() 以上代码简单检查传感器的效果显示:正常,当探头接触到高温时显示: 高温, 如果我们要控制


如果我们用传感器来控制外设可以添加继电器模块, 在以上代码的基础上在编写个控制程序去打开继电器控制风扇。比如我们接入5V继电器+风扇后。将继电器IN引脚接入在树莓派GPIO4上,继电器在控制风扇,程序就可以这样写
import RPi.GPIO as GPIO
import time
# 设置GPIO模式
GPIO.setmode(GPIO.BCM)
# 定义GPIO引脚
GPIO_INPUT_PIN = 18 # 监测引脚
GPIO_OUTPUT_PIN = 4 # 控制风扇的引脚
# 设置GPIO引脚的输入和输出模式
GPIO.setup(GPIO_INPUT_PIN, GPIO.IN)
GPIO.setup(GPIO_OUTPUT_PIN, GPIO.OUT)
try:
while True:
# 读取GPIO18的状态
input_state = GPIO.input(GPIO_INPUT_PIN)
if input_state == GPIO.LOW:
# 有低电平输入
GPIO.output(GPIO_OUTPUT_PIN, GPIO.HIGH) # 启动风扇
print("高温,风扇启动")
else:
# 无低电平输入
GPIO.output(GPIO_OUTPUT_PIN, GPIO.LOW) # 停止风扇
print("正常,风扇停止")
time.sleep(1) # 每秒检查一次
except KeyboardInterrupt:
# 捕获Ctrl+C退出程序
pass
finally:
# 清理GPIO设置
GPIO.cleanup()如果需要使用AO模拟量信号,我们可使用模数转换器PCF8591将模拟信号转换为数字信号。但是在编程中,我们要通过数字信号值计算出热敏电阻的实时阻值,再来计算对应的温度值。
热敏电阻传感器,其内部电阻会随环境温度变化很大,当环境温度升高时热敏电阻的电阻降低,当环境温度降低时它的电阻增加。它可以实时检测周围的温度变化,在使用AO模拟量信号时我们需要使用到模数转换器PCF8591将模拟信号转换为数字信号。在编程中我们要通过数字信号值计算出热敏电阻的实时阻值,再来计算对应的温度值。 关于PCF8591数模转换模块的使用资料可参考:PCF8591模数AD模拟量教程
计算热敏电阻实时阻值:
1.通过函数 ADC.read(0) 取得传感器模拟输出A/D转化后的数字值:
analogVal = ADC.read(0)
2.利用上面的值计算热敏电阻的原始模拟电压值Vr :
Vr= 5 * float(analogVal) / 255
3.串联电路电流值相同,所以电流值相等:
热敏电阻电压 / 热敏电阻值=(5V-热敏电阻电压) / 另外一个分压电阻阻值
从上面的电路图可知,另外一个分压电阻阻值为10K,即10000,所以热敏电阻值:
Rt = 10000 * Vr / (5 - Vr)
热敏电阻公式:
NTC 热敏电阻温度计算公式,Steinhart-Hart公式,即温度-阻值关系等式,他是一个经验公式,是用来描述NTC 热敏电阻的阻值与温度关系的最好的数学表达式:
Rt = R*EXP(B*(1/T1-1/T2))
其中,T1和T2指的是K度,即开尔文温度。
Rt 是热敏电阻在T1温度下的阻值。
R是热敏电阻在T2常温下的标称阻值。10K的热敏电阻25℃的值为10K(即R=10000)。T2=(273.15+25)
EXP是e的n次方
B值是热敏电阻的重要参数,B=3950
通过转换可以得到温度T1与电阻Rt的关系T1=1/(ln(Rt/R)/B+1/T2)
对应的摄氏温度t=T1-273.15,同时+0.5的误差矫正。
在编程时需要先写个PCF8591.py库文件,后面再编写一个python程序引入这个库文件。PCF8591.py库文件就是PCF8591模块的程序,单独编写是为了便于重用。在下面的脚本中,我们使用了一个放大器用于模拟输入和一个LED灯用于模拟输出,模拟输入不能超过3.3V!该程序也可以单独运行,用于测试3个电阻模块的功能。需用短路帽连接AIN0和INPUT0(电位计模块),连接AIN1和INPUT1(光敏电阻模块),以及连接AIN2和INPUT2(热敏电阻模块)。连接LED灯,AIN0(模拟输入0)端口用于接收来自电位计模块的模拟信号,AOUT(模拟输出)用于将模拟信号输出到双色LED模块,以便改变LED的亮度。
AO模拟量参考代码
#!/usr/bin/env python
#www.raspi.cc
#
# 您可以使用下面语句将此脚本导入另一个脚本:
# “import PCF8591 as ADC”
#
# ADC.Setup(Address) # 查询PCF8591的地址:“sudo i2cdetect -y 1”
# i2cdetect is a userspace program to scan an I2C bus for devices.
# It outputs a table with the list of detected devices on the specified bus.
# ADC.read(channal) # Channal范围从0到3
# ADC.write(Value) # Value范围从0到255
#
#------------------------------------------------------
#SMBus (System Management Bus,系统管理总线)
import smbus #在程序中导入“smbus”模块
import time
# for RPI version 1, use "bus = smbus.SMBus(1)"
# 0 代表 /dev/i2c-0, 1 代表 /dev/i2c-1 ,具体看使用的树莓派那个I2C来决定
bus = smbus.SMBus(1) #创建一个smbus实例
#在树莓派上查询PCF8591的地址:“sudo i2cdetect -y 1”
def setup(Addr):
global address
address = Addr
def read(chn): #channel
if chn == 0:
bus.write_byte(address,0x40) #发送一个控制字节到设备
if chn == 1:
bus.write_byte(address,0x41)
if chn == 2:
bus.write_byte(address,0x42)
if chn == 3:
bus.write_byte(address,0x43)
bus.read_byte(address) # 从设备读取单个字节,而不指定设备寄存器。
return bus.read_byte(address) #返回某通道输入的模拟值A/D转换后的数字值
def write(val):
temp = val # 将字符串值移动到temp
temp = int(temp) # 将字符串改为整数类型
# print temp to see on terminal else comment out
bus.write_byte_data(address, 0x40, temp)
#写入字节数据,将数字值转化成模拟值从AOUT输出
if __name__ == "__main__":
setup(0x48)
#在树莓派终端上使用命令“sudo i2cdetect -y 1”,查询出PCF8591的地址为0x48
while True:
print '电位计 AIN0 = ', read(0) #电位计模拟信号转化的数字值
print '光敏电阻 AIN1 = ', read(1) #光敏电阻模拟信号转化的数字
print '热敏电阻 AIN2 = ', read(2) #热敏电阻模拟信号转化的数字值
tmp = read(0)
tmp = tmp*(255-125)/255+125
# 125以下LED不会亮,所以将“0-255”转换为“125-255”,调节亮度时灯不会熄灭
write(tmp)
time.sleep(2)
然后编写控制程序。屏幕不断打印输出实时温度的值。若温度大于33°,打印“Too Hot!”;如果温度小于31°,打印“Better~” 。31和33要根据实验时,实测温度范围调整。
#!/usr/bin/env python import PCF8591 as ADC import RPi.GPIO as GPIO import time import math DO = 17 GPIO.setmode(GPIO.BCM) def setup(): ADC.setup(0x48) GPIO.setup(DO, GPIO.IN) def Print(x): if x == 1: print '' print '***********' print '* Better~ *' print '***********' print '' if x == 0: print '' print '************' print '* Too Hot! *' print '************' print '' def loop(): status = 1 tmp = 1 while True: analogVal = ADC.read(0) #温度传感器模拟输出A/D转化后的数字值 Vr = 5 * float(analogVal) / 255 #Vr为数字值转化为热敏电阻的原始模拟电压值 Rt = 10000 * Vr / (5 - Vr) #Rt是热敏电阻在T1温度下的阻值,10000=10k为与热敏电阻串联的电阻的阻值 #查阅传感器电路图知,因为是串联,所以电流值相等 Vr/Rt=(5-Vr)/10000 temp = 1/(((math.log(Rt / 10000)) / 3950) + (1 / (273.15+25))) # T1=1/(ln(Rt/R)/B+1/T2) 对应的摄氏温度t=T1-273.15 # R=10k=10000 B=3950 T2=(273.15+25) temp = temp - 273.15 print 'temperature = ', temp, 'C' if temp > 33: tmp = 0; elif temp < 31: tmp = 1; if tmp != status: Print(tmp) status = tmp time.sleep(0.2) if __name__ == '__main__': try: setup() loop() except KeyboardInterrupt: pass
关于AO模拟量使用请结合pcf8591AD模块进行使用。