How to use APDS-9930 Proximity and Light Sensor with Arduino

The APDS-9930 is a multifunction sensor that integrates ambient light sensing and proximity detection into a small package. It is applied extensively in use cases such as automatic screen brightness control and touchless interaction systems. In this tutorial, you will learn how to interface the APDS-9930 with an Arduino to sense light intensity and detect objects in close proximity through I2C communication. No matter whether you are a beginner or a seasoned maker, this guide will guide you through step-by-step using real-life examples and simple code snippets. Let’s get started!

Required Materials

ComponentQuantity
APDS-9930 Sensor1
Arduino Uno1
USB Data Sync Cable1
Dupont Wire Set1 Set
Breadboard1

Working of APDS-9930 Proximity and Light Sensor

The APDS-9930 is a single-module combines ambient light and proximity sensing, using an integrated infrared LED and photodiodes to detect nearby objects and sense light levels. It communicates with microcontrollers using an I2C interface and is easily integrated into a number of applications, including touchless controls and display brightness adjustments. It has automatic gain control and interrupt for power-efficient operation, but it could be sensitive to external IR sources, impacting accuracy.

The APDS-9930 is a small digital ambient light and proximity sensor. It emits an infrared pulse and senses back reflection intensity to accomplish its goals. It has two infrared photodiodes for infrared and visible sensing, thus simulating the response of an eye.

Main Features:

1. Approximate human visual response
2. Programmable interrupt facility with upper and lower levels
3. At maximum 16-bit resolution
4. High sensitivity operation behind dark glass
5. 0.01 lux low lumen performance
6. Proximity detection
7. Fully calibrated to 100 mm detection
8. Integrated infrared LED and driver for synchronous LEDs
9. Eliminates factory calibration of proximity sensor
10. Programmable wait timer (2.7 ms to more than 8 seconds)
11. I2C interface of up to 400kHz
12. Special interrupt pin
13. Low power consumption: 90μA (wait state), 2.2μA (sleep mode)
14. Breakout Board for APDS-9930
15. The APDS-9930 chip is smaller than can be directly plugged into an Arduino, so a breakout board is needed.

    Pinout:

    VCC: DC power supply (2.4 – 3.6V)

    GND: Ground

    VL: IR LED power

    SDA: I2C data signal

    SCL: I2C clock signal

    INT: Interrupt pin

    All projects make use of VCC, GND, SDA, and SCL. The INT pin provides an interrupt when programmed values are reached. When powering the IR LED using VL, a solder jumper on the board needs to be bridged. The APDS-9930 is 3.3V only compatible and does not contain an onboard voltage regulator and thus cannot be powered with 5V, which will destroy the sensor.

    Connecting the APDS-9930 to Arduino

    With I2C, we can easily get the APDS-9930 connected to an Arduino:

    SCL → A5

    SDA to A4

    GND → GND

    VCC to 3.3V

    Installing APDS-9930 Library: Prior to coding, install the APDS-9930 Library by Depau (not maintained anymore, but works). Download the library as a ZIP file and then include it through 

    Sketch → Include Library → Add.ZIP Library.

    Ambient Light sensing with APDS-9930


    The code below reads ambient light intensities:

    #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);
    }
    

    Measuring Proximity with APDS-9930

    APDS-9930 sends out IR light and returns the reflected energy. This reads proximity values: 

    #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);
    }
    

    Measuring Proximity and Light Simultaneously

    This code enables both sensors:

    #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);
    }
    

    Measuring Proximity and Light Simultaneously

    This code will allow both sensors:

    #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);
    }
    

    Automatic Brightness Adjustment with APDS-9930

    This usage example uses an LED to dynamically adjust brightness relative to light:

    #include "Wire.h"
    #include "APDS9930.h"
    
    APDS9930 sensor = APDS9930();
    const int ledPin = 11;  // PWM pin
    
    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);
    }
    

    Conclusion:

    The APDS-9930 sensor is a capacitive sensor enabling proximity detection as well as light measurement in an ambient environment. With Arduino integration, you’re able to do projects that have dynamic responses in their surroundings based on the needs of the context, like controlling brightness automatically or gesture control. Its small design and low current consumption make it suitable for several applications, such as mobile, smart home control, and automation. Whether you require general light detection or more sophisticated proximity sensing, APDS-9930 delivers the solution in both reliability and effectiveness.

    Leave a Comment