The graph was just the lux as calculated from the automatic cayenne system, and then some mqtt code to store the Vis+Infra and the Infra values in the cayenne history. Here is my code for testing the device - I could not find any good code for doing the lux calculations in different modes that I could get working. It all seemed to be written using integer math, but this uses floating point math. The calcs here match the Lux meter on my cellphone quite nicely, but the automatic cayenne calc is always much lower. Perhaps I am screwing up the automatic cayenne calculation by sampling to store the raw data ??
Please let me know if I read the datasheet wrong, and these lux calcs are wrong!
# python 2.7
# code scavanged and modified
import smbus
import time
import datetime
TSLaddr = 0x39 #Default I2C address, alternate 0x29, 0x49
TSLcmd = 0x80 #Command
chan0 = 0x0C #Read Channel0 sensor date
chan1 = 0x0E #Read channel1 sensor data
TSLon = 0x03 #Switch sensors on
TSLoff = 0x00 #Switch sensors off
#Exposure settings
NormShort = 0x00 # x1 Gain 13.7 miliseconds
NormMed = 0x01 # x1 Gain 101 miliseconds
NormLong = 0x02 # x1 Gain 402 miliseconds
NormManual = 0x03 # x1 Gain Manual
DarkShort = 0x10 # x16 Gain 13.7 miliseconds
DarkMed = 0x11 # x16 Gain 100 miliseconds
DarkLong = 0x12 # x16 Gain 402 miliseconds
DarkManual = 0x13 # x16 Gain Manual
#Manual Settings
ManDelay = 2 #Manual Exposure in Seconds
StartMan = 0x1F #Start Manual Exposure
EndMan = 0x1E #End Manual Exposure
try:
#Enter in [] the Exposure Setting to use
sequence = [NormLong,NormMed,NormShort,DarkLong,DarkMed,DarkShort]
except:
print("Unknown Exposure Setting used, defaulting to NormLong (x1 402ms")
sequence = [NormLong]*vRepeat
# Get I2C bus
bus = smbus.SMBus(1)
writebyte = bus.write_byte_data
writebyte(TSLaddr, 0x00 | TSLcmd, TSLon) #Power On
def manual(delay,mode):
"""manual exposure"""
bus.write_byte_data(TSLaddr, 0x01 | TSLcmd, mode) #sensativity mode
bus.write_byte_data(TSLaddr, 0x01 | TSLcmd, StartMan) #start detection
time.sleep(delay) #exposure
bus.write_byte_data(TSLaddr, 0x01 | TSLcmd, EndMan) #stop detection
return
print "Part Number", bus.read_byte_data(TSLaddr, 0x8A)
for mode in sequence:
if mode != 3 and mode != 19: #Selected built in delay for exposure. If Manual mode not set
writebyte(TSLaddr, 0x01 | TSLcmd, mode)
time.sleep(1)
else: #use manual exposure
manual(ManDelay,mode)
#Read ch0 Word then ch1
data = bus.read_i2c_block_data(TSLaddr, chan0 | TSLcmd, 2)
data1 = bus.read_i2c_block_data(TSLaddr, chan1 | TSLcmd, 2)
# Convert the data to Integer
ch0 = data[1] * 256 + data[0]
ch1 = data1[1] * 256 + data1[0]
if ch0 > 0:
VIratio = 1.0 * ch1/ch0
else:
VIratio = 2 # no light
#print ("VIratio = ", VIratio)
if VIratio <= 0.52:
lux = 0.0315 * ch0 - 0.0593 * ch0 * ((VIratio)**1.4)
elif VIratio > 0.52 and VIratio <= 0.65:
lux = 0.0229 *ch0 - 0.0291 * ch1
elif VIratio > 0.65 and VIratio <= 0.8:
lux = 0.00157 * ch0 - 0.00180 * ch1
elif VIratio > 0.8 and VIratio <= 1.3:
lux = 0.00338 * ch0 - 0.00260 * ch1
elif VIratio > 1.3:
lux = 0
status = "Normal"
if ch0 > 0:
if mode == NormLong:
slux = lux * 16;
if ch1 >= 65535 or ch0 >= 65535:
status = "Exceed NormLong clipping"
elif mode == NormMed:
slux = lux * 65.136 # 4071 / 1000 * 16
if ch1 >= 37177 or ch0 >= 37177:
status = "Exceed NormMed clipping"
elif mode == NormShort:
slux = lux * 479.6 # 29975 / 1000 * 16
if ch1 >= 5047 or ch0 >= 5047:
status = "Exceed NormShort clipping"
elif mode == DarkLong:
slux = lux
if ch1 >= 65535 or ch0 >= 65535:
status = "Exceed DarkLong clipping"
elif mode == DarkMed:
slux = lux * 4.071 # 4071 / 1000
if ch1 >= 37177 or ch0 >= 37177:
status = "Exceed DarkMed clipping"
elif mode == DarkShort:
slux = lux * 29.975 # 29975 / 1000
if ch1 >= 5047 or ch0 >= 5047:
status = "Exceed DarkShort clipping"
else:
print "Out of modes - manual not implemented"
print datetime.datetime.now(), "Mode: ", mode," Ratio: ", round(VIratio,2)," V+IR",ch0, " IR",ch1, "Lux", round(lux), "Scaled Lux", round(slux), " ", status
else:
#either no light or clipping value exceeded due to too much light
print datetime.datetime.now(), "Mode: ", mode," V+IR",ch0, " IR",ch1, "No Light"
#Power Off
#writebyte(TSLaddr, 0x00 | TSLcmd, TSLoff)