树莓派资料
显示屏资料
系统下载
树莓派Pico
首页 动态 发帖 版块 我的
 退出
游客  
等级:
金币:
经验值:

热敏电阻传感器 树莓派Python教程

  4493 
 0
 2
RASPI   RASPI 

一:传感器参数介绍

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


热敏电阻传感器原理图

工作电压

3.3-5V DC

触发方式

检测高温后输出低电信号

尺寸

32mmx14mm

信号输出

AO模拟量信号,DO开关数字量

指示灯状态

带开关指示灯(常温灯灭,高温灯亮)

     该模块基于热敏电阻的原理,其电阻随环境温度变化很大,当环境温度升高时热敏电阻的电阻降低,当环境温度降低时它的电阻增加。它可以实时检测周围的温度变化。

二:硬件连接

树莓派主板热敏电阻传感器
5VVCC
GNDGND
DOGPIO1(BCM18)

Image

三:DO数字开关量

1.Python程序:

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()
 

以上代码简单检查传感器的效果显示:正常,当探头接触到高温时显示: 高温, 如果我们要控制

Image

Image


如果我们用传感器来控制外设可以添加继电器模块, 在以上代码的基础上在编写个控制程序去打开继电器控制风扇。比如我们接入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模拟量信号

热敏电阻传感器,其内部电阻会随环境温度变化很大,当环境温度升高时热敏电阻的电阻降低,当环境温度降低时它的电阻增加。它可以实时检测周围的温度变化,在使用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模块进行使用。

标签:
作者签名: raspi.cc   楼主  2025-04-23 23:06:16
回复列表
Powered by RASPI _VERSION
© 2017-2025 树莓派极客版权
您的IP: 18.220.121.27 , 2025-04-26 18:31:52
Powered by RASPI _VERSION
© 2017-2025 树莓派极客版权