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);
}
}