11#!/usr/bin/python
22
3- # Python library for the TSL2561 digital luminosity (light) sensors.
4- # Version 0
5-
6- # This library is heavily based on the Arduino library for the TSL2561 digital luminosity (light) sensors.
7- # It is basically a simple translation from C++ to Python.
8- # The thread on the Adafruit forum helped a lot to do this.
9- # Thanks to static, huelke, pandring, adafruit_support_rick, scortier, bryand, csalty, lenos and of course to Adafruit
10- # Source for the Arduino library: https://github.com/adafruit/TSL2561-Arduino-Library
11- # Adafruit forum thread:http://forums.adafruit.com/viewtopic.php?f=8&t=34922&sid=8336d566f2f03c25882aaf34c8a15a92
12- #
13- # Original code posted here http://forums.adafruit.com/viewtopic.php?f=8&t=34922&start=75#p222877
14- #
15- # Changes by Iain Colledge
16- #
17-
18- #
19- # This was checked against a 10 UKP lux meter from Amazon and was withing 10% up and down the range, the meter
20- # had a stated accuracy of 5% but then again, 10 UKP meter.
21- #
22- # Changelog:
23- #
24- # 1.1 - Fixes from https://forums.adafruit.com/viewtopic.php?f=8&t=34922&p=430795#p430782 - Iain Colledge
25- # Bug #1: The class name has the middle two digits transposed - Adafruit_TSL2651 should be Adafruit_TSL2561
26- # Bug #2: The read8 and read16 methods (functions) call the I2C readS8 and readS16 methods respectively.
27- # They should call the readU8 and readU16 (i.e. unsigned) methods.
28- # 1.0 - Initial release - Iain Colledge
29- # Removed commented out C++ code
30- # Added calculateAvgLux
31- # Changed main method to use calculateAvgLux and loop argument support added.
32- # Ported "Extended delays to take into account loose timing with 'delay'" update from CPP code
33- # Added hack so that with autogain every sample goes from 1x to 16x as going from 16x to 1x does not work
34- #
3+ """
4+ Python library for the TSL2561 digital luminosity (light) sensors.
5+
6+ This library is heavily based on the Arduino library for the TSL2561 digital luminosity (light) sensors.
7+ It is basically a simple translation from C++ to Python.
8+ The thread on the Adafruit forum helped a lot to do this.
9+ Thanks to static, huelke, pandring, adafruit_support_rick, scortier, bryand, csalty, lenos and of course to Adafruit
10+ Source for the Arduino library: https://github.com/adafruit/TSL2561-Arduino-Library
11+ Adafruit forum thread:http://forums.adafruit.com/viewtopic.php?f=8&t=34922&sid=8336d566f2f03c25882aaf34c8a15a92
12+
13+ Original code posted here http://forums.adafruit.com/viewtopic.php?f=8&t=34922&start=75#p222877
14+
15+ This was checked against a 10 UKP lux meter from Amazon and was withing 10% up and down the range, the meter
16+ had a stated accuracy of 5% but then again, 10 UKP meter.
17+
18+ Changelog:
19+
20+ 1.1 - Fixes from https://forums.adafruit.com/viewtopic.php?f=8&t=34922&p=430795#p430782 - Iain Colledge
21+ Bug #1: The class name has the middle two digits transposed - Adafruit_TSL2651 should be Adafruit_TSL2561
22+ Bug #2: The read8 and read16 methods (functions) call the I2C readS8 and readS16 methods respectively.
23+ They should call the readU8 and readU16 (i.e. unsigned) methods.
24+ Minor fixes and changes
25+ 1.0 - Initial release - Iain Colledge
26+ Removed commented out C++ code
27+ Added calculateAvgLux
28+ Changed main method to use calculateAvgLux and loop argument support added.
29+ Ported "Extended delays to take into account loose timing with 'delay'" update from CPP code
30+ Added hack so that with autogain every sample goes from 1x to 16x as going from 16x to 1x does not work
31+ """
3532
3633import sys
3734import time
@@ -157,57 +154,64 @@ class Adafruit_TSL2561(Adafruit_I2C):
157154
158155 TSL2561_NO_OF_AVG_SAMPLES = 25 # How many samples to make an average reading
159156
160-
161-
162-
163- #**************************************************************************
164- # Writes a register and an 8 bit value over I2C
165- #**************************************************************************
166157 def write8 (self , reg , value ):
158+ """
159+ Writes a register and an 8 bit value over I2C
160+
161+ :param reg: Register / Address to write value to
162+ :param value: Byte to write to Address
163+ """
167164 if (self ._debug == True ): print "write8"
168165 self ._i2c .write8 (reg , value )
169166 if (self ._debug == True ): print "write8_end"
170167
171- #**************************************************************************
172- # Reads an 8 bit value over I2C
173- #**************************************************************************
174168 def read8 (self , reg ):
169+ """
170+ Reads an 8 bit value over I2C
171+
172+ :param reg: Register / Address to read value from
173+ :return: Unsigned byte
174+ """
175175 if (self ._debug == True ): print "read8"
176176 return self ._i2c .readU8 (reg )
177177 if (self ._debug == True ): print "read8_end"
178178
179- #**************************************************************************
180- # Reads a 16 bit values over I2C
181- #**************************************************************************
182179 def read16 (self , reg ):
180+ """
181+ Reads a 16 bit values over I2C
182+
183+ :param reg: Register / Address to read value from
184+ :return: Unsigned word
185+ """
183186 if (self ._debug == True ): print "read16"
184187 return self ._i2c .readU16 (reg )
185188 if (self ._debug == True ): print "read16_end"
186189
187- #**************************************************************************
188- # Enables the device
189- #**************************************************************************
190190 def enable (self ):
191+ """
192+ Enables the device
193+ """
191194 if (self ._debug == True ): print "enable"
192195 # Enable the device by setting the control bit to 0x03 */
193196 self ._i2c .write8 (self .TSL2561_COMMAND_BIT | self .TSL2561_REGISTER_CONTROL , self .TSL2561_CONTROL_POWERON )
194197 if (self ._debug == True ): print "enable_end"
195198
196- #**************************************************************************
197- # Disables the device (putting it in lower power sleep mode)
198- #**************************************************************************
199199 def disable (self ):
200+ """
201+ Disables the device (putting it in lower power sleep mode)
202+ """
200203 if (self ._debug == True ): print "disable"
201204 # Turn the device off to save power */
202205 self ._i2c .write8 (self .TSL2561_COMMAND_BIT | self .TSL2561_REGISTER_CONTROL , self .TSL2561_CONTROL_POWEROFF )
203206 if (self ._debug == True ): print "disable_end"
204207
205- #**************************************************************************
206- # Private function to read luminosity on both channels
207- #**************************************************************************
208208 def getData (self ):
209+ """
210+ Private function to read luminosity on both channels
211+ """
209212 if (self ._debug == True ): print "getData"
210- # Enable the device by setting the control bit to 0x03 */
213+
214+ #Enables the device by setting the control bit to 0x03
211215 self .enable ();
212216
213217 # Wait x ms for ADC to complete */
@@ -229,10 +233,13 @@ def getData (self):
229233 self .disable ();
230234 if (self ._debug == True ): print "getData_end"
231235
232- #**************************************************************************
233- # Constructor
234- #**************************************************************************
235236 def __init__ (self , addr = TSL2561_ADDR_FLOAT , debug = False ):
237+ """
238+ Constructor
239+
240+ :param addr: I2C address of TSL2561, defaults to 0x39
241+ :param debug: Turn on debugging, defaults to False
242+ """
236243 self ._debug = debug
237244 if (self ._debug == True ): print "__init__"
238245 self ._addr = addr
@@ -246,11 +253,15 @@ def __init__(self, addr=TSL2561_ADDR_FLOAT, debug=False):
246253 self ._ir = 0
247254 if (self ._debug == True ): print "__init___end"
248255
249- #**************************************************************************
250- # Initializes I2C and configures the sensor (call this function before
251- # doing anything else)
252- #**************************************************************************
253256 def begin (self ):
257+ """
258+ Initializes I2C and configures the sensor (call this function before
259+ doing anything else)
260+
261+ Note: by default, the device is in power down mode on bootup
262+
263+ :return: True if connected to a TSL2561
264+ """
254265 if (self ._debug == True ): print "begin"
255266 # Make sure we're actually connected */
256267 x = self .read8 (self .TSL2561_REGISTER_ID );
@@ -268,25 +279,30 @@ def begin(self):
268279
269280 return True
270281
271- #**************************************************************************
272- # Enables or disables the auto-gain settings when reading
273- # data from the sensor
274- #**************************************************************************
275282 def enableAutoGain (self , enable ):
283+ """
284+ Enables or disables the auto-gain settings when reading
285+ data from the sensor
286+
287+ :param enable: True to enable
288+ """
276289 if (self ._debug == True ): print "enableAutoGain"
277290 if (enable == True ):
278291 self ._tsl2561AutoGain = enable
279292 else :
280293 self ._tsl2561AutoGain = False
281294 if (self ._debug == True ): print "enableAutoGain_end"
282295
283- #**************************************************************************
284- # Sets the integration time for the TSL2561
285- #**************************************************************************
286296 def setIntegrationTime (self , time ):
297+ """
298+ Sets the integration time for the TSL2561
299+
300+ :param time:
301+ :return:
302+ """
287303 if (self ._debug == True ): print "setIntegrationTime"
288304 if (not self ._tsl2561Initialised ):
289- self .begin ()
305+ self .begin
290306
291307 # Enable the device by setting the control bit to 0x03 */
292308 self .enable ();
@@ -301,13 +317,15 @@ def setIntegrationTime(self, time):
301317 self .disable ()
302318 if (self ._debug == True ): print "setIntegrationTime_end"
303319
304- #**************************************************************************
305- # Adjusts the gain on the TSL2561 (adjusts the sensitivity to light)
306- #**************************************************************************
307320 def setGain (self , gain ):
321+ """
322+ Adjusts the gain on the TSL2561 (adjusts the sensitivity to light)
323+
324+ :param gain:
325+ """
308326 if (self ._debug == True ): print "setGain"
309327 if (not self ._tsl2561Initialised ):
310- self .begin ()
328+ self .begin
311329
312330 # Enable the device by setting the control bit to 0x03 */
313331 self .enable ()
@@ -322,11 +340,12 @@ def setGain(self, gain):
322340 self .disable ()
323341 if (self ._debug == True ): print "setGain_end"
324342
325- #**************************************************************************
326- # Gets the broadband (mixed lighting) and IR only values from
327- # the TSL2561, adjusting gain if auto-gain is enabled
328- #**************************************************************************
329343 def getLuminosity (self ):
344+ """
345+ Gets the broadband (mixed lighting) and IR only values from
346+ the TSL2561, adjusting gain if auto-gain is enabled
347+
348+ """
330349 # This is a hack to ensure that when looping with autogain the gain can go up and down as without
331350 # setting the gain to 1X before every reading it doesn't seem able to go from 16X
332351 # back to 1X again. Going from 1X to 16X works fine. - IC
@@ -337,7 +356,7 @@ def getLuminosity (self):
337356 valid = False
338357
339358 if (not self ._tsl2561Initialised ):
340- self .begin ()
359+ self .begin
341360
342361 # If Auto gain disabled get a single reading and continue */
343362 if (not self ._tsl2561AutoGain ):
@@ -389,11 +408,13 @@ def getLuminosity (self):
389408 valid = True
390409 if (self ._debug == True ): print "getLuminosity_end"
391410
392- #**************************************************************************
393- # Converts the raw sensor values to the standard SI lux equivalent.
394- # Returns 0 if the sensor is saturated and the values are unreliable.
395- #**************************************************************************
396411 def calculateLux (self ):
412+ """
413+ Converts the raw sensor values to the standard SI lux equivalent.
414+ Returns 0 if the sensor is saturated and the values are unreliable.
415+
416+ :return: lux value, unsigned 16bit word (0 - 65535)
417+ """
397418 if (self ._debug == True ): print "calculateLux"
398419 self .getLuminosity ()
399420 # Make sure the sensor isn't saturated! */
@@ -405,6 +426,7 @@ def calculateLux(self):
405426 clipThreshold = self .TSL2561_CLIPPING_402MS
406427
407428 # Return 0 lux if the sensor is saturated */
429+ # TODO: Throw an exception rather than return 0
408430 if ((self ._broadband > clipThreshold ) or (self ._ir > clipThreshold )):
409431 return 0
410432
@@ -500,10 +522,13 @@ def calculateLux(self):
500522 if (self ._debug == True ): print "calculateLux_end"
501523 return lux
502524
503- #**************************************************************************
504- # Calculates an averaged Lux value over default 25 samples
505- #**************************************************************************
506525 def calculateAvgLux (self , testavg = TSL2561_NO_OF_AVG_SAMPLES ):
526+ """
527+ Calculates an averaged Lux value, useful for flickering lights and for smoothing values due to noise
528+
529+ :param testavg: Number of samples to take in a reading, defaults to 25
530+ :return: lux value, unsigned 16bit word (0 - 65535)
531+ """
507532 # Set initial vars
508533 count = 0
509534 luxavgtotal = 0
0 commit comments