Skip to Content
Dan k
Chen
Measurement
Explorations Dan Chen / April 11, 2016

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.

Download HTML & JS

 

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

DSC01959

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


Download Code

 

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.

IMG_5300

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.

IMG_5301 IMG_5302 IMG_5304

 

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
}
DAN K CHEN © 2024