APDS-9960 Gesture Sensor with Arduino
The APDS-9960 gesture sensor allows for the detection of hand gestures such as swipes and proximity. In this tutorial, we will demonstrate how to connect the APDS-9960 to an Arduino and program it to recognize gestures. The outcome will be a simple setup that can detect movements and report them via the serial monitor. This guide will help you understand the wiring and code needed to get started with the gesture sensor. (in video at 00:30)
Hardware Explained
The APDS-9960 is a versatile sensor that combines RGB color sensing, ambient light sensing, proximity sensing, and gesture detection capabilities. It communicates with the Arduino via I2C, which allows for easy integration with minimal wiring. The sensor only operates at 3.3V, making it essential to ensure proper voltage levels to avoid damaging the device. In this build, we will use the Arduino to read gesture data. The sensor outputs gesture information through interrupts, which allows the Arduino to respond promptly to hand movements. The integration of the APDS-9960 with the Arduino opens up many possibilities for interactive projects, including gesture-controlled devices.Datasheet Details
| Manufacturer | Broadcom |
|---|---|
| Part number | APDS-9960 |
| Logic/IO voltage | 2.7 - 3.6 V |
| Supply voltage | 3.3 V |
| Output current (per channel) | 1 mA |
| Peak current (per channel) | 10 mA |
| PWM frequency guidance | 100 Hz |
| Input logic thresholds | 0.3 x VDD (low), 0.7 x VDD (high) |
| Voltage drop / RDS(on) / saturation | 0.5 V max |
| Thermal limits | -40 to +85 °C |
| Package | 6-pin LGA |
| Notes / variants | Supports I2C communication |
- Ensure the supply voltage does not exceed 3.6 V to prevent damage.
- Use pull-up resistors on the I2C lines for reliable communication.
- Keep the sensor away from direct sunlight for accurate readings.
- Make sure to initialize the sensor correctly in the code.
- Check the wiring connections to avoid floating inputs.
Wiring Instructions

Code Examples & Walkthrough
The provided code initializes the APDS-9960 sensor and sets up the Arduino to read gestures. Here is a brief excerpt of the setup function:void setup() {
pinMode(APDS9960_INT, INPUT);
Serial.begin(9600);
attachInterrupt(0, interruptRoutine, FALLING);
if ( apds.init() ) {
Serial.println(F("APDS-9960 initialization complete"));
}
}
In this snippet, we initialize the serial monitor and set the interrupt pin. The sensor is initialized, and a confirmation message is printed to the console.
Next, we check for gestures in the loop function:
void loop() {
if( isr_flag == 1 ) {
detachInterrupt(0);
handleGesture();
isr_flag = 0;
attachInterrupt(0, interruptRoutine, FALLING);
}
}
Here, the loop continuously checks for gestures. When a gesture is detected, the interrupt is disabled, and the `handleGesture` function is called to process the gesture.
Finally, the `handleGesture` function processes the detected gestures:
void handleGesture() {
if ( apds.isGestureAvailable() ) {
switch ( apds.readGesture() ) {
case DIR_UP:
Serial.println("UP");
break;
case DIR_DOWN:
Serial.println("DOWN");
break;
// Additional cases...
}
}
}
In this function, the gesture is read, and the corresponding action is taken based on the detected direction. This allows for interactive control based on hand movements.
For a complete understanding of the code, please refer to the full program loaded below the article.
Demonstration / What to Expect
When the setup is complete, you can expect the Arduino to read gestures and display the detected direction on the serial monitor. Simple tests include moving your hand up, down, left, or right in front of the sensor. If everything is wired correctly, you should see the corresponding output on the serial monitor, confirming the gesture recognition. Be cautious of floating inputs, as they can lead to inconsistent readings (in video at 05:20).Video Timestamps
- 00:00 - Introduction
- 01:15 - Hardware Overview
- 03:00 - Wiring Instructions
- 04:30 - Code Walkthrough
- 06:15 - Demonstration

1-Code for an APDS-9960 gesture sensor for Arduino
Language: C++
/*
* Code for APDS-9960 Gesture sensor for Arduino
* This code is to detect gestures of your hand, either moving it up, down, left, or right; other gestures.
* can be detected and used to control something else.
* Watch the APDS-9960 Gesture sensor video https://youtu.be/qzSgZV_fbxI
* Get this code from https://robojax.com
* Code used in video by Ahmad Shamshiri for Robojax.com
* on December 31, 2016, at 6:53 AM in Ajax, Ontario, Canada
* Permission granted to share this code, given that this
* note is kept with the code.
* Disclaimer: this code is "AS IS" and for educational purposes only.
GestureTest.ino
APDS-9960 RGB and Gesture Sensor
Shawn Hymel @ SparkFun Electronics
May 30, 2014
https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor
Tests the gesture sensing abilities of the APDS-9960. Configures
APDS-9960 over I2C and waits for gesture events. Calculates the
direction of the swipe (up, down, left, right) and displays it
on a serial console.
To perform a NEAR gesture, hold your hand
far above the sensor and move it close to the sensor (within 2
inches). Hold your hand there for at least 1 second and then move it
away.
To perform a FAR gesture, hold your hand within 2 inches of the
sensor for at least 1 second and then move it away (out of
range) of the sensor.
Hardware Connections:
IMPORTANT: The APDS-9960 can only accept 3.3V!
Arduino Pin APDS-9960 Board Function
3.3V VCC Power
GND GND Ground
A4 SDA I2C Data
A5 SCL I2C Clock
2 INT Interrupt
Resources:
Include Wire.h and SparkFun_APDS-9960.h
Development environment specifics:
Written in Arduino 1.0.5
Tested with SparkFun Arduino Pro Mini 3.3V
This code is beerware; if you see me (or any other SparkFun
employee) at the local, and you've found our code helpful, please
buy us a round!
Distributed as-is; no warranty is given.
***************************************************************
*/
#include <Wire.h>
#include <SparkFun_APDS9960.h>
Servo myservo; // create servo object to control a servo
// Pins
#define APDS9960_INT 2 // Needs to be an interrupt pin
// Constants
// Global Variables
SparkFun_APDS9960 apds = SparkFun_APDS9960();
int isr_flag = 0;
void setup() {
// Set interrupt pin as input
pinMode(APDS9960_INT, INPUT);
// Initialize Serial port
Serial.begin(9600);
Serial.println();
Serial.println(F("--------------------------------"));
Serial.println(F("SparkFun APDS-9960 - GestureTest"));
Serial.println(F("--------------------------------"));
// Initialize interrupt service routine
attachInterrupt(0, interruptRoutine, FALLING);
// Initialize APDS-9960 (configure I2C and initial values)
if ( apds.init() ) {
Serial.println(F("APDS-9960 initialization complete"));
} else {
Serial.println(F("Something went wrong during APDS-9960 init!"));
}
// Start running the APDS-9960 gesture sensor engine
if ( apds.enableGestureSensor(true) ) {
Serial.println(F("Gesture sensor is now running"));
} else {
Serial.println(F("Something went wrong during gesture sensor init!"));
}
}
void loop() {
if( isr_flag == 1 ) {
detachInterrupt(0);
handleGesture();
isr_flag = 0;
attachInterrupt(0, interruptRoutine, FALLING);
}
}
void interruptRoutine() {
isr_flag = 1;
}
void handleGesture() {
if ( apds.isGestureAvailable() ) {
switch ( apds.readGesture() ) {
case DIR_UP:
Serial.println("UP");
break;
case DIR_DOWN:
Serial.println("DOWN");
break;
case DIR_LEFT:
Serial.println("LEFT");
break;
case DIR_RIGHT:
Serial.println("RIGHT");
break;
case DIR_NEAR:
Serial.println("NEAR");
break;
case DIR_FAR:
Serial.println("FAR");
break;
default:
Serial.println("NONE");
}
}
}
2-Source code for controlling a servo with your hand
Language: C++
/****************************************************************
Modified for RoboJax by A.B.S. on May 09, 2017
in Ajax, Ontario, Canada. www.RoboJax.com
Original Source:
APDS-9960 RGB and Gesture Sensor
Shawn Hymel @ SparkFun Electronics
May 30, 2014
https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor
Distributed as-is; no warranty is given.
****************************************************************/
#include <Wire.h>
// added by RoboJax
#include <Servo.h>
#include <SparkFun_APDS9960.h>
Servo myservo; // create servo object to control a servo // added by RoboJax
// Pins
#define APDS9960_INT 2 // Needs to be an interrupt pin
// Constants
// Global Variables
SparkFun_APDS9960 apds = SparkFun_APDS9960();
int isr_flag = 0;
void setup() {
myservo.attach(9); // attaches the servo on pin 9 to the servo object
// Set interrupt pin as input
pinMode(APDS9960_INT, INPUT);
// Initialize Serial port
Serial.begin(9600);
Serial.println();
Serial.println(F("--------------------------------"));
Serial.println(F("SparkFun APDS-9960 - GestureTest"));
Serial.println(F("--------------------------------"));
// Initialize interrupt service routine
attachInterrupt(0, interruptRoutine, FALLING);
// Initialize APDS-9960 (configure I2C and initial values)
if ( apds.init() ) {
Serial.println(F("APDS-9960 initialization complete"));
} else {
Serial.println(F("Something went wrong during APDS-9960 init!"));
}
// Start running the APDS-9960 gesture sensor engine
if ( apds.enableGestureSensor(true) ) {
Serial.println(F("Gesture sensor is now running"));
} else {
Serial.println(F("Something went wrong during gesture sensor init!"));
}
}
void loop() {
if( isr_flag == 1 ) {
detachInterrupt(0);
handleGesture();
isr_flag = 0;
attachInterrupt(0, interruptRoutine, FALLING);
}
}
void interruptRoutine() {
isr_flag = 1;
}
void handleGesture() {
if ( apds.isGestureAvailable() ) {
switch ( apds.readGesture() ) {
case DIR_UP:
Serial.println("UP");
break;
case DIR_DOWN:
Serial.println("DOWN");
break;
case DIR_LEFT:
Serial.println("LEFT");
myservo.write(180); // added by RoboJax
break;
case DIR_RIGHT:
Serial.println("RIGHT");
myservo.write(0); // added by RoboJax
break;
case DIR_NEAR:
Serial.println("NEAR");
break;
case DIR_FAR:
Serial.println("FAR");
break;
default:
Serial.println("NONE");
}
}
}
Resources & references
No resources yet.