光是大自然时刻都存在的一种能量,其本质是一种处于特定频段的光子流,我还依稀记得光具有波粒二象性。根据光波长的不同可分为可见光和不可见光两大类,其中人眼能看见的是可见光,反之则为不可见光。在不可见光中最常见的就是红外光和紫外光,因而光传感器通常就是指能敏锐感应紫外光到红外光的光能量,并将光能量转换成电信号的器件。我们下面会介绍使用树莓派驱动常见的光传感器,并读取参数,或使用光特性制成的传感器来实现一些检测目的。
1、光照传感器
光照传感器可以将光照强度值转为电压值,通过电压的变化来检测光照强度。
光照传感器广泛应用于室内和室外照明控制、自动车灯控制、智能家居系统、太阳能系统、安防系统等领域。它可以根据环境光的变化调整光源的亮度,提供舒适的照明环境,同时也可以节省能源和延长光源的使用寿命。
随着智能化技术的发展,光照传感器也逐渐与其他传感器结合使用,实现更智能、自动化的控制系统。例如,与温度传感器结合使用,可以实现自动调节室内照明和温度的功能,提供更舒适的居住环境。
2、BH1750
BH1750传感器模块是一种数字光强传感器,用于测量光照强度。它基于BH1750芯片,具有高精度和快速响应的特点。
BH1750传感器模块采用数字输出接口,可以通过I2C总线与微控制器或单片机进行通信。它能够测量0到65535勒克斯(Lux)范围内的光照强度,最小误差变动为±20%,并将结果以数字形式输出。传感器模块内部集成了光敏元件的放大电路和ADC转换电路,能够快速、准确地将光照强度转换为数字信号输出。BH1750传感器模块广泛应用于室内和室外光照强度监测、自动光照调节、照明系统控制等领域。它可以帮助实现能源节约和环境保护的目标。
BH1750光照强度传感器的内部由光敏二极管、运算放大器、ADC采集、晶振等组成。PD二极管通过光生伏特效应将输入的光信号转换成电信号,经运算放大器放大后,再由ADC采集电压,通过逻辑电路转换成16位二进制数存储在内部的寄存器中,当光照强度增加时,电压增大,反之越小。
之前我们还学习过光敏电阻传感器,它只有8位精度,将光照值转成0-255之间的数。BH1750得出的数据是可计算的真实数据(电压和光强虽然是一一对应的,但不是成正比的,所以这个芯片内部是做了线性处理的,这也是为什么不直接用光敏二极管而用集成IC的原因),但是光敏电阻只是根据材料感应光照而改变阻值,只能呈现线性关系,但并不是真实的对应关系。
从上图可以看出这个BH1750是6引脚IC,引出了时钟线和数据线,单片机通过I2C协议可以与BH1750模块通讯,可以选择BH1750的工作方式,也可以将BH1750寄存器的光照度数据提取出来。
从寄存器提取出来的数据是2个字节的数据,先接收的是高8位[15:8],后接收的是低8位[7:0],所以我们需要先把这2个字节合成一个数,然后乘上分辨率,再除以1.2即可得到光照值。
计算公式是:光照强度 =(寄存器值[15:0] * 分辨率) / 1.2 (单位:勒克斯lux)
3、勒克斯(照度单位)
勒克斯(lux)是照度的单位,用于衡量光照的强度或亮度。勒克斯的定义是:被光均匀照射的物体,在1平方米面积上得到的光通量是1流明时,其照度为1勒克斯。这个单位用于测量单位面积上的光照强度,是衡量光照条件的一个重要指标。
勒克斯与流明的关系可以这样理解:流明(lumen)是描述光通量的物理单位,而勒克斯则是用来衡量这些光通量在单位面积上的分布情况。具体来说,1勒克斯等于1流明每平方米。这意味着,如果一个光源在1平方米的面积上产生了1流明的光照强度,那么这个光源的照度就是1勒克斯。
在实际应用中,了解勒克斯的概念对于评估和改善照明条件非常重要。例如,阅读时需要的照度通常在50-60勒克斯之间,而电视台演播室的照度要求则高达1000勒克斯。此外,不同环境下的照度标准也有所不同,如夜间路灯的照度大约为0.1勒克斯,而室内日光灯的照度可以达到100勒克斯。
需要注意的是,照度不仅与光源的光通量有关,还与光源的距离、反射装置的使用等因素有关。
4、BH1750与树莓派连接
VCC3.3V,SDA、SCL接树莓派BOARD第3和第5引脚,GND接地。和其他IIC设备的区别就是这个ADDR引脚不能悬空,否则找不到地址。接GND地址为0x23,接VCC地址为0x5C。这个值要注意,代码需要使用。
5、实验代码与实验现象
代码比较简单,计算出光照强度勒克斯,在OLED显示屏上面显示。
import time
import smbus
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
import RPi.GPIO as GPIO
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
# 默认的I2C地址
DEVICE = 0x23
ONE_TIME_HIGH_RES_MODE_1 = 0x20
# 创建一个smbus实例
bus = smbus.SMBus(1)
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:
# 从I2C接口读取数据
data = bus.read_i2c_block_data(DEVICE, ONE_TIME_HIGH_RES_MODE_1)
# 将2个字节的数据转换为十进制数的简单函数
light_level = (data[1] + (256 * data[0])) / 1.2
print("光照强度为 : " + format(light_level,'.2f') + " lx")
with canvas(device) as draw:
draw.rectangle(device.bounding_box, outline=0, fill=0)
draw.text((0,0), "光照强度为:",font=font, fill='white')
draw.text((10,20), str(round(light_level,2)), font=font, fill="white")
draw.text((50,20), "勒克斯", font=font, fill="white")
time.sleep(0.5)
if __name__ == '__main__':
global device
device = load_device()
font = ImageFont.truetype('STKAITI.TTF',17)
try:
loop_print()
except KeyboardInterrupt:
print("程序结束!")
经过实验,可知室内调光等,黄灯的光照强度约为60勒克斯,白灯的光照强度约为70勒克斯,关上灯后,只有电脑屏幕发光,光照强度为1.67勒克斯,用手机拍摄挡住了室内光源,只有15.83勒克斯。阅读时需要的光强在50-60之间,于是我立马把灯光调成黄光。