Source code for micropython_vcnl4010.vcnl4010

# SPDX-FileCopyrightText: Copyright (c) 2023 Jose D. Montoya
#
# SPDX-License-Identifier: MIT
"""
`vcnl4010`
================================================================================

9


* Author(s): Jose D. Montoya


"""

import time
from micropython import const
from micropython_vcnl4010.i2c_helpers import CBits, RegisterStruct


__version__ = "0.0.0+auto.0"
__repo__ = "https://github.com/jposada202020/MicroPython_VCNL4010.git"

_REG_WHOAMI = const(0x81)
_COMMAND_REGISTER = const(0x80)
_PROXIMITY_RATE_REGISTER = const(0x82)
_IR_LED_CURRENT_REGISTER = const(0x83)
_AMBIENT_LIGHT_PARAMETER_REGISTER = const(0x84)
_AMBIENT_LIGHT_DATA = const(0x85)
_PROXIMITY_DATA = const(0x87)

SAMPLERATE_1_95 = const(0b000)
SAMPLERATE_3_90625 = const(0b001)
SAMPLERATE_7_8125 = const(0b010)
SAMPLERATE_16_625 = const(0b011)
SAMPLERATE_31_25 = const(0b100)
SAMPLERATE_62_5 = const(0b101)
SAMPLERATE_125 = const(0b110)
SAMPLERATE_250 = const(0b111)
proximity_rate_values = (
    SAMPLERATE_1_95,
    SAMPLERATE_3_90625,
    SAMPLERATE_7_8125,
    SAMPLERATE_16_625,
    SAMPLERATE_31_25,
    SAMPLERATE_62_5,
    SAMPLERATE_125,
    SAMPLERATE_250,
)

AMBIENT_LIGHT_RATE1 = const(0b000)
AMBIENT_LIGHT_RATE2 = const(0b001)
AMBIENT_LIGHT_RATE3 = const(0b010)
AMBIENT_LIGHT_RATE4 = const(0b011)
AMBIENT_LIGHT_RATE5 = const(0b100)
AMBIENT_LIGHT_RATE6 = const(0b101)
AMBIENT_LIGHT_RATE8 = const(0b110)
AMBIENT_LIGHT_RATE10 = const(0b111)
ambient_light_rate_values = (
    AMBIENT_LIGHT_RATE1,
    AMBIENT_LIGHT_RATE2,
    AMBIENT_LIGHT_RATE3,
    AMBIENT_LIGHT_RATE4,
    AMBIENT_LIGHT_RATE5,
    AMBIENT_LIGHT_RATE6,
    AMBIENT_LIGHT_RATE8,
    AMBIENT_LIGHT_RATE10,
)

AL_AVERAGE1 = const(0b000)
AL_AVERAGE2 = const(0b001)
AL_AVERAGE4 = const(0b010)
AL_AVERAGE8 = const(0b011)
AL_AVERAGE16 = const(0b100)
AL_AVERAGE32 = const(0b101)
AL_AVERAGE64 = const(0b110)
AL_AVERAGE128 = const(0b111)
ambient_light_average_values = (
    AL_AVERAGE1,
    AL_AVERAGE2,
    AL_AVERAGE4,
    AL_AVERAGE8,
    AL_AVERAGE16,
    AL_AVERAGE32,
    AL_AVERAGE64,
    AL_AVERAGE128,
)


[docs] class VCNL4010: """Driver for the VCNL4010 Sensor connected over I2C. :param ~machine.I2C i2c: The I2C bus the VCNL4010 is connected to. :param int address: The I2C device address. Defaults to :const:`0x13` :raises RuntimeError: if the sensor is not found **Quickstart: Importing and using the device** Here is an example of using the :class:`VCNL4010` class. First you will need to import the libraries to use the sensor .. code-block:: python from machine import Pin, I2C from micropython_vcnl4010 import vcnl4010 Once this is done you can define your `machine.I2C` object and define your sensor object .. code-block:: python i2c = I2C(1, sda=Pin(2), scl=Pin(3)) vcnl4010 = vcnl4010.VCNL4010(i2c) Now you have access to the attributes .. code-block:: python """ _device_id = RegisterStruct(_REG_WHOAMI, "B") _ambient_light = RegisterStruct(_AMBIENT_LIGHT_DATA, "H") _proximity = RegisterStruct(_PROXIMITY_DATA, "H") _proximity_rate = CBits(3, _PROXIMITY_RATE_REGISTER, 0) _ambient_light_measure_ready = CBits(1, _COMMAND_REGISTER, 6) _proximity_measure_ready = CBits(1, _COMMAND_REGISTER, 5) _get_ambient_light = CBits(1, _COMMAND_REGISTER, 4) _get_proximity = CBits(1, _COMMAND_REGISTER, 3) _ambient_light_rate = CBits(3, _AMBIENT_LIGHT_PARAMETER_REGISTER, 4) _ambient_light_average = CBits(3, _AMBIENT_LIGHT_PARAMETER_REGISTER, 0) _irl_led_current = CBits(6, _IR_LED_CURRENT_REGISTER, 0) def __init__(self, i2c, address: int = 0x13) -> None: self._i2c = i2c self._address = address if self._device_id != 0x21: raise RuntimeError("Failed to find VCNL4010") @property def proximity_rate(self) -> str: """ Sensor proximity_rate +-----------------------------------------+-------------------+ | Mode | Value | +=========================================+===================+ | :py:const:`vcnl4010.SAMPLERATE_1_95` | :py:const:`0b000` | +-----------------------------------------+-------------------+ | :py:const:`vcnl4010.SAMPLERATE_3_90625` | :py:const:`0b001` | +-----------------------------------------+-------------------+ | :py:const:`vcnl4010.SAMPLERATE_7_8125` | :py:const:`0b010` | +-----------------------------------------+-------------------+ | :py:const:`vcnl4010.SAMPLERATE_16_625` | :py:const:`0b011` | +-----------------------------------------+-------------------+ | :py:const:`vcnl4010.SAMPLERATE_31_25` | :py:const:`0b100` | +-----------------------------------------+-------------------+ | :py:const:`vcnl4010.SAMPLERATE_62_5` | :py:const:`0b101` | +-----------------------------------------+-------------------+ | :py:const:`vcnl4010.SAMPLERATE_125` | :py:const:`0b110` | +-----------------------------------------+-------------------+ | :py:const:`vcnl4010.SAMPLERATE_250` | :py:const:`0b111` | +-----------------------------------------+-------------------+ """ values = ( "SAMPLERATE_1_95", "SAMPLERATE_3_90625", "SAMPLERATE_7_8125", "SAMPLERATE_16_625", "SAMPLERATE_31_25", "SAMPLERATE_62_5", "SAMPLERATE_125", "SAMPLERATE_250", ) return values[self._proximity_rate] @proximity_rate.setter def proximity_rate(self, value: int) -> None: if value not in proximity_rate_values: raise ValueError("Value must be a valid proximity_rate setting") self._proximity_rate = value @property def irl_led_current(self) -> int: """ IR LED current = Value (dec.) x 10 mA. Valid Range = 0 to 20d. e.g. 0 = 0 mA , 1 = 10 mA, …., 20 = 200 mA (2 = 20 mA = DEFAULT) LED Current is limited to 200 mA for values higher as 20d. """ return self._irl_led_current @irl_led_current.setter def irl_led_current(self, value: int) -> None: if value not in range(1, 21, 1): raise ValueError("Value must be a valid irl_led_current setting") self._irl_led_current = value @property def ambient_light_rate(self) -> str: """ Sensor ambient_light_rate +-------------------------------------------+-------------------+ | Mode | Value | +===========================================+===================+ | :py:const:`vcnl4010.AMBIENT_LIGHT_RATE1` | :py:const:`0b000` | +-------------------------------------------+-------------------+ | :py:const:`vcnl4010.AMBIENT_LIGHT_RATE2` | :py:const:`0b001` | +-------------------------------------------+-------------------+ | :py:const:`vcnl4010.AMBIENT_LIGHT_RATE3` | :py:const:`0b010` | +-------------------------------------------+-------------------+ | :py:const:`vcnl4010.AMBIENT_LIGHT_RATE4` | :py:const:`0b011` | +-------------------------------------------+-------------------+ | :py:const:`vcnl4010.AMBIENT_LIGHT_RATE5` | :py:const:`0b100` | +-------------------------------------------+-------------------+ | :py:const:`vcnl4010.AMBIENT_LIGHT_RATE6` | :py:const:`0b101` | +-------------------------------------------+-------------------+ | :py:const:`vcnl4010.AMBIENT_LIGHT_RATE8` | :py:const:`0b110` | +-------------------------------------------+-------------------+ | :py:const:`vcnl4010.AMBIENT_LIGHT_RATE10` | :py:const:`0b111` | +-------------------------------------------+-------------------+ """ values = ( "AMBIENT_LIGHT_RATE1", "AMBIENT_LIGHT_RATE2", "AMBIENT_LIGHT_RATE3", "AMBIENT_LIGHT_RATE4", "AMBIENT_LIGHT_RATE5", "AMBIENT_LIGHT_RATE6", "AMBIENT_LIGHT_RATE8", "AMBIENT_LIGHT_RATE10", ) return values[self._ambient_light_rate] @ambient_light_rate.setter def ambient_light_rate(self, value: int) -> None: if value not in ambient_light_rate_values: raise ValueError("Value must be a valid ambient_light_rate setting") self._ambient_light_rate = value @property def ambient_light_average(self) -> str: """ Sensor ambient_light_average +------------------------------------+-------------------+ | Mode | Value | +====================================+===================+ | :py:const:`vcnl4010.AL_AVERAGE1` | :py:const:`0b000` | +------------------------------------+-------------------+ | :py:const:`vcnl4010.AL_AVERAGE2` | :py:const:`0b001` | +------------------------------------+-------------------+ | :py:const:`vcnl4010.AL_AVERAGE4` | :py:const:`0b010` | +------------------------------------+-------------------+ | :py:const:`vcnl4010.AL_AVERAGE8` | :py:const:`0b011` | +------------------------------------+-------------------+ | :py:const:`vcnl4010.AL_AVERAGE16` | :py:const:`0b100` | +------------------------------------+-------------------+ | :py:const:`vcnl4010.AL_AVERAGE32` | :py:const:`0b101` | +------------------------------------+-------------------+ | :py:const:`vcnl4010.AL_AVERAGE64` | :py:const:`0b110` | +------------------------------------+-------------------+ | :py:const:`vcnl4010.AL_AVERAGE128` | :py:const:`0b111` | +------------------------------------+-------------------+ """ values = ( "AL_AVERAGE1", "AL_AVERAGE2", "AL_AVERAGE4", "AL_AVERAGE8", "AL_AVERAGE16", "AL_AVERAGE32", "AL_AVERAGE64", "AL_AVERAGE128", ) return values[self._ambient_light_average] @ambient_light_average.setter def ambient_light_average(self, value: int) -> None: if value not in ambient_light_average_values: raise ValueError("Value must be a valid ambient_light_average setting") self._ambient_light_average = value @property def proximity(self) -> int: """ Proximity of an object in front of the sensor """ self._get_proximity = True while True: if self._proximity_measure_ready: return self._proximity time.sleep(0.001) @property def ambient(self) -> int: """ Ambient light in lux """ self._get_ambient_light = True while True: if self._ambient_light_measure_ready: return self._ambient_light * 0.25 time.sleep(0.001)