Hi, 
I have tried to get data from both the Temp/Humidity and the Ambient Light sensor by using python and python-smbus. I have found and read the tech docs of both adapters as specified by Pine64 but have not gotten all the way to reading the correct data, i.e. I get data from the T/H sensor but it says that it's -5 C inside and I don't believe that since I'm sitting in short-sleeves...    
I also found the posts from khgoh ( http://forum.pine64.org/showthread.php?tid=231&page=3) and skimmed through the source code for the WifiRemoteI2C server but that is in C (C++) and does not help me at all, or rather, it does not help me solving it in python...
 
My problem is that the value I get from the T/H sensor does not convert correctly into the ambient temperature and relative humidity. 
 
I would really appreciate if someone told me where I am going wrong and how to correct it.
 
Many thanks
 
DS
 
Source:
 Code: import smbus 
import time 
 
bus = smbus.SMBus(1) 
address = 0x40 
cmd_temp = 0xE3 
cmd_humid = 0xE5 
temp = 0L 
humid = 0L 
 
temp = bus.read_word_data(address, cmd_humid) 
print "RH read_word_data returns ", humid 
print "" 
humid = 125.0 * humid / 65536 - 6 
print "RH: ", humid, " %" 
print "" 
print "" 
 
temp = bus.read_word_data(address, cmd_temp) 
print "Temp read_word_data returns ", temp 
print "" 
temp = 175.72 * temp / 65536 - 46.85 
print "Temperature: ", temp, " C" 
print "" 
print ""
  
Output:
 Code: debian@pine64:~/i2c$ python getTemp2.py  
RH read_word_data returns  0 
 
RH:  -6.0  % 
 
 
Temp read_word_data returns  10341 
 
Temperature:  -19.1229412842  C 
 
 
debian@pine64:~/i2c$
  
	 
	
	
	
	
 
 
	
		
		
		09-29-2016, 12:04 AM 
(This post was last modified: 09-29-2016, 12:05 AM by MarkHaysHarris777.)
		
	 
	
		The first step is to use the i2c toolset to see if you can see your device address. if your device is on the wrong i2c bus you won't see the address. The (TWI) bus is reserved. Once you know the address of the device , then you can worry about reading it. 
 
Usually, to read an i2c device you first have to write to it;  this tells the device which register you want to read-- then you have to know whether the data is coming back to you little-endian or big-endian; and this can make a huge difference in terms of interpretation ( if you have the high and low orders confused the data is not going to make much sense ).   
 
The data-sheet is going to be absolutely necessary.
	 
	
	
marcushh777       
please join us for a chat @  irc.pine64.xyz:6667   or ssl  irc.pine64.xyz:6697
 
( I regret that I am not able to respond to personal messages;  let's meet on irc! )
  
	
	
 
 
	
	
		Hi MarkHaysHarris777, 
Thanks for your reply. I must have been unclear in my first post - I am getting data from the T/H sensor, therefore, I have the correct address and bus.      
I was actually thinking about litte-endian vs. big-endian as the cause of my problem since I can see that the T/H sensor sends the result MSB-LSB (can't remember which of the endians that is). So you suggest that I need to switch the order of the returned bytes and the do the conversion again?
 
When you say that I must first write to the I2C device and then read. Do you mean that the smbus command "read_word_data(addr,cmd)" does not write the code in cmd before reading? The only documentation I found is here. I tried writing the command first (using write_byte(0x40, 0xE5)) and then issuing "read_word_data(0x40, 0xE5)" but get similar results.
 
I am probably missing some essential part that is right under my nose...    
	 
	
	
	
	
 
 
	
	
		So I got an answer with code from DonH, thank you very much!   :thumbs_up:  
In order to share the knowledge I am pasting the code he sent me. Essentially you need to tell the sensor to do a measurement and then read the result - which, ironically, is what I did to start with. Except that I only waited 0.02 seconds whereas this code waits 0.5 seconds...  
 
Here's the code, originally from ControlEverything.com and modified for this purpose by DonH:
 
# Distributed with a free-will license. 
# Use it any way you want, profit or free, provided it fits in the licenses of its associated works. 
# STS21 
# This code is designed to work with the STS21_I2CS I2C Mini Module available from ControlEverything.com. 
#  https://www.controleverything.com/conten...t_tabset-2
import smbus 
import time
 
# Get I2C bus 
bus = smbus.SMBus(1)
 
# STS21 address, 0x4A(74) 
# Select Command 
#        0xF3(243)    Temperature measurement in NO HOLD mode 
bus.write_byte(0x40, 0xF3)
 
time.sleep(0.5)
 
# STS21 address, 0x4A(74) 
# Read data back, 2 bytes, MSB first 
data0 = bus.read_byte(0x40) 
data1 = bus.read_byte(0x40)
 
# Convert the data 
temp = (data0 * 256 + data1) & 0xFFFC 
cTemp = -46.85 + (175.72 * temp / 65536.0) 
fTemp = cTemp * 1.8 + 32
 
# Output data to screen 
print ("Temperature in Celsius is :  %.2f C") %cTemp 
print ("Temperature in Fahrenheit is :  %.2f F") %fTemp
 
bus.write_byte(0x40, 0xF5)
 
time.sleep(0.5)
 
data2 = bus.read_byte(0x40) 
data3 = bus.read_byte(0x40)
 
humidity = (data2 * 256 + data3) & 0xFFFC
 
rHumidity = ((125*humidity)/65536)-6
 
print ("Relative humidity is :  %.2f ") %rHumidity
	  
	
	
	
	
 
 
	
	
		In order to complete this request I will now post the code I put together for measuring the Lux value from the Ambient Light Sensor. 
This code is mostly from the manufacturer of the sensor that is used, or rather the sensor used is based on this one ("Base on TAOS/AMS TSL2561T I2C Light Sensor").
 
The original code was in C/C++ but I ported it to Python, please tell me if I made mistakes in porting the code, and the reading of the device registers is based on above code.
 
Have fun    
Yomet
 Code: # -*- coding: utf-8 -*- 
import smbus 
import time 
 
#================================================================================== 
#================================================================================== 
#================================================================================== 
#================================================================================== 
 
# The following code has been adapted from the manufacturers suggested code for converting  
# the Ambient Light measures in Channel 0 and Channel 1 to a Lux value.  
# Ch0 = visible & IR light 
# Ch1 = IR light only 
# Original code was in C and is available at : 
# http://ams.com/eng/content/download/250094/975485/142937 
 
#****************************************************************************  
# Copyright ams AG, Inc. 
# 
# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR 
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 
# PARTICULAR PURPOSE. 
# 
# Module Name: lux.cpp 
# 
#**************************************************************************** 
#unsigned int CalculateLux(unsigned int iGain, unsigned int tInt, unsigned int ch0, unsigned int ch1, int iType) 
def CalculateLux(iGain, tInt, ch0, ch1, iType): 
    LUX_SCALE = 14 # scale by 2^14 
    RATIO_SCALE = 9 # scale ratio by 2^9 
    #--------------------------------------------------- 
    # Integration time scaling factors 
    #--------------------------------------------------- 
    CH_SCALE = 10 # scale channel values by 2^10 
    CHSCALE_TINT0 = 0x7517 # 322/11 * 2^CH_SCALE 
    CHSCALE_TINT1 = 0x0fe7 # 322/81 * 2^CH_SCALE 
    #--------------------------------------------------- 
    # T, FN, and CL Package coefficients 
    #--------------------------------------------------- 
    # For Ch1/Ch0=0.00 to 0.50 
    #    Lux/Ch0=0.0304-0.062*((Ch1/Ch0)^1.4) 
    #    piecewise approximation 
    #       For Ch1/Ch0=0.00 to 0.125: 
    #          Lux/Ch0=0.0304-0.0272*(Ch1/Ch0) 
    #       For Ch1/Ch0=0.125 to 0.250: 
    #          Lux/Ch0=0.0325-0.0440*(Ch1/Ch0) 
    #       For Ch1/Ch0=0.250 to 0.375: 
    #          Lux/Ch0=0.0351-0.0544*(Ch1/Ch0) 
    #       For Ch1/Ch0=0.375 to 0.50: 
    #          Lux/Ch0=0.0381-0.0624*(Ch1/Ch0) 
    # For Ch1/Ch0=0.50 to 0.61: 
    #    Lux/Ch0=0.0224-0.031*(Ch1/Ch0) 
    # For Ch1/Ch0=0.61 to 0.80: 
    #    Lux/Ch0=0.0128-0.0153*(Ch1/Ch0) 
    # For Ch1/Ch0=0.80 to 1.30: 
    #    Lux/Ch0=0.00146-0.00112*(Ch1/Ch0) 
    # For Ch1/Ch0>1.3: 
    #    Lux/Ch0=0 
    #--------------------------------------------------- 
    K1T = 0x0040 # 0.125 * 2^RATIO_SCALE 
    B1T = 0x01f2 # 0.0304 * 2^LUX_SCALE 
    M1T = 0x01be # 0.0272 * 2^LUX_SCALE 
    K2T = 0x0080 # 0.250 * 2^RATIO_SCALE 
    B2T = 0x0214 # 0.0325 * 2^LUX_SCALE 
    M2T = 0x02d1 # 0.0440 * 2^LUX_SCALE 
    K3T = 0x00c0 # 0.375 * 2^RATIO_SCALE 
    B3T = 0x023f # 0.0351 * 2^LUX_SCALE 
    M3T = 0x037b # 0.0544 * 2^LUX_SCALE 
    K4T = 0x0100 # 0.50 * 2^RATIO_SCALE 
    B4T = 0x0270 # 0.0381 * 2^LUX_SCALE 
    M4T = 0x03fe # 0.0624 * 2^LUX_SCALE 
    K5T = 0x0138 # 0.61 * 2^RATIO_SCALE 
    B5T = 0x016f # 0.0224 * 2^LUX_SCALE 
    M5T = 0x01fc # 0.0310 * 2^LUX_SCALE 
    K6T = 0x019a # 0.80 * 2^RATIO_SCALE 
    B6T = 0x00d2 # 0.0128 * 2^LUX_SCALE 
    M6T = 0x00fb # 0.0153 * 2^LUX_SCALE 
    K7T = 0x029a # 1.3 * 2^RATIO_SCALE 
    B7T = 0x0018 # 0.00146 * 2^LUX_SCALE 
    M7T = 0x0012 # 0.00112 * 2^LUX_SCALE 
    K8T = 0x029a # 1.3 * 2^RATIO_SCALE 
    B8T = 0x0000 # 0.000 * 2^LUX_SCALE 
    M8T = 0x0000 # 0.000 * 2^LUX_SCALE 
    #--------------------------------------------------- 
    # CS package coefficients 
    #--------------------------------------------------- 
    # For 0 <= Ch1/Ch0 <= 0.52 
    #    Lux/Ch0 = 0.0315-0.0593*((Ch1/Ch0)^1.4) 
    #    piecewise approximation 
    #       For 0 <= Ch1/Ch0 <= 0.13 
    #          Lux/Ch0 = 0.0315-0.0262*(Ch1/Ch0) 
    #       For 0.13 <= Ch1/Ch0 <= 0.26 
    #          Lux/Ch0 = 0.0337-0.0430*(Ch1/Ch0) 
    #       For 0.26 <= Ch1/Ch0 <= 0.39 
    #          Lux/Ch0 = 0.0363-0.0529*(Ch1/Ch0) 
    #       For 0.39 <= Ch1/Ch0 <= 0.52 
    #          Lux/Ch0 = 0.0392-0.0605*(Ch1/Ch0) 
    # For 0.52 < Ch1/Ch0 <= 0.65 
    #    Lux/Ch0 = 0.0229-0.0291*(Ch1/Ch0) 
    # For 0.65 < Ch1/Ch0 <= 0.80 
    #    Lux/Ch0 = 0.00157-0.00180*(Ch1/Ch0) 
    # For 0.80 < Ch1/Ch0 <= 1.30 
    #    Lux/Ch0 = 0.00338-0.00260*(Ch1/Ch0) 
    # For Ch1/Ch0 > 1.30 
    #    Lux = 0 
    #--------------------------------------------------- 
    K1C = 0x0043 # 0.130 * 2^RATIO_SCALE 
    B1C = 0x0204 # 0.0315 * 2^LUX_SCALE 
    M1C = 0x01ad # 0.0262 * 2^LUX_SCALE 
    K2C = 0x0085 # 0.260 * 2^RATIO_SCALE 
    B2C = 0x0228 # 0.0337 * 2^LUX_SCALE 
    M2C = 0x02c1 # 0.0430 * 2^LUX_SCALE 
    K3C = 0x00c8 # 0.390 * 2^RATIO_SCALE 
    B3C = 0x0253 # 0.0363 * 2^LUX_SCALE 
    M3C = 0x0363 # 0.0529 * 2^LUX_SCALE 
    K4C = 0x010a # 0.520 * 2^RATIO_SCALE 
    B4C = 0x0282 # 0.0392 * 2^LUX_SCALE 
    M4C = 0x03df # 0.0605 * 2^LUX_SCALE 
    K5C = 0x014d # 0.65 * 2^RATIO_SCALE 
    B5C = 0x0177 # 0.0229 * 2^LUX_SCALE 
    M5C = 0x01dd # 0.0291 * 2^LUX_SCALE 
    K6C = 0x019a # 0.80 * 2^RATIO_SCALE 
    B6C = 0x0101 # 0.0157 * 2^LUX_SCALE 
    M6C = 0x0127 # 0.0180 * 2^LUX_SCALE 
    K7C = 0x029a # 1.3 * 2^RATIO_SCALE 
    B7C = 0x0037 # 0.00338 * 2^LUX_SCALE 
    M7C = 0x002b # 0.00260 * 2^LUX_SCALE 
    K8C = 0x029a # 1.3 * 2^RATIO_SCALE 
    B8C = 0x0000 # 0.000 * 2^LUX_SCALE 
    M8C = 0x0000 # 0.000 * 2^LUX_SCALE 
    # lux equation approximation without floating point calculations 
    #//////////////////////////////////////////////////////////////////////////// 
    # Routine: unsigned int CalculateLux(unsigned int ch0, unsigned int ch0, int iType) 
    # 
    # Description: Calculate the approximate illuminance (lux) given the raw 
    #              channel values of the TSL2560. The equation if implemented 
    #              as a piece-wise linear approximation. 
    # 
    # Arguments: unsigned int iGain - gain, where 0:1X, 1:16X 
    #            unsigned int tInt - integration time, where 0:13.7mS, 1:100mS, 2:402mS, 3:Manual 
    #            unsigned int ch0 - raw channel value from channel 0 of TSL2560 
    #            unsigned int ch1 - raw channel value from channel 1 of TSL2560 
    #            unsigned int iType - package type (T or CS) 
    # 
    # Return: unsigned int - the approximate illuminance (lux) 
    # 
    #//////////////////////////////////////////////////////////////////////////// 
    #------------------------------------------------------------------------ 
    # first, scale the channel values depending on the gain and integration time 
    # 16X, 402mS is nominal. 
    # scale if integration time is NOT 402 msec 
    chScale = 0L 
    channel1 = 0L 
    channel0 = 0L 
 
    if tInt == 0: # 13.7 msec 
        chScale = CHSCALE_TINT0 
    elif tInt == 1: # 101 msec 
        chScale = CHSCALE_TINT1 
    else: # assume no scaling 
        chScale = (1 << CH_SCALE) 
    # scale if gain is NOT 16X 
    if iGain == 0: 
        chScale = chScale << 4 # scale 1X to 16X 
    # scale the channel values 
    channel0 = (ch0 * chScale) >> CH_SCALE 
    channel1 = (ch1 * chScale) >> CH_SCALE 
    #------------------------------------------------------------------------ 
    # find the ratio of the channel values (Channel1/Channel0) 
    # protect against divide by zero 
    ratio1 = 0L 
    if channel0 != 0:  
        ratio1 = (channel1 << (RATIO_SCALE+1)) / channel0 
    # round the ratio value 
    ratio = (ratio1 + 1) >> 1; 
 
    b = 0 
    m = 0 
    if iType == 0: # T, FN and CL package 
        if ((ratio >= 0) and (ratio <= K1T)): 
            b = B1T 
            m = M1T 
        elif (ratio <= K2T): 
            b = B2T 
            m = M2T 
        elif (ratio <= K3T): 
            b = B3T 
            m = M3T 
        elif (ratio <= K4T): 
            b = B4T 
            m = M4T 
        elif (ratio <= K5T): 
            b = B5T 
            m = M5T 
        elif (ratio <= K6T): 
            b = B6T 
            m = M6T 
        elif (ratio <= K7T): 
            b = B7T 
            m = M7T 
        elif (ratio > K8T): 
            b = B8T 
            m = M8T 
    elif iType == 1:# CS package 
        if ((ratio >= 0) and (ratio <= K1C)): 
            b = B1C 
            m = M1C 
        elif (ratio <= K2C): 
            b = B2C 
            m = M2C 
        elif (ratio <= K3C): 
            b = B3C 
            m = M3C 
        elif (ratio <= K4C): 
            b = B4C 
            m = M4C 
        elif (ratio <= K5C): 
            b = B5C 
            m = M5C 
        elif (ratio <= K6C): 
            b = B6C 
            m = M6C 
        elif (ratio <= K7C): 
            b = B7C 
            m = M7C 
        elif (ratio > K8C): 
            b = B8C 
            m = M8C 
    temp = 0L 
    temp = ((channel0 * b) - (channel1 * m)) 
    # do not allow negative lux value 
    if temp < 0: 
        temp = 0 
    temp += (1 << (LUX_SCALE-1)) 
    # strip off fractional portion 
    lux = 0L 
    lux = temp >> LUX_SCALE 
    return lux 
 
#================================================================================== 
#================================================================================== 
#================================================================================== 
#================================================================================== 
 
bus = smbus.SMBus(1) 
address = 0x49 
 
#Start the device, only needs to be done when the device is first booted 
bus.write_byte_data(address, 0x80, 0x03) 
time.sleep(0.5) 
 
# Specs on the spec sheet page 30 (Basic Operation) 
# TSL2560-61_DS000110_2-00.pdf 
Ch0L = bus.read_byte_data(address, 0x8C) 
Ch0H = bus.read_byte_data(address, 0x8D) 
Ch0 = Ch0H * 256 + Ch0L 
 
Ch1L = bus.read_byte_data(address, 0x8E) 
Ch1H = bus.read_byte_data(address, 0x8F) 
Ch1 = Ch1H * 256 + Ch1L 
 
# If I understood the technical documents correctly, the Ambient Light Sensor that 
# Pine64 uses should use the FN package calculations. 
# http://ams.com/eng/Products/Light-Sensors/Ambient-Light-Sensors/TSL2561 
# under Technical Documents / Using the Lux Equation 
# http://ams.com/eng/content/view/download/145438 
print "Calculation of Lux according to the T, FN and CL packages" 
light = CalculateLux(0, 2, Ch0, Ch1, 0) # T, FN and CL package 
print "Lux = ", light 
 
#print "Calculation of Lux according to the CS package" 
#light = CalculateLux(0, 2, Ch0, Ch1, 1) # CS package 
#print "Lux = ", light
  
	 
	
	
	
	
 
 
	
	
		Congratulations !
	 
	
	
marcushh777       
please join us for a chat @  irc.pine64.xyz:6667   or ssl  irc.pine64.xyz:6697
 
( I regret that I am not able to respond to personal messages;  let's meet on irc! )
  
	
	
 
 
	
	
		Hi again. 
I add new sensors test here:  http://forum.pine64.org/showthread.php?t...6#pid20736
Now you can test library. Download from here:  https://github.com/blademoon/Sensus
If you have comments or suggestions, please contact me.
	  
	
	
	
	
 
 
	
	
		 (10-01-2016, 02:51 AM)MarkHaysHarris777 Wrote:  Congratulations ! 
Thanks!    
	 
	
	
	
	
 
 
	
	
		 (10-01-2016, 02:40 AM)Yomet Wrote:  In order to complete this request I will now post the code I put together for measuring the Lux value from the Ambient Light Sensor. 
This code is mostly from the manufacturer of the sensor that is used, or rather the sensor used is based on this one ("Base on TAOS/AMS TSL2561T I2C Light Sensor"). 
 
The original code was in C/C++ but I ported it to Python, please tell me if I made mistakes in porting the code, and the reading of the device registers is based on above code. 
 
Have fun    
 
Yomet 
 
 
Code: # -*- coding: utf-8 -*- 
import smbus 
import time 
 
#================================================================================== 
#================================================================================== 
#================================================================================== 
#================================================================================== 
 
# The following code has been adapted from the manufacturers suggested code for converting  
# the Ambient Light measures in Channel 0 and Channel 1 to a Lux value.  
# Ch0 = visible & IR light 
# Ch1 = IR light only 
# Original code was in C and is available at : 
# http://ams.com/eng/content/download/250094/975485/142937 
 
#****************************************************************************  
# Copyright ams AG, Inc. 
# 
# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR 
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 
# PARTICULAR PURPOSE. 
# 
# Module Name: lux.cpp 
# 
#**************************************************************************** 
#unsigned int CalculateLux(unsigned int iGain, unsigned int tInt, unsigned int ch0, unsigned int ch1, int iType) 
def CalculateLux(iGain, tInt, ch0, ch1, iType): 
    LUX_SCALE = 14 # scale by 2^14 
    RATIO_SCALE = 9 # scale ratio by 2^9 
    #--------------------------------------------------- 
    # Integration time scaling factors 
    #--------------------------------------------------- 
    CH_SCALE = 10 # scale channel values by 2^10 
    CHSCALE_TINT0 = 0x7517 # 322/11 * 2^CH_SCALE 
    CHSCALE_TINT1 = 0x0fe7 # 322/81 * 2^CH_SCALE 
    #--------------------------------------------------- 
    # T, FN, and CL Package coefficients 
    #--------------------------------------------------- 
    # For Ch1/Ch0=0.00 to 0.50 
    #    Lux/Ch0=0.0304-0.062*((Ch1/Ch0)^1.4) 
    #    piecewise approximation 
    #       For Ch1/Ch0=0.00 to 0.125: 
    #          Lux/Ch0=0.0304-0.0272*(Ch1/Ch0) 
    #       For Ch1/Ch0=0.125 to 0.250: 
    #          Lux/Ch0=0.0325-0.0440*(Ch1/Ch0) 
    #       For Ch1/Ch0=0.250 to 0.375: 
    #          Lux/Ch0=0.0351-0.0544*(Ch1/Ch0) 
    #       For Ch1/Ch0=0.375 to 0.50: 
    #          Lux/Ch0=0.0381-0.0624*(Ch1/Ch0) 
    # For Ch1/Ch0=0.50 to 0.61: 
    #    Lux/Ch0=0.0224-0.031*(Ch1/Ch0) 
    # For Ch1/Ch0=0.61 to 0.80: 
    #    Lux/Ch0=0.0128-0.0153*(Ch1/Ch0) 
    # For Ch1/Ch0=0.80 to 1.30: 
    #    Lux/Ch0=0.00146-0.00112*(Ch1/Ch0) 
    # For Ch1/Ch0>1.3: 
    #    Lux/Ch0=0 
    #--------------------------------------------------- 
    K1T = 0x0040 # 0.125 * 2^RATIO_SCALE 
    B1T = 0x01f2 # 0.0304 * 2^LUX_SCALE 
    M1T = 0x01be # 0.0272 * 2^LUX_SCALE 
    K2T = 0x0080 # 0.250 * 2^RATIO_SCALE 
    B2T = 0x0214 # 0.0325 * 2^LUX_SCALE 
    M2T = 0x02d1 # 0.0440 * 2^LUX_SCALE 
    K3T = 0x00c0 # 0.375 * 2^RATIO_SCALE 
    B3T = 0x023f # 0.0351 * 2^LUX_SCALE 
    M3T = 0x037b # 0.0544 * 2^LUX_SCALE 
    K4T = 0x0100 # 0.50 * 2^RATIO_SCALE 
    B4T = 0x0270 # 0.0381 * 2^LUX_SCALE 
    M4T = 0x03fe # 0.0624 * 2^LUX_SCALE 
    K5T = 0x0138 # 0.61 * 2^RATIO_SCALE 
    B5T = 0x016f # 0.0224 * 2^LUX_SCALE 
    M5T = 0x01fc # 0.0310 * 2^LUX_SCALE 
    K6T = 0x019a # 0.80 * 2^RATIO_SCALE 
    B6T = 0x00d2 # 0.0128 * 2^LUX_SCALE 
    M6T = 0x00fb # 0.0153 * 2^LUX_SCALE 
    K7T = 0x029a # 1.3 * 2^RATIO_SCALE 
    B7T = 0x0018 # 0.00146 * 2^LUX_SCALE 
    M7T = 0x0012 # 0.00112 * 2^LUX_SCALE 
    K8T = 0x029a # 1.3 * 2^RATIO_SCALE 
    B8T = 0x0000 # 0.000 * 2^LUX_SCALE 
    M8T = 0x0000 # 0.000 * 2^LUX_SCALE 
    #--------------------------------------------------- 
    # CS package coefficients 
    #--------------------------------------------------- 
    # For 0 <= Ch1/Ch0 <= 0.52 
    #    Lux/Ch0 = 0.0315-0.0593*((Ch1/Ch0)^1.4) 
    #    piecewise approximation 
    #       For 0 <= Ch1/Ch0 <= 0.13 
    #          Lux/Ch0 = 0.0315-0.0262*(Ch1/Ch0) 
    #       For 0.13 <= Ch1/Ch0 <= 0.26 
    #          Lux/Ch0 = 0.0337-0.0430*(Ch1/Ch0) 
    #       For 0.26 <= Ch1/Ch0 <= 0.39 
    #          Lux/Ch0 = 0.0363-0.0529*(Ch1/Ch0) 
    #       For 0.39 <= Ch1/Ch0 <= 0.52 
    #          Lux/Ch0 = 0.0392-0.0605*(Ch1/Ch0) 
    # For 0.52 < Ch1/Ch0 <= 0.65 
    #    Lux/Ch0 = 0.0229-0.0291*(Ch1/Ch0) 
    # For 0.65 < Ch1/Ch0 <= 0.80 
    #    Lux/Ch0 = 0.00157-0.00180*(Ch1/Ch0) 
    # For 0.80 < Ch1/Ch0 <= 1.30 
    #    Lux/Ch0 = 0.00338-0.00260*(Ch1/Ch0) 
    # For Ch1/Ch0 > 1.30 
    #    Lux = 0 
    #--------------------------------------------------- 
    K1C = 0x0043 # 0.130 * 2^RATIO_SCALE 
    B1C = 0x0204 # 0.0315 * 2^LUX_SCALE 
    M1C = 0x01ad # 0.0262 * 2^LUX_SCALE 
    K2C = 0x0085 # 0.260 * 2^RATIO_SCALE 
    B2C = 0x0228 # 0.0337 * 2^LUX_SCALE 
    M2C = 0x02c1 # 0.0430 * 2^LUX_SCALE 
    K3C = 0x00c8 # 0.390 * 2^RATIO_SCALE 
    B3C = 0x0253 # 0.0363 * 2^LUX_SCALE 
    M3C = 0x0363 # 0.0529 * 2^LUX_SCALE 
    K4C = 0x010a # 0.520 * 2^RATIO_SCALE 
    B4C = 0x0282 # 0.0392 * 2^LUX_SCALE 
    M4C = 0x03df # 0.0605 * 2^LUX_SCALE 
    K5C = 0x014d # 0.65 * 2^RATIO_SCALE 
    B5C = 0x0177 # 0.0229 * 2^LUX_SCALE 
    M5C = 0x01dd # 0.0291 * 2^LUX_SCALE 
    K6C = 0x019a # 0.80 * 2^RATIO_SCALE 
    B6C = 0x0101 # 0.0157 * 2^LUX_SCALE 
    M6C = 0x0127 # 0.0180 * 2^LUX_SCALE 
    K7C = 0x029a # 1.3 * 2^RATIO_SCALE 
    B7C = 0x0037 # 0.00338 * 2^LUX_SCALE 
    M7C = 0x002b # 0.00260 * 2^LUX_SCALE 
    K8C = 0x029a # 1.3 * 2^RATIO_SCALE 
    B8C = 0x0000 # 0.000 * 2^LUX_SCALE 
    M8C = 0x0000 # 0.000 * 2^LUX_SCALE 
    # lux equation approximation without floating point calculations 
    #//////////////////////////////////////////////////////////////////////////// 
    # Routine: unsigned int CalculateLux(unsigned int ch0, unsigned int ch0, int iType) 
    # 
    # Description: Calculate the approximate illuminance (lux) given the raw 
    #              channel values of the TSL2560. The equation if implemented 
    #              as a piece-wise linear approximation. 
    # 
    # Arguments: unsigned int iGain - gain, where 0:1X, 1:16X 
    #            unsigned int tInt - integration time, where 0:13.7mS, 1:100mS, 2:402mS, 3:Manual 
    #            unsigned int ch0 - raw channel value from channel 0 of TSL2560 
    #            unsigned int ch1 - raw channel value from channel 1 of TSL2560 
    #            unsigned int iType - package type (T or CS) 
    # 
    # Return: unsigned int - the approximate illuminance (lux) 
    # 
    #//////////////////////////////////////////////////////////////////////////// 
    #------------------------------------------------------------------------ 
    # first, scale the channel values depending on the gain and integration time 
    # 16X, 402mS is nominal. 
    # scale if integration time is NOT 402 msec 
    chScale = 0L 
    channel1 = 0L 
    channel0 = 0L 
 
    if tInt == 0: # 13.7 msec 
        chScale = CHSCALE_TINT0 
    elif tInt == 1: # 101 msec 
        chScale = CHSCALE_TINT1 
    else: # assume no scaling 
        chScale = (1 << CH_SCALE) 
    # scale if gain is NOT 16X 
    if iGain == 0: 
        chScale = chScale << 4 # scale 1X to 16X 
    # scale the channel values 
    channel0 = (ch0 * chScale) >> CH_SCALE 
    channel1 = (ch1 * chScale) >> CH_SCALE 
    #------------------------------------------------------------------------ 
    # find the ratio of the channel values (Channel1/Channel0) 
    # protect against divide by zero 
    ratio1 = 0L 
    if channel0 != 0:  
        ratio1 = (channel1 << (RATIO_SCALE+1)) / channel0 
    # round the ratio value 
    ratio = (ratio1 + 1) >> 1; 
 
    b = 0 
    m = 0 
    if iType == 0: # T, FN and CL package 
        if ((ratio >= 0) and (ratio <= K1T)): 
            b = B1T 
            m = M1T 
        elif (ratio <= K2T): 
            b = B2T 
            m = M2T 
        elif (ratio <= K3T): 
            b = B3T 
            m = M3T 
        elif (ratio <= K4T): 
            b = B4T 
            m = M4T 
        elif (ratio <= K5T): 
            b = B5T 
            m = M5T 
        elif (ratio <= K6T): 
            b = B6T 
            m = M6T 
        elif (ratio <= K7T): 
            b = B7T 
            m = M7T 
        elif (ratio > K8T): 
            b = B8T 
            m = M8T 
    elif iType == 1:# CS package 
        if ((ratio >= 0) and (ratio <= K1C)): 
            b = B1C 
            m = M1C 
        elif (ratio <= K2C): 
            b = B2C 
            m = M2C 
        elif (ratio <= K3C): 
            b = B3C 
            m = M3C 
        elif (ratio <= K4C): 
            b = B4C 
            m = M4C 
        elif (ratio <= K5C): 
            b = B5C 
            m = M5C 
        elif (ratio <= K6C): 
            b = B6C 
            m = M6C 
        elif (ratio <= K7C): 
            b = B7C 
            m = M7C 
        elif (ratio > K8C): 
            b = B8C 
            m = M8C 
    temp = 0L 
    temp = ((channel0 * b) - (channel1 * m)) 
    # do not allow negative lux value 
    if temp < 0: 
        temp = 0 
    temp += (1 << (LUX_SCALE-1)) 
    # strip off fractional portion 
    lux = 0L 
    lux = temp >> LUX_SCALE 
    return lux 
 
#================================================================================== 
#================================================================================== 
#================================================================================== 
#================================================================================== 
 
bus = smbus.SMBus(1) 
address = 0x49 
 
#Start the device, only needs to be done when the device is first booted 
bus.write_byte_data(address, 0x80, 0x03) 
time.sleep(0.5) 
 
# Specs on the spec sheet page 30 (Basic Operation) 
# TSL2560-61_DS000110_2-00.pdf 
Ch0L = bus.read_byte_data(address, 0x8C) 
Ch0H = bus.read_byte_data(address, 0x8D) 
Ch0 = Ch0H * 256 + Ch0L 
 
Ch1L = bus.read_byte_data(address, 0x8E) 
Ch1H = bus.read_byte_data(address, 0x8F) 
Ch1 = Ch1H * 256 + Ch1L 
 
# If I understood the technical documents correctly, the Ambient Light Sensor that 
# Pine64 uses should use the FN package calculations. 
# http://ams.com/eng/Products/Light-Sensors/Ambient-Light-Sensors/TSL2561 
# under Technical Documents / Using the Lux Equation 
# http://ams.com/eng/content/view/download/145438 
print "Calculation of Lux according to the T, FN and CL packages" 
light = CalculateLux(0, 2, Ch0, Ch1, 0) # T, FN and CL package 
print "Lux = ", light 
 
#print "Calculation of Lux according to the CS package" 
#light = CalculateLux(0, 2, Ch0, Ch1, 1) # CS package 
#print "Lux = ", light
  
Bravo !!!
	  
	
	
	
	
 
 
	 
 |