APDS9960

Driver class for the APDS9960 board. Supports gesture, proximity, and color detection.

  • Author(s): Michael McWethy, Erik Hess

Implementation Notes

Hardware:

Software and Dependencies:

class adafruit_apds9960.apds9960.APDS9960(i2c: I2C, *, rotation: int = 0, reset: bool = True, set_defaults: bool = True)[source]

Provide basic driver services for the APDS9960 breakout board

Parameters:
  • i2c (I2C) – The I2C bus the APDS9960 is connected to

  • rotation (int) – Rotation of the device. Defaults to 0

  • reset (bool) – If true, reset device on init. Defaults to True

  • set_defaults (bool) – If true, set sensible defaults on init. Defaults to True

Quickstart: Importing and using the APDS9960

Here is an example of using the APDS9960 class. First you will need to import the libraries to use the sensor

import board
from adafruit_apds9960.apds9960 import APDS9960

Once this is done you can define your board.I2C object and define your sensor object

i2c = board.I2C()   # uses board.SCL and board.SDA
apds = APDS9960(i2c)

Now you have access to the apds.proximity_enable and apds.proximity attributes

apds.proximity_enable = True
proximity = apds.proximity

Note

There is no address argument because the APDS-9960 only has one address and doesn’t offer any option to configure alternative addresses.

clear_interrupt() None[source]

Clears all non-gesture interrupts.

This includes all of the following internal interrupts:

  • Proximity Interrupt (PINT)

  • Proximity Saturation Interrupt (STATUS<PGSAT>)

  • Color/Light Interrupt (STATUS<AINT>)

  • Color/Light Clear Saturation Interrupt (STATUS<CPSAT>)

property color_data: Tuple[int, int, int, int]

Tuple containing red, green, blue, and clear light intensity values detected by the sensor during the latest color/light engine run.

Each value is a 16-bit integer with a possible value of 0 to 65535.

Caution

Will always return (0, 0, 0, 0) if enable_color is not set to True.

Tip

To get useful, predictable color_data results it is important to tune color_gain and color_integration_time, to accommodate different lighting conditions, sensor placements, plastic/glass transparencies, expected object reflectivity, and environmental conditions.

For instance, measuring color of objects close to the sensor with bright, nearby illumination (such as the white LEDs on the Adafruit Clue) may work well with a color_gain of 0 and a color_integration_time of 72.

However, measuring the intensity and color temperature of ambient light through difusion glass or plastic is likely to require experimenting with a wide range of color_gain and color_integration_time settings before useful data can be obtained.

property color_data_ready: int

Color data ready flag.

Returns 0 if no new data is ready, 1 if new data is ready.

This flag is reset when color_data is read.

property color_gain: int

Color/light sensor gain value.

This sets the gain multiplier for the ADC during color/light engine operations.

color_gain

Gain Multiplier

Note

0

1x

Power-on Default

1

4x

Driver Default

2

16x

3

64x

Tip

To get useful, predictable color_data results it is important to tune this, along with color_integration_time, to accommodate different lighting conditions, sensor placements, material transparencies, expected object reflectivity, and environmental conditions.

For instance, measuring color of objects close to the sensor with bright, nearby illumination (such as the white LEDs on the Adafruit CLUE) may work well with a color_gain of 0 and a color_integration_time of 72 or lower.

However, measuring the intensity and color temperature of ambient light through difusion glass or plastic is likely to require experimenting with a wide range of integration time and gain settings before useful data can be obtained.

property color_integration_time: int

Color/light sensor gain.

Represents the integration time in number of 2.78 ms cycles for the ADC during color/light engine operations. This also effectively sets the maxmium value returned for each channel by color_data.

color_integration_time

Time

Max Count

Note

1

2.78 ms

1025

Power-on Default

10

27.8 ms

10241

37

103 ms

37889

72

200 ms

65535

256

712 ms

65535

Driver Default

property enable: bool

If True, the sensor is enabled.

If set to False, the sensor will enter a low-power sleep state

When enabled, the sensor’s state machine will run through the following steps in sequence, repeating from the top after all states are run through.

  1. Idle State

    • Will only remain in this state if all three sense engines are disabled.

  2. Proximity Engine (if enabled)

    • Will only run if enable_proximity is True.

    • Will run once, storing fresh data in the sensor’s proximity data registers. If proximity data is is lower than or exceeds the configured proximity thresholds an internal persistence is incremented on each run as well.

  3. Gesture Engine (if enabled)

    • Will only run if enable_gesture is True and if entry threshold of proximity is greater or equal to the gesture proximity entry threshold of 5 counts.

    • Will continuously loop, storing new results in the sensor’s gesture FIFO buffers, until one of four conditions occur.

      • Exit threshold is met. (all gesture measurements <= 30 counts)

      • The gesture engine or sensor are disabled. (`enable_gesture` or `enable` properties are set to ``False``)

      • The sensor is re-initalized by the driver

      • The sensor is power cycled

  4. Wait Timer (set to 0 by default)

    • This driver does not set or make available the WAIT or WLONG registers that control this function and, on intialization, leaves the timer at its power-on default state of 0, effectively disabling this timer.

  5. Color/Light Engine (if enabled)

    • Will run start if enable_color is True.

    • Will run once, storing fresh data in the sensor’s color data registers on each run.

Note

Waking the sensor from its sleep state takes at least 7 ms. Disabling the sensor and entering a sleep state can take as little as 2.78 ms, more typically about 25 ms, or potentially quite a bit longer depending on what engines were enabled and what state was active at the time the disable command was received.

Hint

When in a sleep state the sensor’s power usage drops to as little as 1-10 uA, compared as much as 790 uA of power usage when enabled with proximity and/or gesture engines running. While in a sleep state, the sensor will still listen for and respond to I2C communication which can lead to minor increases in power usage.

property enable_color: bool

If True, the sensor’s color/light engine is enabled

property enable_gesture: bool

If True, the sensor’s gesture engine is enabled.

Note

The gesture engine will only operate if enable_proximity is also set to True

property enable_proximity: bool

If True, the sensor’s proximity engine is enabled.

property enable_proximity_interrupt: bool

If True, the internal proximity interrupt asserts the sensor’s interrupt pin.

Internal proximity interrupt triggering is configured via proximity_interrupt_threshold.

Tip

Using this interrupt will require attaching the sensor’s INT pin to an available digital I/O with an internal or external pull-up resistor.

For boards with built-in sensors the pin is likely already mapped within board.

Board

Pin Mapping

CLUE

board.PROXIMITY_LIGHT_INTERRUPT

Feather nRF52840 Sense

board.PROXIMITY_LIGHT_INTERRUPT

Proximity Trinkey

board.INTERRUPT

gesture() int[source]

Gesture sensor data.

This checks the sensor for new gesture engine results and, if they are present, retrieves and processes the results to determine what, if any, gesture can be deduced from the sensor data.

Returns a gesture code indicating the direction of the gesture. Before returning the code, the rotation value is used to “rotate” the result as intended.

Code

Direction

0

No gesture detected

1

Up

2

Down

3

Left

4

Right

Caution

Will always return 0 if enable_proximity and enable_gesture are not set to True.

The data returned by the sensor is a continuous stream of four proximtiy measurements constrained to up/down/left/right dimensions by using four directionally-aligned sensors. The sensor itself doesn’t include any logic to determine the gesture, leaving that work to the implementer.

This driver implements an algorithm that reliably detects simple gestures in most scenarios while remaining small and efficient enough to work within the resource constraints of as many CircuitPython boards/platforms as possible.

Tip

Detecting gestures with this driver’s algorithm requires actively, continously polling for a gesture, with as little time as possible between gesture() calls. Even with continous polling, however, its possible that gestures may go undetected by gesture() calls if they occurred between or on the edges of gesture() method execution.

Warning

If gesture data becomes available from the sensor, this driver will continuously pull in that new data and analyze it until the sensor’s gesture engine exits and the sensor’s FIFO buffers are clear. This allows for much more reliable gesture detection by comparing the “first” to the “last” detected state at the cost of blocking until the FIFOs are all clear. This will only happen if all four gesture values drop below 30.

As a result, if an object is close to the sensor when gesture() is called, the method will not return until it moves away.

Note

The sensor itself offers a very wide variety of configuration options for tuning the gesture engine, such as the LEDs (pulse count/length, drive power), the photosensors (gain, offsets, masking), the gesture engine’s entry/exit thresholds, wait time, and more. However, this driver does not make those readily available in order to keep file size and memory footprint to a minimum, which is critical for its use on more constrained platforms.

property gesture_gain: int

Gesture mode gain value.

This sets the gain multiplier for the ADC during gesture engine operations.

gesture_gain

Gain Multiplier

Note

0

1x

Power-on Default

1

2x

2

4x

Driver Default

3

8x

property proximity: int

Proximity sensor data.

The proximity engine returns a number between 0 and 255 which represents the intensity of the reflected IR light detected from the sensor’s internal LEDs, which pulse continously during proximity engine operation.

A value of 0 indicates no reflected IR light was received. This typically indicates that no object(s) were in the sensor’s line of sight and within detectable range of its IR LED pulses.

A value of 255 indicates that the maximum detectable amount of reflected IR light was received. This typically indicates that an object was detected very close to the sensor.

Caution

Will always return 0 if enable_proximity is not set True.

Note

The sensor itself offers a very wide variety of configuration options for tuning the proximity engine, such as the LEDs (pulse count/length, drive power) and the photosensors (gain, offsets, masking). However, this driver does not make those readily available in order to keep file size and memory footprint to a minimum, which is critical for its use on more constrained platforms.

property proximity_gain: int

Proximity sensor gain value.

This sets the gain multiplier for the ADC during proximity engine operations.

proximity_gain

Gain Multiplier

Note

0

1x

Power-on Default

1

2x

2

4x

3

8x

property proximity_interrupt_threshold: Tuple[int, int, int]

Tuple representing proximity engine low/high threshold and persistence, which determine when the sensor’s proximity interrupt is asserted.

  1. Low Threshold (PILT)

  2. High Threshold (PIHT) (optional)

  3. Proximity Persistence (PERS<PPERS>) (optional)

The first two items are the “low threshold” and “high threshold” values. These can be set to any number between 0 and 255. If the proximity value is lower than the low threshold or higher than the high threshold for enough cycles, an interrupt will be asserted.

The third item is the “persistence” value. This can be set to any value between 0 to 15. This represents the number of 2.78 ms out-of-threshold cycles to wait for before asserting the interrupt. This is basically a filter to prevent premature/false interrupts.

Hint

For example, setting a low threshold of 0 and a high threshold of 5 will cause the interrupt to be asserted very early when an object enters the sensor’s line of sight. Coversely, a low threshold of 5 and a high threshold of 255 will trigger an interrupt only if an object is removed from the sensor’s line of sight.

Hint

Tuning the persistence value can be useful in some use cases but for most situations the driver’s default value of 4 should provide for stable results without much delay in interrupt triggering.

property rotation: int

Clock-wise offset to apply to gesture results.

Acceptable values are 0, 90, 180, 270.

Tip

The sensor’s “top” end is the one with the larger of the two circular windows.

Some rotation examples for various boards with the APS-9960 built in:

Board

Rotation

CLUE

270

Feather nRF52840 Sense, with USB port to the left

270

Proximity Trinkey, plugged into right-side laptop USB port

270

Proximity Trinkey, plugged into left-side laptop USB port

90

colorutility

Helper functions for color calculations

  • Author(s): Michael McWethy

adafruit_apds9960.colorutility.calculate_color_temperature(r: int, g: int, b: int) float[source]

Converts the raw R/G/B values to color temperature in degrees Kelvin

adafruit_apds9960.colorutility.calculate_lux(r: int, g: int, b: int) float[source]

Calculate ambient light values