Servo Control

When I started playing with Leap control of the Arduino, the first thing I tried was servo control. I was using an example of computer control of a servo that I found online, but was having a lot of difficulty getting the Leap/Processing communication to effectively control it. So, I went back to basics and did some simpler projects with LEDs first. This helped me get comfortable with the Leap - Processing - Arduino system, especially the programming in Processing. 

Now I'm back for round II. Not surprisingly, it fell into place pretty easily. Here's the video:

The movement is a little jerky but that is due to the delay I set to give the servo time to move. The one slightly tricky issue I had to deal with was the out of window constraints. It is not shown in the video, but Processing draws a 720 x  720 window on the computer and displays the finger positions as dots. I was using the vertical finger position to control the servo and wanted the servo to go to its min/max position when the finger position was above/below the window. At first I put this constraint in the Arduino code, but there was a problem with negative values getting read as positive values, so I ended up putting it in the Processing code, which ended up being much simpler.

I also set the window to a height of 720 so that I could simply divide the finger height by 4 to map it to the 0-180 range of the servo rather than using the map() function. A more robust implementation would be setup to handle any window size and map accordingly. 

The Processing code:

/* Servo Control - hand/finger position controls servo motor angle.
By Casey Bloomquist
Using the OnFormative LeapMotionP5 library (http://www.onformative.com/lab/leapmotionp5/)
*/

import com.onformative.leap.LeapMotionP5;
import com.leapmotion.leap.Finger;
LeapMotionP5 leap;

int angle;

import processing.serial.*;
Serial port;

public void setup() {
// set window, P3D = 3D rendering
size(720, 720, P3D);
noFill();
stroke(255);

// set LEAP object
leap = new LeapMotionP5(this);

// set com port. Currently: "/dev/tty.usbmodemfd121"
println("Available serial ports:");
println(Serial.list());
port = new Serial(this, "/dev/tty.usbmodemfd121", 9600);
}

public void draw() {
background(0);
fill(255);
for (Finger f : leap.getFingerList()) {
PVector position = leap.getTip(f);
//PVector velocity = leap.getVelocity(f);
ellipse(position.x, position.y, 10, 10);
if (position.y > 720) {
angle = 180;
} else if (position.y < 0) {
angle = 0;
} else {
angle = int((position.y) / 4);
}
port.write(angle);
println(angle);
}
}

public void stop() {
leap.stop();
}

And the Arduino code:

#include <Servo.h>
Servo myServo;

//int handPos;
//int angle;

void setup() {
myServo.attach(9);
Serial.begin(9600);
myServo.write(0);
}

void loop() {
byte angle;

if (Serial.available()) {
// Read angle from Processing
angle = Serial.read();
Serial.println(angle);
// If fingers in window, read servo angle
myServo.write(angle);
delay(15);
}
}


How Many Fingers Am I Holding Up?

The aim of this project was to continue working on using the Leap Motion controller to control physical actions through an Arduino. The specific goal is to have a set of 5 LEDs display the number of fingers being detected by the Leap Motion controller. 

Here's a image of the Arduino setup,

HowManyFingersArduinoSetup.JPG

and a video of the project in action:

The Processing code:

// How Many Fingers Am I Holding Up?

import com.onformative.leap.LeapMotionP5;
import com.leapmotion.leap.Finger;
LeapMotionP5 leap;

import processing.serial.*;
Serial port;

public void setup() {
// set window, P3D = 3D rendering
size(600, 600, P3D);
noFill();
stroke(255);

// set LEAP object
leap = new LeapMotionP5(this);

// set com port. Currently: "/dev/tty.usbmodemfd121"
println("Available serial ports:");
println(Serial.list());
port = new Serial(this, "/dev/tty.usbmodemfd121", 9600);
}

public void draw() {
background(0);
fill(255);
int numFingers = leap.getFingerList().size();
print("Number of Fingers: ");
println(numFingers);
port.write(numFingers);
for (Finger f : leap.getFingerList()) {
PVector position = leap.getTip(f);
PVector velocity = leap.getVelocity(f);
ellipse(position.x, position.y, 10, 10);
}
}

public void stop() {
leap.stop();
}

And the Arduino code:

/* How Many Fingers Am I Holding Up?

LEDs attached to digital pin 3-7.
Serial Connection to Processing
*/

void setup(){
// initialize serial communication:
Serial.begin(9600);
// set LED pins 3-7 as outputs
for(int x = 3; x<8; x++){
pinMode(x, OUTPUT);
}
}

void loop(){
byte numFingers;
// check if data has been sent from the computer:
if (Serial.available()) {
// read the most recent byte (which will be from 0 to 255):
numFingers = Serial.read();
if (numFingers == 0){
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
} else if (numFingers == 1){
digitalWrite(3, HIGH);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
} else if (numFingers == 2){
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
} else if (numFingers == 3){
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
} else if (numFingers == 4){
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, LOW);
} else if (numFingers == 5){
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);
}
}
}

I used a not-so-elegant if/else decision structure because I was more concerned with the communication rather than the actual output structure. The trickiest part of this project was figuring out how to count the number of fingers. Because getFingerList(), which contains all of the fingers tracked by the Leap, is an ArrayList, I had to use .size() instead of .count().

Up next: controlling a servo motor with the Leap.