31
31
https://github.com/adafruit/Adafruit_CircuitPython_Register
32
32
"""
33
33
34
+ import time
35
+
34
36
from micropython import const
35
37
import adafruit_bus_device .i2c_device as i2cdevice
36
38
from adafruit_register .i2c_struct import UnaryStruct , ROUnaryStruct
@@ -78,6 +80,9 @@ class VEML7700:
78
80
ALS_GAIN_1_8 : 0.125 ,
79
81
}
80
82
83
+ # Convenience list of gains
84
+ gain_settings = [ALS_GAIN_1_8 , ALS_GAIN_1_4 , ALS_GAIN_1 , ALS_GAIN_2 ]
85
+
81
86
# Integration time value integers
82
87
integration_time_values = {
83
88
ALS_25MS : 25 ,
@@ -88,6 +93,16 @@ class VEML7700:
88
93
ALS_800MS : 800 ,
89
94
}
90
95
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
+
91
106
# ALS - Ambient light sensor high resolution output data
92
107
light = ROUnaryStruct (0x04 , "<H" )
93
108
"""Ambient light data.
@@ -205,6 +220,33 @@ def __init__(self, i2c_bus: I2C, address: int = 0x10) -> None:
205
220
else :
206
221
raise RuntimeError ("Unable to enable VEML7700 device" )
207
222
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
+
208
250
def integration_time_value (self ) -> int :
209
251
"""Integration time value in integer form. Used for calculating :meth:`resolution`."""
210
252
integration_time = self .light_integration_time
@@ -253,3 +295,77 @@ def lux(self) -> float:
253
295
time.sleep(0.1)
254
296
"""
255
297
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