Control stuff using your hands with the APDS-9960

//Control stuff using your hands with the APDS-9960

Control stuff using only our hands with the APDS-9960 – In this case a Stepper Motor!


Sometime you buy stuff and forget about it!  This is the case when it comes to this little module.

The APDS-9960 is like 3 modules in one.  It support color recognition, proximity and gesture detection.

In this tutorial we will concentrate on the Gesture engine.

It can detect 6 gestures: LEFT, RIGHT, UP, DOWN, FAR and NEAR

We will use it to control the speed and direction of a NEMA 17 stepper motor.

‘Far’ gesture will start the rotation, ‘Left’ and ‘Right’ the direction, ‘Up’ and ‘Down’ the speed, and ‘Near’ gesture will stop the rotation.

One thing I found out from my testing, is that the module must be perpendicular (90 degrees) as much as possible from your hand to detect the correct gesture.

Also using a piece of white paper instead of your hand results in better detection, so that is what I’m using in the tutorial video.

The module range of detection is about 4 to 8 inches.


The APDS-9960 module is rated for 3.3V, not just for the input voltage but for the control lines as well.

This is why we are using an I2C Logic Level converter to go from 5V to 3.3V from the MEGA2560 to the module.

The connections are as follow:

5V and GND of the MEGA2560 are going to HV and GND of the Level Converter

the LV and GND of the level converter are going to the VCC and GND of the APDS-9960.

Pin 20 (SDA) and 21 (SCL) are connected to the Level Converter and the corresponding pins opposite on the Level Converter are connected to the APDS-9960.

Pin 2 of the MEGA2560 is connected directly to the interrupt pin of the APDS-9960, no need to go through the Level Converter for this one, since the current for the interrupt only flows one way and the MEGA2560 can sense the 3.3V to trigger the interrupt.

For the Easy Driver we are connecting pin 5 and 6 to the STEP and DIR pin.

We also connect GND from the MEGA2560 to the Easy Driver for reference.


The code uses the AccelStepper library and a library specially made for this module.  (Check below for download links)


There is a problem with the APDS-9960 library if you’re using something other than an Arduino UNO, that makes the gesture engine not register any values.

To fix this problem you need to edit the library file () and find this line:

if( !setLedBoost (LED_BOOST_300) ) }

and change the value of 300 to 100 like this:

if( !setLedBoost (LED_BOOST_100) ) }

After that change the Arduino MEGA2560 started to work.  My suggestion is to try it out without modification, and if it doesn’t work, than go ahead and make the change.

I go over this in the tutorial video below if you want more information.


When the APDS-9960 detects something blocking the IR emitter, it will trigger an interrupt then wait to read the gesture.  When the gesture is read we then check to see which one and control the stepper motor in accordance.

We keep track of the speed and direction of the stepper, so that we can adjust properly depending on the gesture.

Up and Down gesture control the speed of the stepper in 200 (or -200) increments without going over 1000 (or under -1000).  Left and Right gestures control the direction.  Far and Near Start and Stop the rotation of the stepper motor.

As always for more information about the tutorial and explanation of the code please watch our tutorial video.

/* Arduino Gesture Control Stepper Motor 
 * Using The ADPS-9960 RGB and Gesture Sensor Module
Created by Yvan /

This code is in the public domain...

You can: copy it, use it, modify it, share it or just plain ignore it!


#include <Wire.h>
#include <SparkFun_APDS9960.h> 
// Library created by Sparkfun at:

#include "AccelStepper.h"
// Library created by Mike McCauley at

// AccelStepper Setup
AccelStepper stepper(1, 5, 6);  
// 1 = Easy Driver interface
// MEGA Pin 5 connected to STEP pin of Easy Driver
// MEGA Pin 6 connected to DIR pin of Easy Driver

#define gesture_interrupt 2 
// Using interrupt zero (Pin 2 on Mega2560)

// Init of module 
SparkFun_APDS9960 apds9960 = SparkFun_APDS9960();

volatile int interrupt_flag = 0; 
// To keep track of triggering of interrupt
int step_direction = 0; 
// to keep track of stepper motor rotation zero for left - one for right
int step_speed = 0;
// to keep track of stepper motor current speed

void setup() {
  stepper.setMaxSpeed(1000); // Set max speed of stepper
  stepper.setSpeed(step_speed);  // Set stepper speed to zero at startup

  pinMode(gesture_interrupt, INPUT); // Set interrupt pin as input

  // Initialize Serial port
  // Initialize interrupt service routine
  attachInterrupt(0, interruptRoutine, FALLING);

  // Init the APDS-9960
  if ( apds9960.init() ) {  // If init is good
    Serial.println("Found APDS-9960 Module!");
  } else { // if not
    Serial.println("Can't find APDS-9960 Module...");
  // Activate the gesture sensor
  if ( apds9960.enableGestureSensor(true) ) { // if init is good
    Serial.println("Gesture sensor is enabled!");
  } else { // if not
    Serial.println("Can't start the Gesture sensor...");

void loop() {

  if( interrupt_flag == 1 ) {  // equals 1 if gesture detected
    detachInterrupt(0);        // Stop listening for interrupt
    handleGesture();           // grab gesture
    interrupt_flag = 0;        // reset interrupt flag to zero
    attachInterrupt(0, interruptRoutine, FALLING);  // Start listening again
    stepper.runSpeed(); // Move Stepper motor

void interruptRoutine() {
  interrupt_flag = 1;  
  // Change flag to 1 to indicated a gesture was detected

void handleGesture() {  // Check which kind of gesture was detected
    if ( apds9960.isGestureAvailable() ) {
    // Make sure a gesture was recorded
    switch ( apds9960.readGesture() ) {
    // Read the gesture
      case DIR_UP:  // UP gesture detected
        Serial.print("SPEED UP: ");
        if (step_direction == 0) { // Stepper current direction is LEFT
          if (step_speed <= 700) { // check so speed doesn't go over 1000
        } else {   // Stepper current direction is RIGHT 
          if (step_speed >= -700) {
      case DIR_DOWN:  // DOWN gesture detected
        Serial.print("SPEED DOWN: ");
        if (step_direction == 0) {  // Stepper current direction is LEFT
          if (step_speed >= 300) { // check so speed doesn't go under zero
        } else {  // Stepper current direction is RIGHT
          if (step_speed <= -300) {
      case DIR_LEFT:  // LEFT gesture detected
        Serial.println("ROTATION LEFT");
        if (step_direction == 1 && (step_speed > 0 || step_speed < 0))  {  
        // If current direction is Right and Speed not zero
        stepper.setSpeed(abs(step_speed)); // Reverse stepper direction
        step_direction=0; // Set direction to Left
        step_speed=abs(step_speed);  // make speed a positive number
      case DIR_RIGHT:  // RIGHT gesture detected
        Serial.println("ROTATION RIGHT");
        if (step_direction == 0 && (step_speed > 0 || step_speed < 0)) {  
        // If current direction is Left and Speed not zero
        stepper.setSpeed(-1*step_speed); // Reverse stepper direction
        step_speed=-1*step_speed; // Make speed a minus number
        step_direction=1; // Set direction to Right
      case DIR_NEAR:  // NEAR gesture detected
        stepper.setSpeed(0); // Stop Stepper rotation
        step_speed=0; // Set speed to zero
      case DIR_FAR:  // FAR gesture detected
        Serial.print("Current Speed: ");
        stepper.setSpeed(500); // Start Stepper rotation
        step_speed=500;  // Set speed to 500 

Copy the above Sketch code you want to use above in your Arduino IDE software to program your Arduino.

To download the APDS-9960 Library created by Sparkfun:

To download the AccelStepper library created by Mike McCauley:

By | 2018-02-23T18:43:14+00:00 January 15th, 2018|Tutorials|

Leave A Comment