En este tutorial aprenderás a usar el sensor de proximidad y luz APDS-9930 con un Arduino o cualquier otro microcontrolador común (ESP32/ESP8266).
El APDS-9930 es un sensor muy pequeño que se usa frecuentemente en smartphones y tablets para el ajuste automático del brillo de la pantalla y la detección de proximidad durante llamadas. También puedes usarlo como un detector de gestos simple que activa luces u otros dispositivos al pasar la mano frente a él.
Partes necesarias
Para este proyecto necesitarás un sensor APDS-9930 y un microcontrolador. Yo usé un Arduino Uno, pero cualquier otro Arduino o un ESP32/ESP8266 funcionará, siempre que proporcione una salida de alimentación de 3.3V.

Sensor APDS-9930

Arduino Uno

Cable USB para Arduino UNO

Juego de cables Dupont

Protoboard
Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.
Características del sensor de proximidad y luz APDS-9930
El APDS-9930 es un sensor diminuto (3.94 x 2.36 x 1.35 mm) para detección de proximidad y medición digital de luz ambiental. La imagen a continuación muestra el frente y la parte trasera del chip APDS-9930.

El sensor mide la proximidad de un objeto enviando un pulso IR a través del LED IR integrado y midiendo la intensidad de la luz reflejada. La luz ambiental se detecta mediante dos fotodiodos. Un fotodiodo detecta luz visible más infrarroja (Ch0) y el otro solo infrarroja (Ch1). Un microprocesador integrado combina ambas señales para calcular un nivel de luz ambiental (ALS) que aproxima la respuesta del ojo humano. Mira la imagen a continuación con el diagrama funcional del APDS-9930:

El APDS-9930 también permite configurar umbrales superiores e inferiores para los valores de luz y proximidad, y envía una señal de interrupción (INT) si se superan esos umbrales. Para comunicación y programación, el APDS-9930 ofrece una interfaz I2C (SCL, SDA)
La siguiente lista resume las principales características del APDS-9930:
- Medición de luz ambiental (ALS)
- Respuesta visual aproximada al ojo humano
- Capacidad de interrupción programable con umbrales superiores e inferiores
- Resolución de hasta 16 bits
- Alta sensibilidad operando detrás de vidrio oscuro
- Rendimiento de bajo lumen de 0.1 lux
- Detección de proximidad
- Calibrado completamente para detección a 100 mm
- LED infrarrojo integrado y controlador síncrono de LED
- Elimina la calibración de fábrica del sensor de proximidad
- Temporizador de espera programable
- Consumo en estado de espera – típico 90μA
- Rango programable desde 2.7 ms hasta más de 8 segundos
- Interfaz compatible con I2C
- Hasta 400kHz (modo rápido I2C)
- Pin de interrupción dedicado
- Consumo en modo suspensión – típico 2.2μA
Para información más detallada, consulta la hoja de datos enlazada a continuación:
Placa breakout para APDS-9930
El chip APDS-9930 es demasiado pequeño para conectarlo directamente a un Arduino. Normalmente necesitarás una placa breakout como la que se muestra a continuación:

Las placas breakout para el APDS-9930 suelen tener seis pines:
- VCC: Alimentación (2.4 – 3.6V)
- GND: Tierra
- VL: Alimentación del LED IR
- SDA: Señal de datos I2C
- SCL: Señal de reloj I2C
- INT: Pin de interrupción
En la mayoría de los casos solo necesitarás los pines de alimentación (VCC, GND) y los pines para comunicación I2C (SCL, SDA). El pin INT se activa si la luz ambiental o la proximidad superan los umbrales programables.
VL te permite suministrar alimentación externa al LED IR. En la parte trasera de la placa breakout hay un puente de soldadura que debes cerrar si quieres usar VL para alimentar el LED IR.
Ten en cuenta que el APDS-9930 funciona a 3.3V y que la mayoría de las placas breakout no tienen regulador de voltaje. Esto significa que debes conectar VCC a 3.3V y no puedes usar la salida de 5V de un Arduino.
Conectando el APDS-9930 al Arduino
Gracias a la interfaz I2C del APDS-9930, conectarlo a un Arduino es sencillo. Primero conecta el pin SCL de la placa breakout APDS-9930 al pin A5 del Arduino. De igual forma, conecta SDA al pin A4 del Arduino. Luego conecta tierra a GND y 3.3V a VCC del APDS-9930.

Asegúrate de usar 3.3V como fuente de alimentación. El sensor APDS-9930 no está diseñado para 5V y las placas breakout típicas no tienen regulador de voltaje.
Instalar la biblioteca APDS-9930
Antes de usar el APDS-9930 necesitamos instalar una biblioteca. La única que encontré es la APDS-9930 Library de Depau, que ya no se mantiene pero sigue funcionando bien. Para instalarla, ve a repo y haz clic en el botón verde «Code». Luego haz clic en «Download Zip» como se muestra a continuación:

Después ve a «Sketch» -> «Include Library» -> «Add .Zip Library..» y selecciona el archivo «APDS9930-master.zip» que acabas de descargar:

Alternativamente, puedes descargar todo el código del repositorio, comprimirlo y luego incluir la biblioteca de la misma forma descrita arriba. Ahora estamos listos para escribir código.
Medir luz ambiental con APDS-9930
El siguiente código lee las mediciones de luz ambiental del sensor APDS-9930.
#include "Wire.h"
#include "APDS9930.h"
APDS9930 sensor = APDS9930();
void setup() {
Serial.begin(9600);
sensor.init();
sensor.enableLightSensor(false);
delay(500);
}
void loop() {
static float light = 0;
if (sensor.readAmbientLightLux(light)) {
Serial.print("light:");
Serial.println(light);
}
delay(500);
}
Comenzamos incluyendo las bibliotecas necesarias y creando el objeto sensor. En la función setup el sensor se inicializa y se activa el sensor de luz.
El false en enableLightSensor(false) significa que no usamos interrupciones al medir la luz ambiental. Puedes conectar la salida INT del APDS-9930 a una entrada digital del Arduino y activar una rutina de servicio de interrupción (ISR) cuando se detecte un cierto nivel de luz. El APDS-9930 tiene example code para esto.
En la función loop leemos el nivel de luz vía readAmbientLightLux(light) y si es exitoso lo imprimimos en el Monitor Serial. Mira los siguientes ejemplos de lectura:

Y si abres el Serial Plotter y apuntas el APDS-9930 a una fuente de luz, por ejemplo una lámpara de escritorio en este caso, deberías ver un pico en el gráfico:

Medir proximidad con APDS-9930
El APDS-9930 detecta la proximidad de un objeto enviando un pulso IR desde el LED IR interno y midiendo la cantidad de energía IR reflejada. Cuanto más cerca esté el objeto, más energía se refleja.
El código para medir proximidad es muy similar al código para medir luz ambiental. Las únicas dos diferencias son que llamamos a enableProximitySensor(false) en la función setup y a readProximity(proximity) en la función loop. Mira el ejemplo a continuación:
#include "Wire.h"
#include "APDS9930.h"
APDS9930 sensor = APDS9930();
void setup() {
Serial.begin(9600);
sensor.init();
sensor.enableProximitySensor(false);
delay(500);
}
void loop() {
static uint16_t proximity = 0;
if (sensor.readProximity(proximity)) {
Serial.print("proximity:");
Serial.println(proximity);
}
delay(500);
}
Como antes, el false en enableProximitySensor(false) significa que no usamos interrupciones sino que leemos continuamente los valores de proximidad. Los valores típicos de proximidad varían entre aproximadamente 300 (sin objeto) y 1023 cuando el objeto está muy cerca.
Si abres el Serial Plotter y acercas o alejas repetidamente tu mano del sensor, deberías ver un patrón ondulado similar al que se muestra a continuación:

Medir proximidad y luz con APDS-9930
Finalmente, obviamente podemos medir la proximidad y los niveles de luz ambiental al mismo tiempo. El ejemplo de código a continuación activa el sensor de proximidad y el de luz en la función setup y lee los valores de proximidad y luz en la función loop:
#include "Wire.h"
#include "APDS9930.h"
APDS9930 sensor = APDS9930();
void setup() {
Serial.begin(9600);
sensor.init();
sensor.enableProximitySensor(false);
sensor.enableLightSensor(false);
}
void loop() {
static uint16_t proximity = 0;
static float light = 0;
if (sensor.readProximity(proximity)) {
Serial.print("proximity:");
Serial.println(proximity);
}
if (sensor.readAmbientLightLux(light)) {
Serial.print("light:");
Serial.println(light);
}
delay(500);
}
Si ejecutas este código y miras el Serial Plotter, notarás que el sensor de luz y el de proximidad muestran un comportamiento correlacionado negativamente. Mira la imagen a continuación.

Esto es porque, si acercas la mano al sensor, el valor de proximidad es alto pero como la mano bloquea la luz ambiental, el nivel de luz medido es bajo. Inversamente, si no hay objeto cerca del sensor, el valor de proximidad es bajo, pero el nivel de luz es mayor (asumiendo que haya luz).
Ajuste automático de brillo con APDS-9930
Para nuestro ejemplo final, implementemos la aplicación típica del APDS-9930. Activamos un LED si un objeto (mano) está cerca del sensor y ajustamos el brillo del LED según los niveles de luz ambiental.
Para eso solo necesitamos añadir un LED a nuestro circuito. En el cableado mostrado abajo añadí un LED con una resistencia de 220Ω al pin 11. Puedes usar otro pin de salida, pero debe ser un pin PWM.

En el código a continuación, leemos los valores de proximidad y luz. Si el umbral de proximidad supera 500 (mano cerca del sensor), ajustamos el brillo del LED relativo al nivel de luz ambiental. Cuanta más luz ambiental, más brillante el LED.
#include "Wire.h"
#include "APDS9930.h"
APDS9930 sensor = APDS9930();
const int ledPin = 11; // PWM
void setup() {
Serial.begin(9600);
sensor.init();
sensor.enableProximitySensor(false);
sensor.enableLightSensor(false);
pinMode(ledPin, OUTPUT);
delay(500);
}
void loop() {
static uint16_t proximity = 0;
static float light = 0;
static float maxLight = 0;
sensor.readProximity(proximity);
sensor.readAmbientLightLux(light);
if (proximity > 500) {
maxLight = max(light, maxLight);
int brightness = map(light, 0, maxLight, 0, 1023);
analogWrite(ledPin, brightness);
} else {
analogWrite(ledPin, 0);
}
delay(100);
}
Como no sabemos de antemano cuán brillante puede ser la luz ambiental, el código también actualiza el nivel máximo de luz ambiental en cada iteración. Pero también podrías hacer pruebas y elegir un nivel máximo fijo.
Y eso es todo. Espero que te hayas divertido jugando con el sensor de proximidad y luz APDS-9930 – yo ciertamente sí ; )
Conclusiones
En este tutorial aprendiste a usar el sensor de proximidad y luz APDS-9930 con un Arduino para detectar objetos y medir niveles de luz ambiental.
Ten en cuenta que la APDS-9930 Library de Depau tiene más funciones que las que demostramos aquí. Específicamente, puedes leer los valores de los dos fotodiodos (Ch0, Ch1), configurar umbrales para proximidad y niveles de luz, y reaccionar a interrupciones. Echa un vistazo al ejemplo code que viene con la biblioteca.
El APDS-9930 es un buen sensor para detectar gestos simples y reaccionar a la luz. Por ejemplo, si quieres activar una pantalla al pasar la mano frente a ella y también ajustar el brillo de la pantalla según la luz ambiental al mismo tiempo, el APDS-9930 es ideal para eso.
Sin embargo, si quieres medir distancias a objetos con precisión, por ejemplo para aplicaciones robóticas, es mejor usar sensores de distancia infrarrojos como el GP2Y0A710K0F que usan triangulación para determinar la distancia a un objeto. O mejor aún, elige un sensor láser de distancia Time-of-Flight (ToF) como el TOF10120 o el VL53L1X library, que pueden medir distancias largas con gran precisión.
Si tienes alguna pregunta, no dudes en dejarla en la sección de comentarios.
¡Feliz bricolaje ; )

