Finger tracking LED light up using Processing — Arduino — Leap

Diego Zaks
Visual Lab
Published in
6 min readApr 22, 2016

This was a short project intended to get started with working with an Arduino controller that I did a while back (2013… how time flies). The main goal is setting up communication between a Processing sketch and a real-world physical device. I thought I’d document and share the process and the code (probably still works).

The idea is very simple, track a finger to light an LED from a strip, if the finger moves, the LED changes.It might not sound like much but it does require a few pieces of equipment.

  1. LEAP Motion Controller
  2. Processing 2.0.3 with Leap Motion Library
  3. Arduino Uno Controller
  4. Breadboard
  5. LEDs
  6. Cables
  7. Resistors

The Wiring

Wiring is very straightforward, using Pins 8 through 13 on the Arduino Uno as OUTPUT.

The code:

Before getting into the code specifics, I find it helpful to describe what we want to achieve in “pseudo-code” to determine a logic that will optimize the coding.

  1. Track finger’s position along the X axis using the LEAP.
  2. Map the position to one of 5 LEDs on the Arduino.
  3. Light one LED at a time.

There’s two pieces of code for this setup, the first is the Processing Sketch. This sketch is in charge of processing the input from the LEAP and mapping it to the X axis, sending a signal via Serial (USB) to the Arduino. I used Processing 2.0.3 and the latest iteration of the LeapMotion library at the time of posting.

Processing v0.1

My first version of the code did what I wanted but it wasn’t the best solution, I will explain later on why it wasn’t suited for my needs. I’ll share it anyway since it was a learning experience.

// An array of LEDs lit up by LEAP motion on an ARDUINO
// by Diego Zaks
// LEAP libraries
import de.voidplus.leapmotion.*;
LeapMotion leap;
// Serial Port Output
import processing.serial.*; // Serial libraries, send OUTPUT through USB
Serial myPort;

Importing the needed processing libraries and creating the objects for the Serial port and the Leap.

void setup() {
size(800, 500, P3D);
background(255);
noStroke();
fill(50);
// New serial port object
myPort = new Serial(this, Serial.list()[4], 9600);
// New leap object
leap = new LeapMotion(this);
}

A standard setup for a processing sketch, there are the two objects we are creating.

void draw() {
background(255);
// Leap magic
int fps = leap.getFrameRate();

This is a standard method from the LEAP library, below is the LEAP code that detects hands and finger tips.

// Clean LEAP Hand position
for (Hand hand : leap.getHands()) {
hand.draw();
PVector hand_position = hand.getPosition();
println(“Hand on X: ” + hand.getPosition().x );

Here is the mapping of the hand’s position to a series of 5 integers

// Determine ledPin according to mapped hand x positionint ledPin = (int) map(constrain(hand.getPosition().x, -100, 800), 0, 700, 9, 13);println(“Pin: ” + ledPin);

And finally the command to write and send the current mapped value down the Serial port to the Arduino.

myPort.write(ledPin); // Send ledPin number through port
}
}
void leapOnInit() {
// println(“Leap Motion Init”);
}
void leapOnConnect() {
// println(“Leap Motion Connect”);
}
void leapOnFrame() {
// println(“Leap Motion Frame”);
}
void leapOnDisconnect() {
// println(“Leap Motion Disconnect”);
}
void leapOnExit() {
// println(“Leap Motion Exit”);}

Arduino v0.1

On the Arduino side, things look much simpler.

// Arduino sketch turn LED on via serial input from Processing// Define main variables
int ledPin;
int currentRead;
// activate the pins I want to use on my board
int myPins[5] = {9, 10, 11, 12, 13};

Array of the 5 pins we want to use, replace any number but you’ll need to match them on the Arduino.

void setup() {
// Activate all Digital pins on my board
for (int i = 0; i < 5; i++) {
pinMode(myPins[i], OUTPUT);
}
Serial.begin(9600);
}

Set up our pins as OUTPUT using a simple for loop and begin reading from the Serial.

void loop() {
// Compare read from Serial to current pin
currentRead = Serial.read();
digitalWrite(ledPin, HIGH);
if(ledPin != currentRead) { // If serial is different from current pin then turn it off and turn on the new one
digitalWrite(ledPin, LOW);
}
ledPin = currentRead;
}

Now, this seems like it’d work, what happens? why isn’t this good enough?

Well, in theory it’s a working sketch of what I need, but in reality it’s overwhelmingly wasting resources. Processing is running at 30fps, which means it’s sending a signal through the Serial port 30 times every second.

The Arduino on the other hand, with such a simple code should be running at over 100,000fps, reading the Serial constantly, checking to see if the values are different and resetting the ledPin variable every frame. This caused uncontrolled flickering light on the LED and a very low brightness. Imagine, it’s turning itself on and off 100,000 times a second (in theory).

I had to rewrite the code so that it is more efficient and “to the point”. So it looks like this:

Processing v0.2

// An array of LEDs lit up by LEAP motion on an ARDUINO// LEAP libraries
import de.voidplus.leapmotion.*;
LeapMotion leap;
// Serial Port Output
import processing.serial.*; // Serial libraries, send OUTPUT through USB
Serial myPort;
int ledPin;
int checkPin;
void setup() {
size(800, 500, P3D);
background(255);
noStroke();
fill(50);
// New port object
myPort = new Serial(this, Serial.list()[4], 9600);
// New leap object
leap = new LeapMotion(this);
}
void draw() {
background(255);
// Leap magic
int fps = leap.getFrameRate();
// Clean LEAP Hand position
for (Hand hand : leap.getHands()) {
hand.draw();
PVector hand_position = hand.getPosition();
// println(“Hand on X: ” + hand.getPosition().x );

Same variables, objects, setup and LEAP methods. The change is below.

// Determine ledPin according to mapped hand x positioncheckPin = (int) map(hand.getPosition().x, 0, 700, 8, 14);
if (ledPin != checkPin) {
assignPin();
}
// Send ledPin number through port}
}

This is where the code gets different, the check now happens on the processing side. When the current mapped finger’s value changes, then, and only then will it redefine the ledPin variable and write it out an instruction through the Serial port.

void assignPin() {
ledPin = checkPin;
myPort.write(ledPin);
println(“Serial Output: ” + ledPin);
}

The new assignPin() void, only called when the value of the ledPin and checkPin are different writes the Serial Command to the Arduino.

void leapOnInit() {
// println(“Leap Motion Init”);
}
void leapOnConnect() {
// println(“Leap Motion Connect”);
}
void leapOnFrame() {
// println(“Leap Motion Frame”);
}
void leapOnDisconnect() {
// println(“Leap Motion Disconnect”);
}
void leapOnExit() {
// println(“Leap Motion Exit”);
}

The Leap functions are the same.

Arduino v0.2

The Arduino code went through a few changes to reflect the new logic.

// Arduino sketch turn LED on via serial input from Processing// Define main variables
int ledPin = 0;
int currentRead;
// Slowing down the process
//unsigned long millisCounter = 0;
//int interval = 10;
// activate the pins I want to use on my board
int myPins[5] = {
9, 10, 11, 12, 13};
void setup() {
// Activate all Digital pins on my board
for (int i = 0; i < 5; i++) {
pinMode(myPins[i], OUTPUT);
}
Serial.begin(9600);
}

The above didn’t change. It all happened in the loop().

void loop() {if (Serial.available()) {
currentRead = Serial.read();
if(currentRead != ledPin) {
digitalWrite(ledPin, LOW);
ledPin = currentRead;
digitalWrite(ledPin, HIGH);
}
}
}

Now the Arduino checks the Serial port (100,000 times/sec) and only if there is input will it execute the command. There is another check to see if the incoming input matched the current LED. Same as in Processing. This significantly reduced the load on the Arduino and the LED shines bright.

That’s it.

Note: I’m starting a series of Medium articles in this vein, documenting the things I make. Teaching is the best way to start a conversation, and hopefully my writing can help artists and designers can get started with code and physical computing. If you’re interested in Technology in the arts then I’d love to hear from you.

--

--

Diego Zaks
Visual Lab

New York City based Branding Consultant, Freelance Designer & Digital Artist.