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