Using a camera with head position detection, I was able to create parallax effect for positioning a remote camera, like looking through a window.
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.
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
The bridge library has a very simple URL request commands, I am modifying the command to send the servo position.
#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); }
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 }