Quickly Design Your Own Low-Cost 3D Gesture Controller

By Jacob Beningo

Contributed By Digi-Key's North American Editors

Knobs, buttons, levers, and touchscreens are typically how humans interact with machines and embedded devices. However, recent improvements in sensor technology are now opening the path for developers to add three-dimensional (3D) gesture control to their products.

Depending on the technology used, purchasing and integrating a gesture controller can be expensive. However, there are a wide variety of gesture sensor technologies available, ranging from inexpensive sensors that use infrared LEDs and photodiodes to detect movement to expensive gesture recognition cameras. Infrared gesture sensors are inexpensive, can be digitally interfaced to a low-cost microcontroller, and with a little bit of software can be sufficiently accurate for many applications.

This article explores gesture control using the Broadcom APDS-9960, an infrared (IR) gesture control sensor that can be easily integrated into nearly any embedded system.

IR-based gesture sensors

The theory behind IR-based gesture sensors is relatively simple. When detecting a hand gesture, there are several different gestures that developers might want to detect:

  • Up/down
  • Left/right
  • Forward/backwards

In each of these cases, the sensor needs to be able to detect the direction of movement. This is done by using two main components in the sensor: a light-emitting diode (LED) and multiple directional photodiodes. Directional photodiodes are nothing more than at least four photodiodes that are positioned at a predefined distance from the IR LED. For example, the Broadcom APDS-9960 ambient light, proximity, and gesture sensor positions its photodiodes in a diamond pattern with each diode having a directional specifier such as up, down, left, and right (Figure 1).

Diagram of Broadcom APDS-9960Figure 1: The Broadcom APDS-9960 has an integrated IR LED and four directional photodiodes that detect reflected IR energy that can be analyzed for a gesture profile. (Image source: Broadcom)

When the LED transmits infrared energy, the energy will be emitted into empty space unless there is an object, such as a hand, there to reflect it.  The reflected energy will be detected by the photodiodes at different intensities depending on where the object is positioned. For example, a photodiode along the leading edge of the gesture will initially receive less reflected energy than a photodiode at the trailing edge, resulting in one photodiode having a higher count value than the other. Taking measurements over time as the gesture is made will result in the photodiodes detecting different reflected intensities at the different diodes. This stream of directional information can then be analyzed to determine the gesture.

For example, if a user were to swipe their hand from the top of the sensor to the bottom, at the start of the gesture the down photodiode would detect a larger incident reflected light than the up photodiode. As the gesture takes place, the hand moves to a point where both diodes receive an equal amount of energy. As the gesture completes, the down photodiode will receive less reflected light and the up photodiode will receive more, inverting the curve and the phase for the photodiodes (Figure 2).

Graph of Broadcom APDS-9960 photodiode curvesFigure 2: A downward gesture motion across the Broadcom APDS-9960 generates these photodiode curves where the leading curve indicates the gesture direction. (Image source: Broadcom)

With an understanding of how the data is generated for a gesture, the next step is to look at how to interface to the APDS-9960.

Interfacing to the Broadcom APDS-9960 gesture controller

The APDS-9960 comes in an eight-pin surface mount (SMD-8) package which takes up minimal pc board space (Figure 3). The sensor measures only 3.94 × 2.36 × 1.35 millimeters (mm). The package contains the normal power and ground pins along with an I2C interface for a digital connection to a microcontroller and pins for customizing the LED drive circuits. The package also contains an interrupt pin to notify the microcontroller when there is gesture data available for processing.

Image of Broadcom APDS-9960 in a compact surface mount SMD-8 packageFigure 3: The APDS-9960 comes in a compact surface mount SMD-8 package that minimizes board space. (Image source: Broadcom)

There are several different options available for building a prototype and interfacing to the APDS-9960. For example, the SparkFun APDS-9960 evaluation board provides a relatively small breakout board that includes LED drive circuits, making it ready to use out of the box (Figure 4). All a developer needs to do is solder a header in place to jumper power and ground, wire up the I2C bus and optional interrupt pin to a microcontroller, and they can start developing their embedded software. The SparkFun board also includes mounting holes so that it can be dropped into a design if using an existing board makes sense for the application.

Image of SparkFun APDS-9960 evaluation boardFigure 4: The SparkFun APDS-9960 evaluation board has all the on-board circuitry necessary to get started with gesture control. (Image source: Digi-Key Electronics)

Alternatively, developers can also use the Adafruit APDS-9960 breakout board which is another all-in-one solution (Figure 5). The Adafruit breakout board is interesting because it is not only small, but it also contains an on-board 3 volt regulator that can be used to power additional circuitry such as a power LED or even a low-power microcontroller. On top of that, Adafruit provides developers with an entire Adafruit APDS9960 breakout user guide, along with several software libraries for connecting to Arduino boards or development boards that run Python. This makes using the APDS-9960 a great out of the box experience and can dramatically decrease the amount of time a developer spends getting started with the sensor.

Image of Adafruit APDS-9960 breakout boardFigure 5: The Adafruit APDS-9960 breakout board includes the APDS-9960 along with an on-board 3 volt regulator and I2C voltage translation circuits to support 3 volt or 5 volt buses. (Image source: Digi-Key Electronics)

The easiest way to interface either of these breakout boards is to solder Molex 22-28-4255 breakaway headers to the boards. This is best done with the headers facing down to provide several advantages. First, it allows the board to be plugged into a breadboard like the Digilent 340-002-1 solderless breadboard kit (Figure 6). Second, it keeps the top surface of the board clear, providing plenty of room for a hand to make gestures without accidentally catching wires hanging off the headers.

Image of Adafruit APDS-9960 breakout boardFigure 6: The Adafruit APDS-9960 breakout board soldered and prepared on a Digilent Solderless Breadboard. (Image source: Adafruit)

At this point, power and ground need to be wired, and the I2C lines need to be wired to the desired microcontroller development board. Any development board with a microcontroller on it can be used. However, a good choice is STMicroelectronicsB-L475E-IOT01A2 STM32L475 IoT Discovery Kit for IoT Node (Figure 7). This development board has Arduino headers and is also supported by MicroPython, which can be programmed on the board with minimal effort. Once that is done, Python scripts can be used to interface with the gesture sensor, further making gesture control not just feasible, but nearly trivial.

Image of STMicroelectronics STM32L475 Discovery Kit for IoT NodeFigure 7: The STM32L475 Discovery Kit for IoT Node includes Arduino headers that can be easily interfaced to the APDS-9960 breakout boards. (Image source: STMicroelectronics)

Detecting gestures using Python

Obtaining gesture data from the APDS-9960 is not complicated, but it does require a developer to read through the datasheet carefully. The APDS-9960 has several different capabilities that include the following:

  • Gesture sensing
  • Ambient light sensing
  • RGB color sensing
  • Proximity sensing

These are all controlled through a state machine that executes based on how the registers are set up for the application. For example, a great technique to prevent the gesture engine from executing all the time is to use the proximity sensing engine to detect when a hand is present. Once the reflected IR energy reaches a preset count, the proximity engine state will transition to the gesture engine, which will measure the directional photodiodes and place the measured value into a first-in, first-out (FIFO) buffer. In order to enable this capability, the control register needs to be set to enable proximity, and a count threshold needs to be set.

Depending on the gestures needed by the application, a developer may need to write algorithms to detect specific gestures. However, for common gestures such as up/down and left/right, developers can leverage the Adafruit APDS-9960 CircuitPython library. After the library is copied to the Python device, it can be imported using the code shown in Listing 1. This code imports the APDS-9960 library along with several libraries that support the I2C bus.

import board 
import busio 
import adafruit_apds9960.apds9960 
i2c = busio.I2C(board.SCL, board.SDA) 
sensor = adafruit_apds9960.apds9960.APDS9960(i2c)

Listing 1: The CircuitPython imports and library initialization code to interface with the APDS-9960 gesture controller. (Image source: Adafruit)

The sensor object is an instance of the APDS-9960 library. We will see in just a moment that it is very easy to use. In order to enable gestures, a developer only needs to enable the gesture feature using the following code:

sensor.enable_gesture = True
The main program loop setup to read the gesture is itself just a few lines of code (Listing 2).
gesture = sensor.gesture()
while gesture == 0:
gesture = sensor.gesture()
print('Saw gesture: {0}'.format(gesture))

Listing 2: Detecting a gesture is as simple as making the call to a single library method repeatedly. (Image source: Adafruit)

As you’ll notice from reading this code, if a gesture is seen, the gesture detected will be printed to the screen (Figure 8).

Image of example gesture output result from the Adafruit APDS-9960 CircuitPython libraryFigure 8: Example gesture output result from the Adafruit APDS-9960 CircuitPython library. (Image source: Adafruit)

The gesture output is given by a number, which can be easily converted using the following key:

0 = No gesture detected

1 = Up gesture detected

2 = Down gesture detected

3 = Left gesture detected

4 = Right gesture detected

As shown, leveraging a pre-existing library can make basic gesture recognition easy using just a few lines of code. More complex gestures would require modifying the library to analyze the raw gesture data.

Tips and tricks for creating a gesture controller

Building and integrating a gesture control sensor in a product isn’t without a few challenges. Here are a number of “tips and tricks” that developers need to consider when working with infrared-based gesture controllers:

  • Use the gesture sensor’s internal proximity detector to trigger the gesture control engine in order to minimize invalid gesture starts.
  • Start with an existing gesture library and build additional gestures on top of the capabilities that already exist.
  • Adjust the gain on the photodiodes to values that best fit the end gesture application.
  • Adjust the LED output drive intensity to values that best fit the application. This may require some tweaking in order to get repeatable results.
  • A developer should start any gesture application development with high level software development until they understand the sensor and then move to lower level code.

Following these tips will help ensure that developers minimize the time that they spend getting an IR gesture controller up and running.


There is a steady push to start interacting with machines in a more natural and intuitive way, and one leading option is to use gesture control technology. While there are many different types of gesture control technologies, the lowest cost and easiest to work with is an infrared-based gesture sensor. As shown, integrating a gesture sensor with a microcontroller doesn’t need to be a time-consuming activity provided developers leverage existing hardware and software technologies.

Disclaimer: The opinions, beliefs, and viewpoints expressed by the various authors and/or forum participants on this website do not necessarily reflect the opinions, beliefs, and viewpoints of Digi-Key Electronics or official policies of Digi-Key Electronics.

About this author

Jacob Beningo

Jacob Beningo is an embedded software consultant. He has published more than 200 articles on embedded software development techniques, is a sought-after speaker and technical trainer, and holds three degrees, including a Masters of Engineering from the University of Michigan.

About this publisher

Digi-Key's North American Editors