How to Use APDS9960 RGB Infrared Gesture Sensor with Arduino.

APDS9960 RGB Gesture and Proximity sensor with Arduino

The APDS9960 sensor is a multifunction sensor widely used in smart phones to provide a number of functions. The first use is recognition of swiping gestures as up, down, left or right depending on the movement of a user’s finger over the screen.

This sensor also provides proximity sensing which is used to detect when the phone is placed near the ear thereby disabling the touchscreen while attending to a call. The ambient light and RGB color detection feature is used to adjust the brightness and color balance of the phone’s backlight depending on lighting conditions.

In this tutorial I’ll demonstrate how the APDS9960 RGB Infrared Gesture sensor is used with Arduino.

APDS9960 sensor hardware overview.

This sensor comes attached to a breadboard friendly breakout board with other electronics components like the one shown below.

APDS9960 RGB Infrared Gesture sensor

There are six header pin connections namely;

  • VL –   This an optional power supply for the IR LED. It is used when the PS jumper is removed and should have a voltage of 3.0 – 4.5V DC.
  • GND – Connection to ground of a microcontroller.
  • VCC – Power supply connected to 3.3V of the microcontroller.
  • SDA – I2C Data line. 
  • SCL – I2C Clock line. 
  • INT – Interrupt output active LOW.  Output is open-collector so requires pull-up resistor and is connected to an interrupt input of a microcontroller when used.

The breakout board also has two solder jumper pads.

  • PS – This solder jumper comes closed by default and is used to connect the power supplies of the sensor and IR LED together therefore you only need to supply power to the VCC pin. However, if the jumper is open, you have to provide separate power supplies for VCC (2.4 – 3.6V) and VL (3.0 – 4.5V). 
  • I2C PU – This is a 3-way solder jumper used to connect the I2C 10K pull-up resistors to the SDA and SCL line on the board circuits.  The jumper is also closed by default but in case you want to use external pull-up resistors then you can open it.

How the APDS9960 sensor works.

The APDS9960 sensor is used for detection of gestures, sensing proximity and detection of color and ambient light intensity. This sensor has four photodiodes and an IR LED arranged as illustrated below.

APDS9960 Gesture sensor photodiodes and IR LED arrangement

Gesture Detection

APDS9960 Gesture detection is made possible using the four photodiodes that reflect IR radiation from the built-in IR LED.  These photodiodes are placed in such a way that an object moving from one direction to the opposite side will first approach one photodiode and then the other. The direction of movement of the object is determined by which photodiode the object first passes.

The reflected IR by the photodiodes is converted to signals that are translated into basic up, down, left and right movements or gestures. Gesture detection works best when the object passes within a distance of 1 to 2 inches from the sensor.

Proximity Sensor

The proximity sensor uses reflected IR to determine the relative distance to an object.  Both the IR transmitter LED and photodiode detectors are located in the small black package.  It has a maximum detection range of about 6″ depending on the surface and a minimum range of about 1″

With no object detected, the sensor will report 255 or something close to that reading.  When an object is detected, the reading will approach 0 as the object moves closer and will read 0 at about 1″ distance from the sensor.

Color and Ambient Light Sensor

The color and ambient light sensing functionality uses an array of red / green / blue / clear filtered photodiodes with IR filters over them to minimize the impact of IR light.  The measurement data is provided as 16-bit results.

Connecting APDS9960 Gesture sensor to Arduino.

Since the APDS9960 RGB gesture and proximity sensor uses I2C communication, the SCL and SDA pins will be connected to the corresponding I2C pins of Arduino which are pins A5 and A4 respectively for Arduino UNO.

The operating voltage for this sensor is 3.3V therefore, VCC will be connected to 3.3V and GND to GND of Arduino.

The interrupt pin (INT) of APDS9960 is connected to an interrupt pin of Arduino like Pin 2.

Arduino UNO has two interrupt pins, that is, digital pins 2 and 3 given as INT.0 and INT.1 respectively.

Schematic for APDS9960 Gesture sensor with Arduino and 16X2 I2C LCD

I have also included a 16×2 I2C LCD for displaying the gesture detected by the APDS9960 sensor.

Code for controlling APDS9960 RGG Infrared Gesture sensor using Arduino.

There are a number of libraries that have been developed to work with this sensor but the most common ones are from Arduino, Adafruit and Sparkfun. All of these libraries come with several example programs demonstrating the working of the main features of this sensor. I have used the SparkFun_APDS996.h library from Sparkfun.

The code below is for testing gesture detection of the APDS9960 sensor with Arduino.

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include <SparkFun_APDS9960.h>

LiquidCrystal_I2C lcd(0x27, 16, 2); 

#define APDS9960_INT    2 
SparkFun_APDS9960 apds = SparkFun_APDS9960();
int isr_flag = 0;

void setup() {
  pinMode(APDS9960_INT, INPUT);  
  attachInterrupt(0, interruptRoutine, FALLING); 
  apds.init();   
  apds.enableGestureSensor(true);  
  lcd.begin();
  lcd.backlight();
}

void loop() {
  lcd.setCursor(0, 0);
  lcd.print("Gesture ");
  if( isr_flag == 1 ) {
    detachInterrupt(0);
    lcd.setCursor(5, 1);
    handleGesture();
    isr_flag = 0;
    attachInterrupt(0, interruptRoutine, FALLING);
  }
}

void interruptRoutine() {
  isr_flag = 1;
}

void handleGesture() {
    
    if ( apds.isGestureAvailable() ) {
    switch ( apds.readGesture() ) {
      case DIR_UP:
        lcd.print("UP");
        delay (1000);
        lcd.clear();
        break;
      case DIR_DOWN:
        lcd.print("DOWN");
        delay (1000);
        lcd.clear();
        break;
      case DIR_LEFT:
        lcd.print("LEFT");
        delay (1000);
        lcd.clear();
        break;
      case DIR_RIGHT:
        lcd.print("RIGHT");
        delay (1000);
        lcd.clear();
        break;
      case DIR_NEAR:
        lcd.print("NEAR");
        delay (1000);
        lcd.clear();
        break;
      case DIR_FAR:
        lcd.print("FAR");
        delay (1000);
        lcd.clear();
        break;
      default:
        lcd.print("NONE");
    }
  }
}

Code Description

First, you need to include header files which are LiquidCrystal_I2C.h for controlling the I2C  LCD, Wire.h is used for I2C communication and SparkFun_APDS9960.h is for the APDS9960 sensor.

Then define a macro for the interrupt pin which is connected on digital pin 2 and isr_flag for the interrupt service routine.

Next an object is created for the SparkFun_APDS9960, so that we can access the gesture movements and fetch the RGB values.

In setup function, we set the interrupt pin as input and use the attachInterrupt() to initialize the interrupt service routine. The apds.init() method is used to initialize the APDS9960 sensor and the lcd.begin() initializes the LCD.

In the loop() section, we first check the isr_flag and if it is 1 then the detachInterrupt() method is called to turn off the interrupt.  Then we call the handleGesture() function and finally set isr_flag to zero and attach the interrupt.

The attachInterrupt() is a function used for external interrupt which in this case is sensor’s interrupt. The first argument in this function is interrupt number which is 0 since we have used pin 2. The second argument calls the interruptRoutine() method which is defined later on and the last argument is FALLING edge trigger  for the interrupt when the pin goes from high to low.

The interruptRoutine() function is used to turn the isr_flag variable 1, so that the interrupt service can be initialized.

The handleGesture() function first checks for the availability of gesture sensor using isGestureAvailable() method and then the readGesture() method reads the gesture values and checks which gesture it and displays the corresponding values to LCD as is UP, DOWN, RIGHT, LEFT, FAR, NEAR.  

I have mainly dealt with gesture detection since it is the major feature of the APDS9960 sensor. However, you can also try out other example programs for proximity and color detection using the SparkFun_APDS996.h library.

SparkFun-APDS9960 RGB and Gesture Sensor library examples

The APDS9960 sensor is not ideal for use in projects involving majorly proximity detection or color sensing. In such a situation then it is better to use more specific sensors like TC3200 color sensor.

I have tutorials about color sensing and proximity detection using TCS3200 color sensor and HC-SR04 ultrasonic sensor which you can also check out for further reference.