Using a camera with head position detection, I was able to create parallax effect for positioning a remote camera, like looking through a window.
Face Tracking with getUserMedia/WebRTC
headtrackr is a javascript library for real-time face tracking and head tracking, tracking the position of a users head in relation to the computer screen, via a web camera and the webRTC / getUserMedia.
https://github.com/auduno/headtrackr/
I modified the head tracking code with servo position conversion. Using the face/head X & Y Position, I mapped it into pan and tilt servo position.
Setup on Arduino Yun
When you first get the Arduino Yun, you can setup the WIFI SSD and password by making it as an access point. After the connecting your computer to arduino Yun as access point, you can then type in http://192.168.240.1 in your browser to access the setup page.
I am using the WIFI connection, the router assigns the Yun with an IP address automatically. I uploaded the WIFIStatus sketch to get the following message. The Sketch is under Examples > Bridge > WIFIStatus.
Starting bridge... Current WiFi configuration SSID: MIT Mode: Client Signal: 85% Encryption method: None Interface name: wlan0 Active for: 0 minutes IP address: 18.111.14.20/255.255.224.0 MAC address: xx:xx:xx:xx:xx:xx RX/TX: 5/7 KBs
Modifying the Bridge Library
The bridge library has a very simple URL request commands, I am modifying the command to send the servo position.
Download Code#include
#include
#include
#include
Servo servoRotateBase;
Servo servoRarm;
Servo servoLarm;
// Listen to the default port 5555, the Yún webserver
// will forward there all the HTTP requests you send
YunServer server;
void setup() {
// Bridge startup
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
Bridge.begin();
digitalWrite(13, HIGH);
servoRotateBase.attach(A0);
servoRarm.attach(A1);
servoLarm.attach(A2);
// Listen for incoming connection only from localhost
// (no one from the external network could connect)
server.listenOnLocalhost();
server.begin();
}
void loop() {
// Get clients coming from server
YunClient client = server.accept();
// There is a new client?
if (client) {
// Process request
process(client);
// Close connection and free resources.
client.stop();
}
delay(50); // Poll every 50ms
}
void process(YunClient client) {
// read the command
String command = client.readStringUntil('/');
// is "digital" command?
if (command == "digital") {
digitalCommand(client);
}
// is "analog" command?
if (command == "analog") {
analogCommand(client);
}
// is "mode" command?
if (command == "mode") {
modeCommand(client);
}
}
void digitalCommand(YunClient client) {
int pin, value;
// Read pin number
pin = client.parseInt();
// If the next character is a '/' it means we have an URL
// with a value like: "/digital/13/1"
if (client.read() == '/') {
value = client.parseInt();
digitalWrite(pin, value);
}
else {
value = digitalRead(pin);
}
// Send feedback to client
client.print(F("Pin D"));
client.print(pin);
client.print(F(" set to "));
client.println(value);
// Update datastore key with the current pin value
String key = "D";
key += pin;
Bridge.put(key, String(value));
}
void analogCommand(YunClient client) {
int pin, value;
// Read pin number
pin = client.parseInt();
// If the next character is a '/' it means we have an URL
// with a value like: "/analog/5/120"
if (client.read() == '/') {
// Read value and execute command
value = client.parseInt();
// analogWrite(pin, value);
//if pin=1 pan
//if pin=2 titl
servoRotateBase.write(pin);
servoLarm.write(180-value);
servoRarm.write(value);
// Send feedback to client
client.print(F("Pan X: "));
client.print(pin);
client.print(F(", "));
client.print(F(" Tilt Y: "));
client.println(value);
// Update datastore key with the current pin value
String key = "D";
key += pin;
Bridge.put(key, String(value));
}
else {
// Read analog pin
value = analogRead(pin);
// Send feedback to client
client.print(F("Pin A"));
client.print(pin);
client.print(F(" reads analog "));
client.println(value);
// Update datastore key with the current pin value
String key = "A";
key += pin;
Bridge.put(key, String(value));
}
}
void modeCommand(YunClient client) {
int pin;
// Read pin number
pin = client.parseInt();
// If the next character is not a '/' we have a malformed URL
if (client.read() != '/') {
client.println(F("error"));
return;
}
String mode = client.readStringUntil('r');
if (mode == "input") {
pinMode(pin, INPUT);
// Send feedback to client
client.print(F("Pin D"));
client.print(pin);
client.print(F(" configured as INPUT!"));
return;
}
if (mode == "output") {
pinMode(pin, OUTPUT);
// Send feedback to client
client.print(F("Pin D"));
client.print(pin);
client.print(F(" configured as OUTPUT!"));
return;
}
client.print(F("error: invalid mode "));
client.print(mode);
}
Capacitive Pressure Sensing
Software
I used Paul Badger’s Capacitive Sensing Library for my Arduino sketch.
Hardware
I used a PBC board as a template to cut out 2 layers of latex glove.
I used a 100 kilohm – 50 megohm resistor for pin 11, this is the TX. The middle plate is the RX, it goes directly to pin 10.
The 2 TX plates sandwiches the RX plate in the middle.
More pressure = less charge
#include /* * CapitiveSense Library Demo Sketch * Paul Badger 2008 * Uses a high value resistor e.g. 10M between send pin and receive pin * Resistor effects sensitivity, experiment with values, 50K - 50M. Larger resistor values yield larger sensor values. * Receive pin is the sensor pin - try different amounts of foil/metal on this pin */ CapacitiveSensor cs_4_2 = CapacitiveSensor(11,10); // 10M resistor between pins 4 & 2, pin 2 is sensor pin, add a wire and or foil if desired void setup() { cs_4_2.set_CS_AutocaL_Millis(0xFFFFFFFF); // turn off autocalibrate on channel 1 - just as an example Serial.begin(9600); } void loop() { long start = millis(); long total1 = cs_4_2.capacitiveSensor(30); //long total2 = cs_4_6.capacitiveSensor(30); //long total3 = cs_4_8.capacitiveSensor(30); Serial.print(millis() - start); // check on performance in milliseconds Serial.print("t"); // tab character for debug windown spacing Serial.println(total1); // print sensor output 1 delay(20); // arbitrary delay to limit data to serial port }