I have summarized only the necessary parts. The trial and error edition is here.
2017-04-09 It was uploaded to github. https://github.com/boyaki-machine/TSL2561
Solder the pin header to the sensor that arrived. Then wire.
Sensor 1pin (GND)-> Raspi 6th pin Sensor 2pin (SDA)-> Raspi pin 3 Sensor 3pin (SCL)-> Raspi 5th pin Sensor 4pin (VDD)-> Raspi pin 1
It is like this.
Set in the OS config menu.
$ sudo raspi-config
Select the menu in the order of "9 Advenced Options"-> "A7 I2C". You will be asked "Would you like the ARM I2C interface to be enabled?", So select yes. You will be asked "Would you like the I2C kernel module to be loaded by default?", So select yes.
Next, edit /boot/config.txt.
$ sudo vi /boot/config.txt
...Added the following contents
dtparam=i2c_arm=on
In addition, edit / etc / modules.
$ sudo vi /etc/modules
...Added the following contents
snd-bcm2835
i2c-dev
After completing the settings, restart Raspy. Make sure the kernel module is loaded after rebooting.
$ lsmod
...
i2c_dev 6709 0
snd_bcm2835 21342 0
...
$ sudo apt-get install i2c-tools python-smbus
Check the address of the sensor.
$ sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- 39 -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
Recognized at address 0x39.
Use the following class.
#!/usr/bin/python -u
# -*- coding: utf-8 -*-
import smbus
import time
#From "TSL2561 Illuminance Sensor Module" by Strawberry Linux
#Class to get data in I2C
# https://strawberry-linux.com/catalog/items?code=12561
# 2016-05-03 Boyaki Machine
class SL_TSL2561:
def __init__(self, address, channel):
self.address = address
self.channel = channel
self.bus = smbus.SMBus(self.channel)
self.gain = 0x00 # 0x00=normal, 0x10=×16
self.integrationTime = 0x02 # 0x02=402ms, 0x01=101ms, 0x00=13.7ms
self.scale = 1.0
#Initialization of sensor settings
self.setLowGain()
self.setIntegrationTime('default')
def powerOn(self):
self.bus.write_i2c_block_data(self.address, 0x80, [0x03])
time.sleep(0.5)
def powerOff(self):
self.bus.write_i2c_block_data(self.address, 0x80, [0x00])
#Set to High Gain(16 times more sensitive?)
def setHighGain(self):
#When set to High Gain, raw data may not be obtained properly.
#Investigation of the cause required(5047 Fixed value)
self.gain = 0x10
data = self.integrationTime | self.gain
self.bus.write_i2c_block_data(self.address, 0x81, [data])
self.calcScale()
# Low Gain(default)Set to
def setLowGain(self):
self.gain = 0x00
data = self.integrationTime | self.gain
self.bus.write_i2c_block_data(self.address, 0x81, [data])
self.calcScale()
#Setting the time to integrate (time for one sensing?)
# val = shor, middle, logn(default)
def setIntegrationTime(self, val):
if val=='short':
self.integrationTime = 0x00 # 13.7ms scale=0.034
elif val=='middle':
self.integrationTime = 0x01 # 101ms scale=0.252
else:
self.integrationTime = 0x02 # defaultVal 402ms scale=1.0
data = self.integrationTime | self.gain
self.bus.write_i2c_block_data(self.address, 0x81, [data])
self.calcScale()
def getVisibleLightRawData(self):
data = self.bus.read_i2c_block_data(self.address, 0xAC ,2)
raw = data[1] << 8 | data[0] #16bit with lower byte first
return raw
def getInfraredRawData(self):
data = self.bus.read_i2c_block_data(self.address, 0xAE ,2)
raw = data[1] << 8 | data[0] #16bit with lower byte first
return raw
def getRawData(self):
data = self.bus.read_i2c_block_data(self.address, 0xAC ,4)
VL = data[1] << 8 | data[0] #Visible light 16 bits, lower byte first
IR = data[3] << 8 | data[2] #Infrared 16bit, lower byte first
return (VL,IR)
def calcScale(self):
_scale = 1.0
#Scale by integrationTime
if self.integrationTime == 0x01: # middle
_scale = _scale / 0.252
elif self.integrationTime == 0x00: # short
_scale = _scale / 0.034
#Scale by gain
if self.gain == 0x00 : # gain 1
_scale = _scale * 16.0
self.scale = _scale
def getLux(self):
#Acquisition of raw sensor data
raw = self.getRawData()
#Implementation to output an error when 65535
if raw[0] == 65535 or raw[1] == 65535:
return "Range Over"
#Scale raw data with sensor settings
VLRD = raw[0] * self.scale
IRRD = raw[1] * self.scale
#Don't divide by zero
if (float(VLRD) == 0):
ratio = 9999
else:
ratio = (IRRD / float(VLRD))
#Lux calculation
if ((ratio >= 0) & (ratio <= 0.52)):
lux = (0.0315 * VLRD) - (0.0593 * VLRD * (ratio**1.4))
elif (ratio <= 0.65):
lux = (0.0229 * VLRD) - (0.0291 * IRRD)
elif (ratio <= 0.80):
lux = (0.0157 * VLRD) - (0.018 * IRRD)
elif (ratio <= 1.3):
lux = (0.00338 * VLRD) - (0.0026 * IRRD)
elif (ratio > 1.3):
lux = 0
return lux
if __name__ == "__main__":
sensor = SL_TSL2561(0x39,1)
sensor.powerOn()
# sensor.setHighGain()
sensor.setIntegrationTime('default')
while True:
print "Lux : " + str(sensor.getLux())
time.sleep(1.0)
--When set to High Gain, there is a problem that it is fixed to an abnormal value if there is a certain amount of illuminance (around the window during May day).
Recommended Posts