Using the APDS-9960 RGB, Proximity, and Gesture Sensor with the Raspberry Pi

I’m always excited to get my hands on new sensors, so when I saw the APDS-9960 RGB and gesture sensor breakout board from SparkFun I ordered one immediately. The neat thing about this sensor is that it does a lot for its tiny size and relatively low cost.

The features this sensor offers are:

  • Proximity measurement
  • Ambient light intensity measurement
  • Color detection
  • Simple gesture detection including left, right, up, down, foward, and back
  • More complex gestures are apparently possible, although I haven’t seen evidence of this yet

SparkFun offers an Arduino library for the sensor, but no other platforms are supported yet. I really wanted to use the sensor with the Raspberry Pi so I quickly ported it. The connections I’m using are:

I put the code up on BitBucket at https://bitbucket.org/justin_woodman/apds-9960-raspberry-pi-library. You can clone the repository using:

git clone https://bitbucket.org/justin_woodman/apds-9960-raspberry-pi-library.git

In order to get it working you’ll need to install wiringPi for I2C and interrupt support. Just follow the installation instruction at the wiringPi website.

Once you have wiringPi installed you can build any of the examples. So the GestureTest example can be built using the compile string:

g++ -Wall -o GestureTest GestureTest.cpp APDS9960_RPi.cpp -lwiringPi

It’ll be easier to write makefiles for larger projects so you don’t have to keep doing that, but for testing it’s fine. Before you run the program you’ll need to set up I2C and the interrupt with:

gpio load i2c
and
gpio edge 7 falling

You might get a warning with the i2c load, which you can safely ignore. Run the program with:

sudo ./GestureTest

And wave your hand over the sensor to see what it does. Neat right?? I’ll be digging further into this code to see if I can get more complex gesture sensing to work if someone doesn’t beat me to it. Have fun!

Posted on November 15, 2014, in Electronics, Programming and tagged , , , , . Bookmark the permalink. 23 Comments.

  1. g++ -Wall -o GestureTest GestureTest.cpp SparkFun_APDS9960.cpp -lwiringPi
    SparkFun_APDS9960.cpp:19:22: fatal error: Arduino.h: No such file or directory
    I need Arduino library ?

    • Hello Francis, thanks for pointing out my mistake. The compile string you should use is “g++ -Wall -o GestureTest GestureTest.cpp APDS9960_RPi.cpp -lwiringPi”. I’ve updated the post as well. Make sure you grab the right library from the bitbucket link above.

  2. Hello Justin
    Thank you for this great post.
    I tried to use it with http://www.dx.com/p/apds-9960-rgb-gesture-sensor-board-module-w-i2c-interface-purple-384037#.VW9Wrc_tlBc what is should be equal with the Sparkfun one.

    With a fresh Rasbian install i enabled i2c, i2cdetect -y 1 works well, i see the device at 39.
    When i try the gesture sensing i get only:

    ————————————
    SparkFun APDS-9960 – GestureTest
    ————————————
    Something went wrong during APDS-9960 init!
    Gesture sensor is now running

    Sensing won’t work.

    But the color sensing seems to work (with a weird green value):
    Ambient: 14 Red: 1 Green: 1023 Blue: 0

    Can you help me please?

    • Hi Bela, sorry you’re having trouble. The only major difference I see between the DX and Sparkfun modules is that the VL jumper on the back of the DX one is left open. This is the LED power jumper, so most of the functions won’t work if yours looks like this: http://img.dxcdn.com/productimages/sku_384037_2.jpg
      All you should need to do is either bridge those two pads with solder, or connect the VCC and VL pins together.

  3. Thank you for your answer.
    Yes, i use it with bridged pins + i realized that SCL and SDA is switched.
    Still no luck, when i run gpio load i2c i get

    gpio: Warning (not an error): File not present: /dev/i2c-0

  4. Did you use a B+ or a Raspberry 2 board?

  5. Yes, the ambient light reading change when i move my hand over it.
    I am testing with B+ also.

  6. I teseted with a Raspberry 2 board. It’s the same without any modification. The ambient light still works:

    ————————————
    SparkFun APDS-9960 – ColorSensor
    ————————————
    Something went wrong during APDS-9960 init!
    Light sensor is now running

    Ambient: 264 Red: 80 Green: 1023 Blue: 0
    Ambient: 237 Red: 72 Green: 1023 Blue: 0
    Ambient: 264 Red: 68 Green: 1023 Blue: 0
    Ambient: 4 Red: 0 Green: 1023 Blue: 0
    Ambient: 247 Red: 63 Green: 1023 Blue: 0
    Ambient: 177 Red: 46 Green: 1023 Blue: 0
    Ambient: 159 Red: 42 Green: 1023 Blue: 0
    Ambient: 148 Red: 39 Green: 1023 Blue: 0
    Ambient: 132 Red: 34 Green: 1023 Blue: 0
    Ambient: 117 Red: 30 Green: 1023 Blue: 0
    Ambient: 63 Red: 17 Green: 1023 Blue: 0
    Ambient: 60 Red: 16 Green: 1023 Blue: 0
    Ambient: 21 Red: 6 Green: 1023 Blue: 0
    Ambient: 260 Red: 67 Green: 1023 Blue: 0
    Ambient: 259 Red: 67 Green: 1023 Blue: 0
    Ambient: 261 Red: 67 Green: 1023 Blue: 0

    • It looks like you’re getting real data from the sensor, so your hookup is probably okay. How long are your signal wires? Are you running the program with sudo? You might want to put some print statements in “APDS9960_RPi::init()” within “APDS9960_RPi.cpp” to see exactly where it’s returning false. I’m guessing it’s line 58, line 63, or line 66 so you could put the prints just before the return statements to figure out which one it is.

  7. Thank you again for your informations.

    I ordered one piece from Sparkfun and everything works.
    So, this is why the DX pieces did not work, they are different, i can’t find that difference,

    Thank you again

  8. Hello Bela,
    I also bought several “APDS-9960” from DX. But in reality, they are APDS-9930 devices.
    Those are older devices without RGB or Gesture Sensing capabilities.
    I’m sure about it. When I read Device ID register, I get 0x39 (yes, same that i2c address).
    You can check APDS-9930 device datasheet here:
    _http://www.avagotech.com/docs/AV02-3190EN

    I’m trying to recover my money!
    best regards

  9. Hi Bela,
    I’m a newbie of raspberry. Now I’m making a project with this sensor. Thanks for your codes and tutorial. It can runs well on my raspberry Pi now. Since I don’t understand the code very much. I want to ask how to call and use your cpp library / functions in python ? I searched a lot on web, most of them said extending the python with cpp. It seems quite complicate. Are there have any other method that can let me call the library via python? I just wanna to catch the values of the gesture senses (e.g. right, left, etc…) and call other function program by python. Thanks a lot and hope you can help me!

    Best regards.

  10. Justin, thanks for the tut and code–it works great on a Pi2!
    Question: I want to use the sensor to add gesture control to a slideshow. I just need to modify your code to issue , , etc. keystrokes when the corresponding gesture is detected. I have experience coding in Python, but not C++. Can you tell me what function/method I should use to pass a keystroke to another process (the picture viewer program)?

    Thanks!

  11. For the benefit of others who want to use the APDS-9960 as a control for a Pi-based media center, below is a Bash script I wrote that translates output from Justin’s GestureTest program to XBMC/Kodi commands. I use it with OSMC on a Pi2 and launch it on boot by putting this into /etc/rc.local:
    sleep 15
    sudo /home/osmc/scripts/GestureCommands.sh

    Here’s the code for GestureCommands.sh
    ———————————————————-
    #! /bin/bash

    # Description: Converts output of the GestureTest program to xbmc-send actions for OSMC
    # Description: By W. Wayt Gibbs. With thanks to Justin Woodman and DBMandrake at the OSMC forum.

    ROOT_UID=0 # Only users with $UID 0 have root privileges.
    E_NOTROOT=67 # Non-root exit error.

    xbmc-send –action=”RecursiveSlideShow(/home/osmc/Pictures/Art)”

    if [ “$UID” -ne “$ROOT_UID” ]
    then
    echo “Must be root to run this script.”
    exit $E_NOTROOT
    fi

    /home/osmc/scripts/GestureTest | {
    while read command
    do
    echo $command

    case “$command” in
    UP ) action=BACK;;
    DOWN ) action=SELECT;;
    LEFT ) action=LEFT;;
    RIGHT ) action=RIGHT;;
    FAR ) action=”RecursiveSlideShow(/home/osmc/Pictures/Art)”;;
    NEAR ) action=SHUTDOWN;;
    NONE ) action=”Notification(‘Sorry!’,’Unrecognized gesture’,1000)”;;
    * ) action=NULL;;
    esac

    # the mpg321 commands in the section below are optional; they play either a confirmation sound or an alert sound, depending on whether a valid gesture was recognized

    if [ “$action” != NULL ]
    then
    if [ “$command” = NONE ]
    then
    mpg321 /home/osmc/Music/input_failed_clean.mp3 >/dev/null 2>&1
    else
    mpg321 /home/osmc/Music/ds9intercom.mp3 >/dev/null 2>&1
    fi
    xbmc-send –action=”$action”
    fi
    done
    } &

    exit 0

  12. Thank you for the code.
    Just for helping anyone… While(1) loop eats the entire cpu load (100%, even more). I put usleep(2000); to solve this issue.
    so, change to this:
    while(1)
    {
    if(blabla){

    }
    usleep(2000);
    }
    this works for me!!

  1. Pingback: Sparkfun RGB and Gesture Sensor Breakout Board | paulcreaser

  2. Pingback: how to Raspberry Pi using APDS-9960 Gesture Sensor its c++ library in python - BlogoSfera

  3. Pingback: Build the Ultimate Digital Picture Frame | Top in Earth

  4. Pingback: Build the Ultimate Digital Picture Frame | photo frame

  5. Pingback: Build the Ultimate Digital Picture Frame | Robots Everywhere 機械人科技資訊分享

Leave a reply to justinwoodman Cancel reply