3131 https://github.com/adafruit/Adafruit_CircuitPython_Register
3232"""
3333
34+ import time
35+
3436from micropython import const
3537import adafruit_bus_device .i2c_device as i2cdevice
3638from adafruit_register .i2c_struct import UnaryStruct , ROUnaryStruct
@@ -78,6 +80,9 @@ class VEML7700:
7880 ALS_GAIN_1_8 : 0.125 ,
7981 }
8082
83+ # Convenience list of gains
84+ gain_settings = [ALS_GAIN_1_8 , ALS_GAIN_1_4 , ALS_GAIN_1 , ALS_GAIN_2 ]
85+
8186 # Integration time value integers
8287 integration_time_values = {
8388 ALS_25MS : 25 ,
@@ -88,6 +93,16 @@ class VEML7700:
8893 ALS_800MS : 800 ,
8994 }
9095
96+ # Convenience list of integration times
97+ integration_time_settings = [
98+ ALS_25MS ,
99+ ALS_50MS ,
100+ ALS_100MS ,
101+ ALS_200MS ,
102+ ALS_400MS ,
103+ ALS_800MS ,
104+ ]
105+
91106 # ALS - Ambient light sensor high resolution output data
92107 light = ROUnaryStruct (0x04 , "<H" )
93108 """Ambient light data.
@@ -205,6 +220,33 @@ def __init__(self, i2c_bus: I2C, address: int = 0x10) -> None:
205220 else :
206221 raise RuntimeError ("Unable to enable VEML7700 device" )
207222
223+ self .last_read = self .milliseconds ()
224+
225+ @staticmethod
226+ def milliseconds () -> float :
227+ """The time in milliseconds.
228+
229+ :return: The current time.
230+ :rtype: float
231+ """
232+ return time .monotonic () * 1000
233+
234+ def compute_lux (self , als : int , use_correction : bool ) -> float :
235+ """Compute lux, possibly using non-linear correction.
236+
237+ :param int als: The ambient light level.
238+ :param bool use_correction: Flag for applying the non-linear correction.
239+
240+ :return: The calculated lux.
241+ :rtype: float
242+ """
243+ lux = self .resolution () * als
244+ if use_correction :
245+ lux = (
246+ ((6.0135e-13 * lux - 9.3924e-9 ) * lux + 8.1488e-5 ) * lux + 1.0023
247+ ) * lux
248+ return lux
249+
208250 def integration_time_value (self ) -> int :
209251 """Integration time value in integer form. Used for calculating :meth:`resolution`."""
210252 integration_time = self .light_integration_time
@@ -253,3 +295,77 @@ def lux(self) -> float:
253295 time.sleep(0.1)
254296 """
255297 return self .resolution () * self .light
298+
299+ @property
300+ def autolux (self ) -> float :
301+ """Light value in lux using auto checks and correction.
302+
303+ This property uses auto gain and auto integration time adjustments as well
304+ as a non-linear correction if necessary.
305+
306+ .. code-block:: python
307+
308+ import time
309+ import board
310+ import adafruit_veml7700
311+
312+ i2c = board.I2C() # uses board.SCL and board.SDA
313+ veml7700 = adafruit_veml7700.VEML7700(i2c)
314+
315+ while True:
316+ print("Lux:", veml7700.autolux)
317+ veml7700.wait_autolux(0.1)
318+ """
319+ gain_index = 0
320+ it_index = 2
321+ use_correction = False
322+
323+ self .gain_settings .index (self .light_gain )
324+ self .integration_time_settings .index (self .light_integration_time )
325+
326+ als = self ._read_als_wait ()
327+
328+ if als <= 100 :
329+ while als <= 100 and not (gain_index == 3 and it_index == 5 ):
330+ if gain_index < 3 :
331+ gain_index += 1
332+ self .light_gain = self .gain_settings [gain_index ]
333+ elif it_index < 5 :
334+ it_index += 1
335+ self .light_integration_time = self .integration_time_settings [
336+ it_index
337+ ]
338+ als = self ._read_als_wait ()
339+ else :
340+ use_correction = True
341+ while als > 10000 and it_index > 0 :
342+ it_index -= 1
343+ self .light_integration_time = self .integration_time_settings [it_index ]
344+ als = self ._read_als_wait ()
345+
346+ return self .compute_lux (als , use_correction )
347+
348+ def _read_als_wait (self ) -> float :
349+ """Read ambient light level, but wait on the integration time.
350+
351+ :return: The ambient light level value.
352+ :rtype: float
353+ """
354+ time_to_wait = 2 * self .integration_time_value ()
355+ time_waited = self .milliseconds () - self .last_read
356+ if time_waited < time_to_wait :
357+ time .sleep ((time_to_wait - time_waited ) / 1000 )
358+ self .last_read = self .milliseconds ()
359+ return self .light
360+
361+ def wait_autolux (self , wait_time : float ) -> None :
362+ """Wait minimum time between autolux measurements.
363+
364+ Ensure that the shortest wait time cannot be below the current
365+ integration time setting.
366+
367+ :param float wait_time: The requested time between measurements (seconds).
368+ """
369+ minimum_wait_time = self .integration_time_value () / 1000
370+ actual_wait_time = max (minimum_wait_time , wait_time )
371+ time .sleep (actual_wait_time )
0 commit comments