TSL2561可将光强度转换为能够直接通过I2C总线输出的数字信号。
两个积分ADC将光电二极管电流转换为数字输出,表示在每个通道上测量的辐照度。
引脚 | 描述 |
---|---|
GND | 接地 |
INT | 中断控制 |
SCL | I2C时钟线 |
SDA | I2C地址线 |
VDD | 电源供电(3.3V) |
I2C总线传输协议
我们直接调用wiringPi中包含的I2C库来编写程序
i2cdetect -y 1
该函数的原型为:int wiringPiI2CSetup(int devId);
该函数使用指定设备标示号来初始化 I2C 系统。参数 devId 是 I2C 设备的地址,此处设备为TSL2561。fd为文件描述符。
fd = wipi.wiringPiI2CSetup(TSL2561I2C_ADDR)
该函数的原型为:int wiringPiI2CWrite(int fd, int data); 简单的设备写操作。此处先写入寄存器的地址,再写入寄存器的值。
wipi.wiringPiI2CWrite(fd,CONTROL_REG)
wipi.wiringPiI2CWrite(fd,POWER_UP)
该函数的原型为:int wiringPiI2CRead(int fd);
简单的设备读操作。此处用于读寄存器的值,返回值就是该寄存器的当前值。在wiringPiI2CWrite之后使用。
wipi.wiringPiI2CWrite(fd,DATA0LOW)
data0low = wipi.wiringPiI2CRead(fd)
表中给出了TSL2561中所有寄存器的名称、地址和功能。
此处我们用到命令寄存器(COMMAND)、控制寄存器(CONTROL)和数字寄存器(Ch Dh Eh Fh)
命令寄存器中共有8位,最高位必须置1。第4-7位写0,低四位为寄存器的地址。
DATA0LOW = 0x8c
DATA0HIGH = 0x8d
DATA1LOW = 0x8e
DATA1HIGH = 0x8f
当不访问数据存储器时,低四位置0。
传统的硅探测器对人眼看不到的红外光强烈反应。 由于硅探测器响应与人类感知的亮度之间的差异,当环境光的红外含量很高时(例如白炽灯照明),这会导致严重错误。通过使用两个光电二极管在TSL256x中克服了这个问题。 其中一个光电二极管(CH0)对可见光和红外光都敏感,而第二个光电二极管(CH1)主要对红外光敏感。 积分ADC将光电二极管电流转换为数字输出。 CH1数字输出用于补偿光的红外分量对通道0数字输出的影响。 来自两个通道的ADC数字输出用于公式中,以获得近似于Lux常用照度单位中人眼响应的值:
两个通道CH0,CH1同时对光强数据进行采集,数据处理时将两个通道CH0,CH1数据进行位运算:
CH0 = 256*data0high + data0low
CH1 = 256*data1high + data1low
if (ratio <= 0):
Lux = 0
elif ratio <= 0.50:
Lux = 0.0304*float(CH0)-0.062*float(CH0)*(ratio**1.4)
elif (ratio > 0.5 & ratio <= 0.61):
Lux = 0.0224*float(CH0)-0.031*CH1
elif (ratio > 0.61 & ratio <= 0.80):
Lux = 0.0128*float(CH0)-0.0153*CH1
elif (ratio > 0.80 & ratio <= 1.30):
Lux = 0.00146*float(CH0)-0.00112*CH1
elif ratio > 1.30:
Lux = 0
#!/usr/bin/python
"""
Filename:tsl2561.py
Description: This file is used to collect lux.
"""
import wiringpi as wipi
import time
TSL2561I2C_ADDR = 0x39
POWER_UP = 0x03
POWER_DOWN = 0x00
CONTROL_REG = 0x80
DATA0LOW = 0x8c
DATA0HIGH = 0x8d
DATA1LOW = 0x8e
DATA1HIGH = 0x8f
#initial I2C device
fd = wipi.wiringPiI2CSetup(TSL2561I2C_ADDR)
#collect data
wipi.wiringPiI2CWrite(fd,CONTROL_REG)
wipi.wiringPiI2CWrite(fd,POWER_UP)
time.sleep(0.5) //
#read data
wipi.wiringPiI2CWrite(fd,DATA0LOW)
data0low = wipi.wiringPiI2CRead(fd)
wipi.wiringPiI2CWrite(fd,DATA0HIGH)
data0high = wipi.wiringPiI2CRead(fd)
wipi.wiringPiI2CWrite(fd,DATA1LOW)
data1low = wipi.wiringPiI2CRead(fd)
wipi.wiringPiI2CWrite(fd,DATA1HIGH)
data1high = wipi.wiringPiI2CRead(fd)
#data processing
CH0 = 256*data0high + data0low
CH1 = 256*data1high + data1low
ratio = float(CH1)/float(CH0)
#calculate lux
if (ratio <= 0):
Lux = 0
elif ratio <= 0.50:
Lux = 0.0304*float(CH0)-0.062*float(CH0)*(ratio**1.4)
elif (ratio > 0.5 & ratio <= 0.61):
Lux = 0.0224*float(CH0)-0.031*CH1
elif (ratio > 0.61 & ratio <= 0.80):
Lux = 0.0128*float(CH0)-0.0153*CH1
elif (ratio > 0.80 & ratio <= 1.30):
Lux = 0.00146*float(CH0)-0.00112*CH1
elif ratio > 1.30:
Lux = 0
#show lux
print '%.3f' % Lux