本文将介绍2种电阻式传感器--光敏和热敏,这2个传感器之前在介绍AD转换芯片PCF8591的时候使用过,但是具体的原理没有介绍,它们是利用金属体的阻值变化来实现,电阻值因金属的种类而异。同样的材料,越细或越薄,阻值越大。当加有外力时,金属变细长,阻值增加,若变粗变短,则阻值减少。有些材料对关照和温度敏感,进而制作出了光敏和热敏电阻。
1、光敏电阻传感器
光敏电阻(Photosensitive resistor),也称为光敏电阻器、光敏电阻元件,是一种能够根据光线强度变化而改变电阻值的电子元件。光敏电阻的电阻值随着光线的强弱而变化,当光线强度较弱时电阻值较大,光线强度较强时电阻值较小。光敏电阻通常由半导体材料制成,其中常用的材料有硫化铟、硫化镉等。
光敏电阻的原理是基于半导体材料的光致电阻效应。当光线照射到光敏电阻上时,光子的能量被吸收并激发了半导体材料中的电子,使得半导体材料的电阻值发生变化。光敏电阻的电阻值和光线强度之间存在一种线性关系,越强的光线会导致电阻值越低。
光敏电阻广泛应用于光控开关、光电传感器、光敏电路等领域。在光控开关中,光敏电阻可以感知光线的强度,通过控制开关的通断来实现光线的自动控制。在光电传感器中,光敏电阻可以将光信号转换为电信号,用于测量光线的强度。在光敏电路中,光敏电阻可以作为光敏元件和其他电子元件组成不同的电路,用于光控或光测等应用。
总之,光敏电阻作为一种根据光线强度变化而改变电阻值的元件,具有灵敏度高、成本低、易于使用等优点,因此在各种光控和光测应用中得到了广泛的应用。
2、光敏传感器与树莓派连接
该模块的工作电压为 3.3~5V,共有4个引脚:VCC、GND 、DO和AO,也有的光敏电阻传感器只有3个引脚,就是前3个,没有AO引脚。我们先介绍前面3个引脚,其中 VCC 和 GND 分别接树莓派的3.3V输出和GND。DO引脚为数字开关信号输出引脚。当模块所处环境的光线亮度达不到设定阀值(阀值可通过旋转模块的蓝色电位器改变)时,DO引脚输出高电平:当外界环境的光线亮度超过设定的阀值时,DO引脚输出低电平。DO引脚可以与开发板的任一GPIO 引脚连接,这里使用的是GPIO26,物理引脚39。通过开发板检测高低电平,由此来检测环境的光线亮度变化。
由于DQ引脚输入的数字量,类似按键,要么低电平表示外界光亮度高,要么高电平表示外界光亮度低,但具体量化值是多少,需要通过AO模拟量输出到树莓派GPIO,但是树莓派开发板和STM32不同,没有办法进行接模拟电压信号的输入(STM32可以),因此需要借助PCF8591芯片将模拟电压量转数字量,通过IIC总线通信,输出到树莓派,树莓派接收。
整个AD转换,自然界的光照强度不同改变光敏电阻的阻值,从而改变PCF8591的IN1输入电压的大小,由PCF8591芯片将模拟输入的电压值转为数字量,8位量化精度,范围0-255,然后通过IIC总线发给微处理器。我们先介绍直连树莓派的GPIO口情况,最后再通过我们的老朋友PCF8591介绍AD转化的值的处理
3、实验代码与现象
外界环境黑暗时,LED灯亮,外界有光的时候,LED灯灭,这个类似街边的路灯,白天灯不亮,晚上灯自然就亮了。对光照的敏感阈值可通过旋转模块的蓝色电位器改变。超过阈值,说明光强,光敏传感器模块上面的LED灯亮,模拟路灯的LED不亮(GPIO17),反之同学们自己推。
import time
import RPi.GPIO as GPIO
Led_Port = 17
Photo_Port = 26
# 指定编号规则为BCM
GPIO.setmode(GPIO.BCM)
#Led灯使用GPIO17,设置为输出模式
GPIO.setup(Led_Port, GPIO.OUT)
# 将引脚设置为输入模式
GPIO.setup(Photo_Port, GPIO.IN)
def Photo_Sensor():
while True:
if GPIO.input(Photo_Port):
print('外界环境较暗,打开路灯!')
GPIO.output(Led_Port,GPIO.LOW)
else:
print("检测到的光线亮度正常,关闭路灯!")
GPIO.output(Led_Port,GPIO.HIGH)
time.sleep(1)
if __name__ == '__main__':
try:
Photo_Sensor()
except KeyboardInterrupt:
print("程序结束!")
finally:
GPIO.cleanup()
4、热敏电阻传感器
热敏电阻是一种电阻值随温度变化的电阻器,按照温度系数不同分为正温度系数热敏电阻器
(PTC)和负温度系数热敏电阻器(NTC)。PTC在温度越高时电阻值越大,而NTC在温度越高时电
阻值越低。
通常情况下,PTC用作保险丝,当电路中的电流增加,导致温度急剧升高,此时PTC电阻值增加
降低电路中的电流,以此保护电路。而NTC因其对各种温度变化响应快的特点,所以常用来制作温度测量的传感器。本节将 NTC为例,用其测量当前室温。
要通过电阻值的变化测量出温度的变化,就需要先理解热敏电阻的温度计算公式::
Rt=R∗EXP(B∗(1/T1−1/T2))
其中:
- Rt是热敏电阻在 T1温度下的阻值。
- R是热敏电阻在 T2常温下的标称阻值,通常为25℃。
- T1 和 T2指的是开尔文温度,即摄氏度加上273.15。
- B 值是热敏电阻的材料常数,也因电阻的型号而区分。
为了从测量的电阻值计算出对应的温度,可以使用以下公式计算 T1 的值:
T1=1/(ln(Rt/R)/B+1/T2) 计算出的T1是开尔文温度,为了得到摄氏温度,需要减去273.15。此外,为了更精确的结果,可能还需要考虑一定的误差矫正,例如加0.5的误差矫正。
5、热敏传感器与树莓派连接
由于温度是不断变化的,如果用DO连接GPIO引脚,只能定性的看到温度相比阈值温度是高还是低。树莓派与Arduino 不同,其没有任何模拟输入,要进行模拟输入必须使用额外的模数转换器(ADC)这里只有请出我们的老朋友PCF8591出场了。
我们重点介绍这个AD模块PCF8591的接线。
上图的AD模块集成了四路模拟输入,分别是IN0(热敏)、IN1(光敏)、IN2-3(可调电阻),标注1是已经有了光敏和热敏电阻,同学们可直接使用,见标注2,只要用跳线帽给短接相应的引脚即可,如果不短接这几个引脚,那么就请把目光转移到标注3。
接线VCC接树莓派VCC3.3,GND接树莓派GND,SCL、SDA接树莓派SCL、SDA,同学可参考我之前的文章,这里不赘述。IN0接热敏电阻传感器模块的AO引脚,IN1可接光敏电阻传感器模块的AO引脚,传感器模块的电源和接地可以从PCF8591 的VCC和GND接,也可以从面包板接,随便同学们了。
6、IIC Hub简介
由于树莓派开发板的IIC引脚数量有限,我们介绍一位新朋友,IIC Hub可以扩展8个IIC设备,Hub之间仍然可以再串联,就像以太网交换机一样。
IIC Hub是一个集成电路总线(Inter-Integrated Circuit)的集线器,它允许多个IIC设备通过一条总线进行通信。IIC总线是一种串行通信总线,广泛应用于嵌入式系统中,用于连接低速周边设备,如内存、LED及LCD驱动器、A/D及D/A转换器等。
IIC Hub的主要功能包括:
多主从架构:IIC总线支持多个主设备和从设备,其中主设备负责启动数据传输,而从设备则负责响应主设备的请求。
串行通信:数据在IIC总线上以串行方式传输,即每个时钟周期传输一位数据。
主从模式:在IIC总线上,主设备通过发送地址来选择从设备,从设备则通过应答信号来响应主设备。
仲裁机制:当多个主设备同时请求访问总线时,仲裁机制决定哪个主设备获得总线控制权。
数据传输速率:IIC总线的数据传输速率可高达每秒十万位,高速方式时在每秒四十万位以上。
设备地址:每个接到IIC总线的设备都有一个唯一的地址,以便于主设备寻访。
通过IIC Hub,可以实现多个IIC设备之间的数据共享和通信,简化了系统的硬件设计,减少了成本,并提高了系统的可靠性和稳定性。在实际应用中,IIC Hub常用于各种电子设备,如汽车电子、工业控制、医疗电子以及物联网设备等。
最前面白色的四条线接树莓派,后面8个扩展都可以用,我们随便找2组接OLED和PCF8591。这两个设备供电可以从树莓派或Hub上,我这边是从树莓派上取电,所以就没有接到IIC Hub上。
从上图可以看出IIC总线上挂载2个设备,0x3C是OLED的寄存器地址,0x48是PCF8591芯片的寄存器地址。
7、热敏电阻实验代码(含光敏及OLED)
import time
import math
import RPi.GPIO as GPIO
import smbus
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
import luma.oled as oled
from luma.core.interface.serial import i2c
from luma.oled.device import ssd1306
from luma.core.render import canvas
WIDTH=128
HEIGHT=64
# 指定编号规则为BOARD
GPIO.setmode(GPIO.BOARD)
# 设置地址
address = 0x48
# 创建一个smbus实例
bus=smbus.SMBus(1)
# 读取模拟量信息
def read(chn): #通道选择,范围是0-3之间
try:
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) # 开始进行读取转换
except Exception as e:
print ("Address: %s" % address)
print (e)
return bus.read_byte(address)
def load_device():
# 创建I2C接口对象
serial = i2c(port=1, address=0x3C) # 地址可能因显示屏型号而异,由命令行“sudo i2cdetect -y 1”得到
# 创建OLED设备对象
device = ssd1306(serial, WIDTH, HEIGHT)
return device
def loop_print():
"""遍历打印数据"""
while True:
# 读取数据
value = read(0)
# 计算电压
voltage = value / 255.0 * 3.3
# 计算电阻
Rt = 10 * voltage / (3.3 - voltage)
# 获取当前开尔文温度
temp_K = 1/(1/(273.15 + 25) + math.log(Rt/10)/3950.0)
# 转化为摄氏度
temp_C = round(temp_K - 273.15 + 0.5,2)
print('当前温度为:', temp_C)
time.sleep(1)
guangzhao = read(1)
print('当前光照值:',guangzhao)
time.sleep(1)
with canvas(device) as draw:
draw.rectangle(device.bounding_box, outline=0, fill=0)
draw.text((0,0), "当前温度为:",font=font, fill='white')
draw.text((0,15), str(temp_C), font=font, fill="white")
draw.text((0,30), "当前光照值:",font=font, fill='white')
draw.text((0,45), str(guangzhao), font=font, fill="white")
if __name__ == '__main__':
device = load_device()
font = ImageFont.truetype('STKAITI.TTF',16)
try:
loop_print()
except KeyboardInterrupt:
print("程序结束!")
finally:
GPIO.cleanup()
(1)温度与光照值要想都获取,需要先有写入寄存器的操作,然后再读出该寄存器的值。
(2) 计算出的温度值小数位太多,用round函数取2位小数即可
8、将温度光照值写入远程Mysql数据库
大量监控数据放到嵌入式设备里也未尝不可,主要看存储容量,如果配备的存储容量不够,还是把数据写入远程Mysql数据库最好。
(1)在win10主机安装Mysql数据库,这个就不用我再多说了,但是需要注意几个问题。一是root用户的默认密码可以通过执行命令mysqld --initialize --console来获取,一般都是最后一行。二是如果之前已经安装过Mysql,再次安装出现问题,可以删除原来的数据,重新安装。同学们可以参考博文https://blog.csdn.net/a8039974/article/details/121007756安装mysql数据库。最后一个问题是之前设置的Mysql数据库路径不对,导致数据库安装后无法启动,可以通过sc config MySQL binPath= "\"F:\mysql-5.7.37-winx64\bin\mysqld.exe\" --defaults-file=\"F:\mysql-5.7.37-winx64\my.ini\" MySQL" 这个命令重新设置启动目录后,再启动数据库。后面修改root密码和授权远程用户登录和linux系统一样。
(2)将树莓派数据库的表导入win10数据库。
(3)修改表结构,在设计表里面增加光照字段。这下就可以在代码里面将数据写入该表了。
(4)win10防火墙高级设置入站规则开放3306
如果你的系统中没有预设的 MySQL 规则,可以按如下步骤创建一个规则:
打开 Windows 10 的“控制面板”,选择“系统和安全”->“Windows Defender 防火墙”。
点击“高级设置”,在左侧面板中选择“入站规则”。
在右侧面板中,点击“新建规则”。
选择“端口”作为规则类型,点击“下一步”。
选择“TCP”作为端口协议,指定端口为 3306,点击“下一步”。
选择“允许连接”作为操作,点击“下一步”。
选择“仅在以下网络类型中启用此规则”并选中“专用”,点击“下一步”。
为规则命名并添加描述(可选),点击“完成”保存规则。
安装 MySQL 数据库服务后,防火墙规则需要允许 3306 端口的进入流量,这样才能正常访问 MySQL 数据库服务。
9、总结
本次实验内容较多,很多内容都放到一起去了,没有单独列出。可能看起来比较乱,但是同学们遇到问题还是要一点一点的解决,不能慌,后面我们继续学习传感器,有了网络和数据库,我们就可以把物联网和云计算联系起来了,再加上Python语言的优势,在人工智能,大数据上面相信同学们会对自己的职业方向有很明确的规划。