Github Repo | C Header | C source | JS source |
---|---|---|---|
mongoose-os-libs/apds9960-i2c | mgos_apds9960.h |
A Mongoose library for Avago's APDS-9960 RGB, IR and Gesture Sensor.
The APDS-9960 device features advanced Gesture detection, Proximity detection, Digital Ambient Light Sense (ALS) and Color Sense (RGBC). The slim modular package, L 3.94 x W 2.36 x H 1.35 mm, incorporates an IR LED and factory calibrated LED driver for drop-in compatibility with existing footprints.
Gesture detection utilizes four directional photodiodes to sense reflected IR energy (sourced by the integrated LED) to convert physical motion information (i.e. velocity, direction and distance) to a digital information. The architecture of the gesture engine features automatic activation (based on Proximity engine results), ambient light subtraction, cross-talk cancelation, dual 8-bit data converters, power saving inter-conversion delay, 32-dataset FIFO, and interrupt driven I2C communication. The gesture engine accommodates a wide range of mobile device gesturing requirements: simple UP-DOWN-RIGHT-LEFT gestures or more complex gestures can be accurately sensed. Power consumption and noise are minimized with adjustable IR LED timing.
The Proximity detection feature provides distance measurement (E.g. mobile device screen to user’s ear) by photodiode detection of reflected IR energy (sourced by the integrated LED). Detect/release events are interrupt driven, and occur whenever proximity result crosses upper and/ or lower threshold settings. The proximity engine features offset adjustment registers to compensate for system offset caused by unwanted IR energy reflections appearing at the sensor. The IR LED intensity is factory trimmed to eliminate the need for end-equipment calibration due to component variations. Proximity results are further improved by automatic ambient light subtraction.
The Color and ALS detection feature provides red, green, blue and clear light intensity data. Each of the R, G, B, C channels have a UV and IR blocking filter and a dedicated data converter producing16-bit data simultaneously. This architecture allows applications to accurately measure ambient light and sense color which enables devices to calculate color temperature and control display backlight.
There are two APIs defined in this driver. Firstly, a low level API is used to
drive the configuration of the chip. Secondly, a higher level abstraction is
provided for application programmers that want to merely read proximity
and
light
data from the sensor, or install a hardware interrupt to callback user
code upon certain events (such as proximity
, light
and gesture
events
described above.)
Gesture sending is incredibly hard with this sensor. Work is needed to improve the performance of the gesture code in this driver.
Proximity and Light sensing and interrupts are working fine.
An example program using a timer to read data from the sensor every 5 seconds:
#include "mgos.h"
#include "mgos_config.h"
#include "mgos_apds9960.h"
static void light_interrupt(uint16_t clear, uint16_t red, uint16_t green, uint16_t blue) {
LOG(LL_INFO, ("clear=%u red=%u green=%u blue=%u", clear, red, green, blue));
}
static void proximity_interrupt(uint8_t proximity) {
LOG(LL_INFO, ("proximity=%u", proximity));
}
static void apds9960_timer_cb(void *user_data) {
struct mgos_apds9960 *sensor = (struct mgos_apds9960 *)user_data;
uint16_t clear = 0, red = 0, green = 0, blue = 0;
uint8_t proximity = 0;
if (!mgos_apds9960_read_light(sensor, &clear, &red, &green, &blue)) {
LOG(LL_ERROR, ("Could not read APDS9960 light sensor"));
}
if (!mgos_apds9960_read_proximity(sensor, &proximity)) {
LOG(LL_ERROR, ("Could not read APDS9960 proximity sensor"));
}
LOG(LL_INFO, ("clear=%u red=%u green=%u blue=%u proximity=%u", clear, red, green, blue, proximity));
}
enum mgos_app_init_result mgos_app_init(void) {
struct mgos_apds9960 *sensor;
sensor = mgos_apds9960_create(mgos_i2c_get_global(), mgos_sys_config_get_apds9960_i2caddr());
if (!sensor) {
LOG(LL_ERROR, ("Could not create APDS9960 sensor"));
return false;
}
if (!mgos_apds9960_set_callback_light(sensor, 10, 1000, light_interrupt)) {
LOG(LL_ERROR, ("Could not enable APDS9960 light callback"));
return false;
}
if (!mgos_apds9960_set_callback_proximity(sensor, 0, 150, proximity_interrupt)) {
LOG(LL_ERROR, ("Could not enable APDS9960 proximity callback"));
return false;
}
mgos_set_timer(1000, true, apds9960_timer_cb, sensor);
return MGOS_APP_INIT_SUCCESS;
}
This project is not an official Google project. It is not supported by Google and Google specifically disclaims all warranties as to its quality, merchantability, or fitness for a particular purpose.
struct mgos_apds9960 *mgos_apds9960_create(struct mgos_i2c *i2c, uint8_t i2caddr);
Initialize a APDS9960 on the I2C bus
i2c
at address specified ini2caddr
parameter (default APDS9960 is on address 0x39). The sensor will be polled for validity, upon success a newstruct mgos_apds9960
is allocated and returned. If the device could not be found, NULL is returned.
void mgos_apds9960_destroy(struct mgos_apds9960 **sensor);
Destroy the data structure associated with a APDS9960 device. The reference to the pointer of the
struct mgos_apds9960
has to be provided, and upon successful destruction, its associated memory will be freed and the pointer set to NULL.
bool mgos_apds9960_set_callback_light(struct mgos_apds9960 *sensor, uint16_t low_threshold, uint16_t high_threshold, mgos_apds9960_light_event_t handler);
bool mgos_apds9960_set_callback_proximity(struct mgos_apds9960 *sensor, uint8_t low_threshold, uint8_t high_threshold, mgos_apds9960_proximity_event_t handler);
bool mgos_apds9960_set_callback_gesture(struct mgos_apds9960 *sensor, mgos_apds9960_gesture_event_t handler);
Install an interrupt (see
mos.yml
keyapds9960.irq_pin
), and when the interrupt is asserted, call a callback forlight
,proximity
and/orgesture
events.For light:
low_threshold
andhigh_threshold
arguments determine between which values on theclear
(ambient) light channel an interrupt is generated.For proximity:
low_threshold
andhigh_threshold
arguments determine between which values on theproximity
channel an interrupt is generated. Note: high values are closer to the sensor, low values are further away.Returns true on success, or false otherwise.
bool mgos_apds9960_read_light(struct mgos_apds9960 *sensor, uint16_t *clear, uint16_t *red, uint16_t *green, uint16_t *blue);
Read the clear (ambient), red, green, and blue light values from the sensor. Lower values mean less light was detected. The arguments clear, red, green and blue may be NULL, in which case they are not polled from the sensor. Returns true on success, or false otherwise. If false is returned, the values of clear, red, green and blue cannot be used.
bool mgos_apds9960_read_proximity(struct mgos_apds9960 *sensor, uint8_t *proximity);
Read the proximity value from the sensor. Lower values mean further away, higher values mean closer to the sensor. Returns true on success, or false otherwise. If false is returned, the value of proximity cannot be used.
bool mgos_apds9960_is_gesture_available(struct mgos_apds9960 *sensor);
edit this docReturn true if the gesture sensor has available data in its FIFO buffer.