Neste tutorial, vais aprender a usar o sensor de proximidade e luz APDS-9930 com um Arduino ou qualquer outro microcontrolador comum (ESP32/ESP8266).
O APDS-9930 é um sensor muito pequeno, frequentemente usado em smartphones e tablets para ajuste automático do brilho do ecrã e deteção de proximidade durante chamadas. Também podes usá-lo como um detector simples de gestos que ativa luzes ou outros dispositivos ao acenar com a mão à sua frente.
Peças Necessárias
Para este projeto vais precisar de um sensor APDS-9930 e um microcontrolador. Usei um Arduino Uno, mas qualquer outro Arduino ou ESP32/ESP8266 também funciona, desde que forneça uma saída de alimentação de 3.3V.

Sensor APDS-9930

Arduino Uno

Cabo USB para Arduino UNO

Conjunto de fios Dupont

Breadboard
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 do Sensor de Proximidade e Luz APDS-9930
O APDS-9930 é um sensor minúsculo (3.94 x 2.36 x 1.35mm) para deteção de proximidade e medição digital de luz ambiente. A imagem abaixo mostra a parte frontal e traseira do chip APDS-9930.

O sensor mede a proximidade de um objeto enviando um pulso IR através do LED IR integrado e medindo a intensidade da luz refletida. A luz ambiente é detetada por dois fotodíodos. Um fotodíodo deteta luz visível mais infravermelha (Ch0) e o outro apenas infravermelha (Ch1). Um microprocessador integrado combina os dois sinais para calcular um nível de luz ambiente (ALS) que aproxima a resposta do olho humano. Vê a imagem abaixo com o Diagrama Funcional do APDS-9930:

O APDS-9930 também permite definir limites superiores e inferiores para os valores de luz e proximidade, enviando um sinal de interrupção (INT) se esses limites forem ultrapassados. Para comunicação e programação, o APDS-9930 fornece uma interface I2C (SCL, SDA)
A lista seguinte resume as principais características do APDS-9930:
- Medição de Luz Ambiente (ALS)
- Resposta aproximada ao olho humano
- Capacidade de interrupção programável com limites superiores e inferiores
- Resolução até 16 bits
- Operação de alta sensibilidade atrás de vidro escuro
- Desempenho de baixa luminosidade a 0,1 lux
- Deteção de proximidade
- Totalmente calibrado para deteção até 100 mm
- LED infravermelho integrado e controlador síncrono do LED
- Elimina a calibração de fábrica do sensor de proximidade
- Temporizador de espera programável
- Consumo de energia em estado de espera – 90μA típico
- Intervalo programável de 2,7 ms a mais de 8 segundos
- Interface compatível com I2C
- Até 400kHz (modo rápido I2C)
- Pino de interrupção dedicado
- Consumo em modo de suspensão – 2,2μA típico
Para informações mais detalhadas, consulta o datasheet ligado abaixo:
Placa breakout para APDS-9930
O chip APDS-9930 é demasiado pequeno para ligar diretamente a um Arduino. Normalmente, precisas de uma placa breakout como a mostrada abaixo:

As placas breakout para o APDS-9930 geralmente têm seis pinos:
- VCC: Alimentação (2.4 – 3.6V)
- GND: Terra
- VL: Alimentação do LED IR
- SDA: Sinal de dados I2C
- SCL: Sinal de relógio I2C
- INT: Pino de interrupção
Na maioria dos casos, só precisas dos pinos de alimentação (VCC, GND) e dos pinos para comunicação I2C (SCL, SDA). O pino INT fica ativo se a luz ambiente ou a proximidade ultrapassarem os limites programáveis.
O pino VL permite fornecer alimentação externa ao LED IR. No verso da placa breakout há um jumper de solda que precisas de fechar se quiseres usar o VL para alimentar o LED IR.
Note que o APDS-9930 funciona a 3.3V e que a maioria das placas breakout normalmente não tem regulador de tensão. Isto significa que deves ligar o VCC a 3.3V e não podes usar a saída de 5V do Arduino!
Ligação do APDS-9930 ao Arduino
Graças à interface I2C do APDS-9930, ligá-lo ao Arduino é fácil. Primeiro, liga o pino SCL da placa breakout do APDS-9930 ao A5 do Arduino. De forma semelhante, liga o SDA ao A4 do Arduino. Depois, liga o terra ao GND e os 3.3V ao VCC do APDS-9930.

Assegura-te de usar 3.3V como fonte de alimentação. O sensor APDS-9930 não é indicado para 5V e as placas breakout típicas para o APDS-9930 não têm regulador de tensão.
Instalar a Biblioteca APDS-9930
Antes de usarmos o APDS-9930, precisamos instalar uma biblioteca. A única biblioteca que encontrei é a APDS-9930 Library de Depau, que já não é mantida mas ainda funciona bem. Para a instalar, vai a repo e clica no botão verde “Code”. Depois clica em “Download Zip” como mostrado abaixo:

Depois vai a “Sketch” -> “Include Library” -> “Add .Zip Library..” e seleciona o ficheiro “APDS9930-master.zip” que acabaste de descarregar:

Alternativamente, podes descarregar todo o código do repositório, compactá-lo e depois incluir a biblioteca da mesma forma descrita acima. Agora estamos prontos para escrever algum código.
Medir Luz Ambiente com APDS-9930
O código seguinte lê as medições de luz ambiente do 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);
}
Começamos por incluir as bibliotecas necessárias e criar o objeto do sensor. Na função setup o sensor é inicializado e o sensor de luz ativado.
O false em enableLightSensor(false) significa que não estamos a usar interrupções ao medir a luz ambiente. Podes ligar a saída INT do APDS-9930 a uma entrada digital do Arduino e ativar uma rotina de serviço de interrupção (ISR) quando um certo nível de luz for detetado. O APDS-9930 tem example code para isso.
Na função loop lemos o nível de luz via readAmbientLightLux(light) e, se for bem-sucedido, imprimimos no Monitor Serial. Vê os exemplos de leituras a seguir:

E se abrires o Serial Plotter e apontares o APDS-9930 para uma fonte de luz, por exemplo uma lâmpada de secretária neste caso, deverás ver um pico no gráfico:

Medir Proximidade com APDS-9930
O APDS-9930 deteta a proximidade de um objeto enviando um pulso IR do LED IR interno e medindo a quantidade de energia IR refletida. Quanto mais próximo o objeto, mais energia é refletida.
O código para medir proximidade é muito semelhante ao código para medir luz ambiente. As únicas duas diferenças são que chamamos enableProximitySensor(false), na função setup e readProximity(proximity) na função loop. Vê o exemplo abaixo:
#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, o false em enableProximitySensor(false) significa que não estamos a usar interrupções, mas a ler continuamente os valores de proximidade. Os valores típicos de proximidade variam entre cerca de 300 (sem objeto) e 1023 quando o objeto está muito próximo.
Se abrires o Serial Plotter e colocares a mão repetidamente mais perto ou mais longe do sensor, deverás ver um padrão ondulado semelhante ao mostrado abaixo:

Medir Proximidade e Luz com APDS-9930
Finalmente, obviamente podemos medir proximidade e níveis de luz ambiente ao mesmo tempo. O exemplo de código abaixo ativa o sensor de proximidade e o sensor de luz na função setup e lê os valores de proximidade e os níveis de luz na função 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);
}
Se executares este código e vires o Serial Plotter, vais notar que o sensor de luz e o sensor de proximidade mostram um comportamento negativamente correlacionado. Vê a imagem abaixo.

Isto acontece porque, se aproximares a mão do sensor, o valor de proximidade é alto, mas como a mão bloqueia a luz ambiente, o nível de luz medido é baixo. Inversamente, se não houver objeto perto do sensor, o valor de proximidade é baixo, mas o nível de luz é mais alto (assumindo que há alguma luz).
Ajuste automático de brilho com APDS-9930
Para o nosso exemplo final, vamos implementar a aplicação típica do APDS-9930. Ativamos um LED se um objeto (mão) estiver perto do sensor e ajustamos o brilho do LED de acordo com os níveis de luz ambiente.
Para isso, só precisamos de adicionar um LED ao nosso circuito. Na ligação mostrada abaixo, adicionei um LED com um resistor de 220Ω ao pino 11. Podes usar outro pino de saída, mas tem de ser um pino PWM.

No código abaixo, lemos os valores de proximidade e luz. Se o limite de proximidade ultrapassar 500 (mão perto do sensor), definimos o brilho do LED em relação ao nível de luz ambiente. Quanto mais luz ambiente, mais brilhante o 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 não sabemos antecipadamente quão brilhante pode ser a luz ambiente, o código também atualiza o nível máximo de luz ambiente em cada iteração. Mas também podes fazer alguns testes e escolher um nível máximo fixo de luz.
E é isso. Espero que te tenhas divertido a brincar com o sensor de proximidade e luz APDS-9930 – eu certamente me diverti ; )
Conclusões
Neste tutorial aprendeste a usar o sensor de proximidade e luz APDS-9930 com um Arduino para detetar objetos e medir níveis de luz ambiente.
Note que a APDS-9930 Library de Depau tem mais funções do que as que demonstrámos aqui. Especificamente, podes ler os valores dos dois fotodíodos (Ch0, Ch1), definir limites para proximidade e níveis de luz, e reagir a interrupções. Dá uma vista de olhos ao exemplo code que vem com a biblioteca.
O APDS-9930 é um bom sensor para detetar gestos simples e reagir à luz. Por exemplo, se quiseres ativar um ecrã ao acenar com a mão à sua frente e também ajustar o brilho do ecrã consoante a luz ambiente ao mesmo tempo, o APDS-9930 é ótimo para isso.
No entanto, se quiseres medir distâncias a objetos com precisão, por exemplo para aplicações robóticas, é melhor usares sensores de distância infravermelhos como o GP2Y0A710K0F que usam triangulação para determinar a distância a um objeto. Ou ainda melhor, escolhe um sensor de distância a laser Time-of-Flight (ToF) como o TOF10120 ou o VL53L1X library, que podem medir distâncias longas com grande precisão.
Se tiveres alguma dúvida, não hesites em deixar nos comentários.
Boas experiências ; )

