|
26 | 26 | * Adafruit's Register library: https://github.com/adafruit/Adafruit_CircuitPython_Register
|
27 | 27 | """
|
28 | 28 |
|
29 |
| -# imports |
| 29 | +import time |
| 30 | + |
| 31 | +from adafruit_bus_device.i2c_device import I2CDevice |
| 32 | +from adafruit_register.i2c_bit import ROBit, RWBit |
| 33 | +from adafruit_register.i2c_bits import RWBits |
| 34 | +from adafruit_register.i2c_struct import ROUnaryStruct, Struct, UnaryStruct |
| 35 | +from micropython import const |
| 36 | + |
| 37 | +try: |
| 38 | + import typing |
| 39 | + |
| 40 | + from busio import I2C |
| 41 | +except ImportError: |
| 42 | + pass |
30 | 43 |
|
31 | 44 | __version__ = "0.0.0+auto.0"
|
32 | 45 | __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_VCNL4200.git"
|
| 46 | + |
| 47 | +_I2C_ADDRESS = const(0x51) # Default I2C address for VCNL4200 |
| 48 | + |
| 49 | +# Register addresses |
| 50 | +_ALS_CONF = const(0x00) # ALS configuration register |
| 51 | +_ALS_THDH = const(0x01) # ALS high threshold register |
| 52 | +_ALS_THDL = const(0x02) # ALS low threshold register |
| 53 | +_PS_CONF12 = const(0x03) # Proximity sensor configuration register 1 & 2 |
| 54 | +_PS_CONF3MS = const(0x04) # Proximity sensor configuration register 3 & MS |
| 55 | +_PS_CANC_LVL = const(0x05) # Proximity cancellation level register |
| 56 | +_PS_THDL = const(0x06) # Proximity sensor low threshold register |
| 57 | +_PS_THDH = const(0x07) # Proximity sensor high threshold register |
| 58 | +_PS_DATA = const(0x08) # Proximity sensor data register |
| 59 | +_ALS_DATA = const(0x09) # ALS data register |
| 60 | +_WHITE_DATA = const(0x0A) # White sensor register |
| 61 | +_INT_FLAG = const(0x0D) # Interrupt flag register |
| 62 | +_ID = const(0x0E) # Device ID register |
| 63 | + |
| 64 | +# Interrupt flags |
| 65 | +_INTFLAG_PROX_UPFLAG = const(0x80) # Proximity code saturation flag |
| 66 | +_INTFLAG_PROX_SPFLAG = const(0x40) # Proximity sunlight protection flag |
| 67 | +_INTFLAG_ALS_LOW = const(0x20) # ALS interrupt flag |
| 68 | +_INTFLAG_ALS_HIGH = const(0x10) # Proximity interrupt flag |
| 69 | +_INTFLAG_PROX_CLOSE = const(0x02) # Proximity THDH trigger |
| 70 | +_INTFLAG_PROX_AWAY = const(0x01) # Proximity THDL trigger |
| 71 | + |
| 72 | +# ALS Integration Time settings |
| 73 | +ALS_IT = { |
| 74 | + "50MS": const(0x00), # 50 ms integration time |
| 75 | + "100MS": const(0x01), # 100 ms integration time |
| 76 | + "200MS": const(0x02), # 200 ms integration time |
| 77 | + "400MS": const(0x03), # 400 ms integration time |
| 78 | +} |
| 79 | + |
| 80 | +# ALS Persistence settings |
| 81 | +ALS_PERS = { |
| 82 | + "1": const(0x00), # ALS persistence 1 conversion |
| 83 | + "2": const(0x01), # ALS persistence 2 conversions |
| 84 | + "4": const(0x02), # ALS persistence 4 conversions |
| 85 | + "8": const(0x03), # ALS persistence 8 conversions |
| 86 | +} |
| 87 | + |
| 88 | +# Proximity Sensor Integration Time settings |
| 89 | +PS_IT = { |
| 90 | + "1T": const(0x00), # Proximity integration time 1T |
| 91 | + "2T": const(0x01), # Proximity integration time 2T |
| 92 | + "3T": const(0x02), # Proximity integration time 3T |
| 93 | + "4T": const(0x03), # Proximity integration time 4T |
| 94 | + "8T": const(0x04), # Proximity integration time 8T |
| 95 | + "9T": const(0x05), # Proximity integration time 9T |
| 96 | +} |
| 97 | + |
| 98 | +# Proximity Sensor Persistence settings |
| 99 | +PS_PERS = { |
| 100 | + "1": const(0x00), # Proximity persistence 1 conversion |
| 101 | + "2": const(0x01), # Proximity persistence 2 conversions |
| 102 | + "3": const(0x02), # Proximity persistence 3 conversions |
| 103 | + "4": const(0x03), # Proximity persistence 4 conversions |
| 104 | +} |
| 105 | + |
| 106 | +# Proximity Sensor Duty settings |
| 107 | +PS_DUTY = { |
| 108 | + "1_160": const(0x00), # Proximity duty cycle 1/160 |
| 109 | + "1_320": const(0x01), # Proximity duty cycle 1/320 |
| 110 | + "1_640": const(0x02), # Proximity duty cycle 1/640 |
| 111 | + "1_1280": const(0x03), # Proximity duty cycle 1/1280 |
| 112 | +} |
| 113 | + |
| 114 | +# Proximity Sensor Interrupt settings |
| 115 | +PS_INT = { |
| 116 | + "DISABLE": const(0x00), # Proximity interrupt disabled |
| 117 | + "CLOSE": const(0x01), # Proximity interrupt when an object is close |
| 118 | + "AWAY": const(0x02), # Proximity interrupt when an object is away |
| 119 | + "BOTH": const(0x03), # Proximity interrupt for both close and away |
| 120 | +} |
| 121 | + |
| 122 | +# LED Current settings |
| 123 | +LED_I = { |
| 124 | + "50MA": const(0x00), # LED current 50mA |
| 125 | + "75MA": const(0x01), # LED current 75mA |
| 126 | + "100MA": const(0x02), # LED current 100mA |
| 127 | + "120MA": const(0x03), # LED current 120mA |
| 128 | + "140MA": const(0x04), # LED current 140mA |
| 129 | + "160MA": const(0x05), # LED current 160mA |
| 130 | + "180MA": const(0x06), # LED current 180mA |
| 131 | + "200MA": const(0x07), # LED current 200mA |
| 132 | +} |
| 133 | + |
| 134 | +# Proximity Sensor Multi Pulse settings |
| 135 | +PS_MPS = { |
| 136 | + "1": const(0x00), # Proximity multi pulse 1 |
| 137 | + "2": const(0x01), # Proximity multi pulse 2 |
| 138 | + "4": const(0x02), # Proximity multi pulse 4 |
| 139 | + "8": const(0x03), # Proximity multi pulse 8 |
| 140 | +} |
| 141 | + |
| 142 | + |
| 143 | +class Adafruit_VCNL4200: |
| 144 | + # Device ID expected value for VCNL4200 |
| 145 | + _DEVICE_ID = 0x1058 |
| 146 | + |
| 147 | + # Register for ALS configuration |
| 148 | + als_shutdown = RWBits(1, _ALS_CONF, 0) # ALS shutdown bit |
| 149 | + als_integration_time = RWBits(2, _ALS_CONF, 6) # ALS integration time bits |
| 150 | + als_persistance = RWBits(2, _ALS_CONF, 2) # ALS persistence bits |
| 151 | + als_low_threshold = UnaryStruct(_ALS_THDL, "<H") |
| 152 | + als_high_threshold = UnaryStruct(_ALS_THDH, "<H") |
| 153 | + prox_shutdown = RWBit(_PS_CONF12, 0) # Bit 0: PS_SD (Proximity Sensor Shutdown) |
| 154 | + prox_integration_time = RWBits(3, _PS_CONF12, 1) |
| 155 | + proximity = ROUnaryStruct(_PS_DATA, "<H") |
| 156 | + lux = ROUnaryStruct(_ALS_DATA, "<H") |
| 157 | + white_light = ROUnaryStruct(_WHITE_DATA, "<H") # 16-bit register for white light data |
| 158 | + _als_int_en = RWBits(1, _ALS_CONF, 1) # Bit 1: ALS interrupt enable |
| 159 | + _als_int_switch = RWBits(1, _ALS_CONF, 5) # Bit 5: ALS interrupt channel selection (white/ALS) |
| 160 | + _proximity_int_en = RWBits( |
| 161 | + 1, _PS_CONF12, 0 |
| 162 | + ) # Bit 0 in proximity config register for proximity interrupt enable |
| 163 | + |
| 164 | + def __init__(self, i2c: I2C, addr: int = _I2C_ADDRESS) -> None: |
| 165 | + self.i2c_device = I2CDevice(i2c, addr) |
| 166 | + for _ in range(2): |
| 167 | + with self.i2c_device as i2c: |
| 168 | + # Manually read the device ID register (0x0E, 2 bytes) |
| 169 | + buffer = bytearray(2) |
| 170 | + i2c.write_then_readinto(bytes([_ID]), buffer) |
| 171 | + device_id = int.from_bytes(buffer, "little") |
| 172 | + # Check if it matches expected device ID |
| 173 | + if device_id == self._DEVICE_ID: |
| 174 | + break |
| 175 | + else: |
| 176 | + raise RuntimeError("Device ID mismatch.") |
| 177 | + try: |
| 178 | + self.als_shutdown = False |
| 179 | + self.als_integration_time = ALS_IT["50MS"] |
| 180 | + self.als_persistence = ALS_PERS["1"] |
| 181 | + self.als_low_threshold = 0 |
| 182 | + self.als_high_threshold = 0xFFFF |
| 183 | + self.set_interrupt(enabled=False, white_channel=False) |
| 184 | + self.prox_shutdown = False |
| 185 | + self.prox_integration_time = PS_IT["1T"] |
| 186 | + except Exception as error: |
| 187 | + raise RuntimeError(f"Failed to initialize: {error}") from error |
| 188 | + |
| 189 | + def set_interrupt(self, enabled, white_channel): |
| 190 | + """Configure ALS interrupt settings, enabling or disabling |
| 191 | + the interrupt and selecting the interrupt channel.""" |
| 192 | + try: |
| 193 | + self._als_int_en = enabled |
| 194 | + self._als_int_switch = white_channel |
| 195 | + return True |
| 196 | + except OSError: |
| 197 | + return False |
0 commit comments