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 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.
@@ -144,7 +159,7 @@ class VEML7700:
144159 import adafruit_veml7700
145160
146161 i2c = board.I2C() # uses board.SCL and board.SDA
147- veml7700 = adafruit_vcnl4040.VCNL4040 (i2c)
162+ veml7700 = adafruit_veml7700.VEML7700 (i2c)
148163
149164 veml7700.light_gain = veml7700.ALS_GAIN_2
150165
@@ -167,7 +182,7 @@ class VEML7700:
167182 import adafruit_veml7700
168183
169184 i2c = board.I2C() # uses board.SCL and board.SDA
170- veml7700 = adafruit_vcnl4040.VCNL4040 (i2c)
185+ veml7700 = adafruit_veml7700.VEML7700 (i2c)
171186
172187 veml7700.light_integration_time = veml7700.ALS_400MS
173188
@@ -191,6 +206,33 @@ def __init__(self, i2c_bus: I2C, address: int = 0x10) -> None:
191206 else :
192207 raise RuntimeError ("Unable to enable VEML7700 device" )
193208
209+ self .last_read = self .milliseconds ()
210+
211+ @staticmethod
212+ def milliseconds () -> float :
213+ """The time in milliseconds.
214+
215+ :return: The current time.
216+ :rtype: float
217+ """
218+ return time .monotonic () * 1000
219+
220+ def compute_lux (self , als : int , use_correction : bool ) -> float :
221+ """Compute lux, possibly using non-linear correction.
222+
223+ :param int als: The ambient light level.
224+ :param bool use_correction: Flag for applying the non-linear correction.
225+
226+ :return: The calculated lux.
227+ :rtype: float
228+ """
229+ lux = self .resolution () * als
230+ if use_correction :
231+ lux = (
232+ ((6.0135e-13 * lux - 9.3924e-9 ) * lux + 8.1488e-5 ) * lux + 1.0023
233+ ) * lux
234+ return lux
235+
194236 def integration_time_value (self ) -> int :
195237 """Integration time value in integer form. Used for calculating :meth:`resolution`."""
196238 integration_time = self .light_integration_time
@@ -239,3 +281,77 @@ def lux(self) -> float:
239281 time.sleep(0.1)
240282 """
241283 return self .resolution () * self .light
284+
285+ @property
286+ def autolux (self ) -> float :
287+ """Light value in lux using auto checks and correction.
288+
289+ This property uses auto gain and auto integration time adjustments as well
290+ as a non-linear correction if necessary.
291+
292+ .. code-block:: python
293+
294+ import time
295+ import board
296+ import adafruit_veml7700
297+
298+ i2c = board.I2C() # uses board.SCL and board.SDA
299+ veml7700 = adafruit_veml7700.VEML7700(i2c)
300+
301+ while True:
302+ print("Lux:", veml7700.autolux)
303+ veml7700.wait_autolux(0.1)
304+ """
305+ gain_index = 0
306+ it_index = 2
307+ use_correction = False
308+
309+ self .gain_settings .index (self .light_gain )
310+ self .integration_time_settings .index (self .light_integration_time )
311+
312+ als = self ._read_als_wait ()
313+
314+ if als <= 100 :
315+ while als <= 100 and not (gain_index == 3 and it_index == 5 ):
316+ if gain_index < 3 :
317+ gain_index += 1
318+ self .light_gain = self .gain_settings [gain_index ]
319+ elif it_index < 5 :
320+ it_index += 1
321+ self .light_integration_time = self .integration_time_settings [
322+ it_index
323+ ]
324+ als = self ._read_als_wait ()
325+ else :
326+ use_correction = True
327+ while als > 10000 and it_index > 0 :
328+ it_index -= 1
329+ self .light_integration_time = self .integration_time_settings [it_index ]
330+ als = self ._read_als_wait ()
331+
332+ return self .compute_lux (als , use_correction )
333+
334+ def _read_als_wait (self ) -> float :
335+ """Read ambient light level, but wait on the integration time.
336+
337+ :return: The ambient light level value.
338+ :rtype: float
339+ """
340+ time_to_wait = 2 * self .integration_time_value ()
341+ time_waited = self .milliseconds () - self .last_read
342+ if time_waited < time_to_wait :
343+ time .sleep ((time_to_wait - time_waited ) / 1000 )
344+ self .last_read = self .milliseconds ()
345+ return self .light
346+
347+ def wait_autolux (self , wait_time : float ) -> None :
348+ """Wait minimum time between autolux measurements.
349+
350+ Ensure that the shortest wait time cannot be below the current
351+ integration time setting.
352+
353+ :param float wait_time: The requested time between measurements (seconds).
354+ """
355+ minimum_wait_time = self .integration_time_value () / 1000
356+ actual_wait_time = max (minimum_wait_time , wait_time )
357+ time .sleep (actual_wait_time )
0 commit comments