Intimacy Prosthetics

By Dan Chen, September 12, 2014

This project consist of the following elements / skills

  • Laser cutting
  • CNC with shopBot
  • Composites
  • Input & output device
  • Networking
  • Embedded Programming
  • Electronic Design
  • Computer Aided Design

Intimacy Prosthetics consist of 2 wearable devices that 2 people would wear to communicate sense of human connection through touch. The device is capable of sending and receiving double tap, x & y movement wirelessly.

I want to create a film prop for my next project. It’s about the future of human interaction, how technology might shift our ways of human connection, both digitally and physically.  Ultimately I’m trying to ask what is intimacy without humanity or what is intimacy with technology.

Jump to final video

Process

Electronics

Building on top of previous projects, I designed a board uses atmega328 with female pins that docks NRF24L01. The special connector also doubles as an ISP pins, for loading the boot loader.

IMG_0644 IMG_0639

I was not able to get high resolution positioning with my capacitive touchpad from my previous project. I decided to go with Capacitive Trackpad/Touchpad – Microcontroller-Friendly PS/2. from http://www.adafruit.com/product/837

IMG_1900

Mechanical design & Form Design

I tried out many different form factors for this wearable device. I want it to feel human and machine like at the same time. The difficulty with the wearable device is the sizing. I was not sure what size to go with and how I would make it adjustable. At this point I was not sure how much space my board is going to take up, which is a major problem at the end.

IMG_1920

I was going to design my pan and tilt servo mount, but I end up going with Aircraft FPV dedicated nylon Pan/Tilt Camera Platform Anti-Vibration Camera Mount. from http://www.amazon.com/gp/product/B00CSCBSZY/ref=oh_aui_search_detailpage?ie=UTF8&psc=1

IMG_1901

For composites, I designed the shape in SolidWorks, then using a shopBot to cut out the blue foam.

IMG_1977 IMG_1983

I stack all my small cut out pieces and glue them together. Notice the gap on the bottom, this is for pinning down the end of composites materials.IMG_2027

I smoothed the surface using a fine sand paper.IMG_2033

I tested out the fit using the negative cut outs.

IMG_2037

The shape is fairly simple, all I had to do was to cut the burlaps and canvas in rectangular shapes using a laser cutter.

IMG_2044

I wrap and glue down the release film onto the foam and started to lay everything out, layer by layer.

IMG_2054 I need a lot of surface tension with my composites, so i pin down one side with several pins, then stretch and pin down the other side.

IMG_2055 IMG_2057

I positioned it vertically to get the excess Epoxy Resin out, then flipping it over. I spread the clear Entropy Resins (2 part A and 1 part B) onto each burlap and stack them layer by layer.
IMG_2060 IMG_2064 IMG_2065 IMG_2101 IMG_2114IMG_2111  IMG_2119

At the meantime, I tried to print my other parts with a 3D printer…

IMG_2130

Trimming  the Composites

I used a chop saw first to trim the ends to size.

IMG_2171

I then used the table saw to trim the bottom to size.IMG_2175

For safety and speed, I didn’t have to cut the bottom too high.IMG_2177

All the leftover composites materials pop right out.

IMG_2180

Note: I used the plastic table saw blade.IMG_2181 IMG_2182

I dug out the blue foam using a chisel, and the release film made the process easy.IMG_2184 IMG_2185

3D Printing

The prints takes about 80 hours to print, I setup an IP cam to monitor it and I can shut the printer off remotely just in case.

IMG_2287 IMG_2290

 

Given more time, I would probably use 3D  printer for prototyping, and ShopBot for final production.

Testing my electronic setup.

For programing my electronics, I used arduino as IDE, with servo library, RF24 Library and Adafruit_PS2_Trackpad library. I could not get the RF24 library to duplex, meaning that sending and receiving data at the same time.

IMG_2227

I decided that it is quicker to do the RF communication with 4 boards, on 2 sets of channels, but the RF seems to be unreliable. IMG_2309

Code for the Touchpad board

#include 
#define PS2_DATA 2
#define PS2_CLK 3
Adafruit_PS2_Trackpad ps2(PS2_CLK, PS2_DATA);




// other stuff
int ledPin = A2;    // LED connected to digital A2
int counter=1;



/*
RF24 test transmitter
*/

#include 
#include "nRF24L01.h"
#include "RF24.h"
int joystick[2];
RF24 radio(7,8);


byte addresses[][6] = {"8Node","8Node"};
//byte addresses[][6] = {"3Node","3Node"};
//byte addresses[][6] = {"7Node","7Node"};
//const uint64_t pipe = 0xE8E8F0F0E1LL;








void setup() {
  

  Serial.begin(9600);
 

  
  
      analogWrite(ledPin, 255);delay (100);      
      analogWrite(ledPin, 0); delay (100);
      analogWrite(ledPin, 255);delay (100);      
      analogWrite(ledPin, 0); delay (100); 
      analogWrite(ledPin, 255);delay (100);      
      analogWrite(ledPin, 0); delay (100);
      analogWrite(ledPin, 255);delay (100);      
      analogWrite(ledPin, 0); delay (100); 
      
        for (float br = 0; br < 3800; br=br+10) {
                    analogWrite(ledPin, 0);
                    analogWrite(ledPin, 255);
                    delayMicroseconds(br); // Approximately 10% duty cycle @ 1KHz
                    analogWrite(ledPin, 0);
                    delayMicroseconds(2000);
          }


      // PS2 stuff
      /*
      if (ps2.begin()){
        Serial.println("Successfully found PS2 mouse device");
        }
      else{
        Serial.println("Did not find PS2 mouse device");
      }
      */
      while (!ps2.begin()){
        Serial.println("Did not find PS2 mouse device");
        delay (100);
      }
      
      Serial.println("Successfully found PS2 mouse device");
      Serial.print("PS/2 Mouse with ID 0x");
      Serial.println(ps2.readID(), HEX);
       
      
  pinMode(ledPin, OUTPUT);



 
  //Radio stuff
 radio.begin();
 radio.setAutoAck(1);                    // Ensure autoACK is enabled
  radio.setRetries(2,2);     
  
 //radio.openWritingPipe(pipe);
 radio.openWritingPipe(addresses[1]);
 radio.printDetails();
  
//delay (1000);

}


uint16_t lasttap_x = 0, lasttap_y = 0;

void loop() {
  


  if (! ps2.readData()) {
      if (counter % 2) {analogWrite(ledPin,255);}
      else{analogWrite(ledPin,0);}
      return;  
    }

  //int x=map(ps2.x,120,997, 5, 175 );
  //int y=map(ps2.y,88,741, 5, 175 );

/*
//33channel
//more +/- 90 numer more movement
  int x=map(ps2.x,120,997, 90-27, 90+18 );  // (right , left ) looking at faceing device front // more +/0- more numer more movement
  int y=map(ps2.y,88,741, 90-70, 90+25 );  // ( up , down )
*/

//88 channel
//more +/- 90 numer more movement

  int x=map(ps2.x,120,997, 90-16, 90+50 );  // (right , left ) looking at faceing device front // more +/0- more numer more movement
  int y=map(ps2.y,88,741, 90-70, 90+10 );  // ( up , down )
  
  
    joystick[0] = 180-x;
    joystick[1] = y;
       
       
  
// send double tap
    if (ps2.gesture && !ps2.finger)  {
              if ((lasttap_x == ps2.x) && (lasttap_y == ps2.y)) {
                //Serial.print("\tDouble tap!");            
                  joystick[0] = 999;
                  joystick[1] = 999;
                 analogWrite(ledPin, 255);
                  radio.write( joystick, sizeof(joystick) );
              }
               lasttap_x = ps2.x;
               lasttap_y = ps2.y;
      }
      else  if (x < 180  && x  &&  y < 180  && y ){                analogWrite(ledPin, 255);                                   Serial.print("Sending >>>>");
                   Serial.print(joystick[0]);
                   Serial.print(" / ");
                   Serial.println(joystick[1]);
               analogWrite(ledPin, 0);
             radio.write( joystick, sizeof(joystick) );

            }
            else{
               analogWrite(ledPin, 0);
            }
}

Code for the Servo board

/*
RF24 test transmitter
*/

#include 
#include "nRF24L01.h"
#include "RF24.h"
int joystick[2];
int vibrationPin = A2;   

RF24 radio(7,8);


//byte addresses[][6] = {"8Node","8Node"};
byte addresses[][6] = {"3Node","3Node"};
//byte addresses[][6] = {"7Node","7Node"};
//const uint64_t pipe = 0xE8E8F0F0E1LL;


#include  
Servo servoT; 
Servo servoB; 


#define PS2_DATA 2
#define PS2_CLK 3


void setup() {
  

  Serial.begin(9600);
 
//RF stuff  // RF24 test transmitter     
 radio.begin();
radio.setAutoAck(1); 
radio.setRetries(0,15);                 // Smallest time between retries, max no. of retries

 radio.openReadingPipe( 1,addresses[0]);
 

radio.startListening();
radio.powerUp();
radio.printDetails(); 
  
  
  

  //Serial.println("Start");
  
// servo
servoT.attach(A1);  // attaches the servo on pin 9 to the servo object 
servoB.attach(A0);  // attaches the servo on pin 9 to the servo object 

 
 
 
  for(int pos = 30; pos>=15; pos-=1)     // goes from 180 degrees to 0 degrees 
  {                                
    servoB.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(15);                       // waits 15ms for the servo to reach the position 
  } 
  
  
//move servo // top server closer to the FTDI
  for(int pos = 80; pos <= 100; pos += 1) // goes from 0 degrees to 180 degrees    {                                  // in steps of 1 degree      servoT.write(pos);              // tell servo to go to position in variable 'pos'      delay(15);                       // waits 15ms for the servo to reach the position    }    for(int pos = 100; pos>=80; pos-=1)     // goes from 180 degrees to 0 degrees 
  {                                
    servoT.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(15);                       // waits 15ms for the servo to reach the position 
  } 
  for(int pos = 80; pos <= 90; pos += 1) // goes from 0 degrees to 180 degrees 
  {                                  // in steps of 1 degree 
    servoT.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(15);                       // waits 15ms for the servo to reach the position 
  } 
  

pinMode(vibrationPin, OUTPUT);


                digitalWrite(vibrationPin, HIGH); 
                delay(300);
                digitalWrite(vibrationPin, LOW); 
                delay(50);
                
                
                digitalWrite(vibrationPin, HIGH); 
                delay(300);
                digitalWrite(vibrationPin, LOW);                 
                
  
}


void loop() {

              //debug 
              //Serial.println(joystick[0]);
              //delay(200);
  
            radio.read( joystick, sizeof(joystick) );
            
            if (joystick[0] < 180  && joystick[0] > 1  )
            {
               /*
              Serial.print("Getting <<<<<<   ");
             Serial.print(joystick[0]);
             Serial.print(" / ");
             Serial.println(joystick[1]);
              */
              servoT.write(joystick[0]);
              servoB.write(joystick[1]);
             }
             
             
             
             if (joystick[0]==999 ){
                digitalWrite(vibrationPin, HIGH); 
                delay(300);
                digitalWrite(vibrationPin, LOW); 
                delay(50);
                digitalWrite(vibrationPin, HIGH); 
                delay(300);
                digitalWrite(vibrationPin, LOW); 
             }
   
  

    

  
}

I end up with 4 boards, 2 board sends the touchpad data and 2 boards gets the touch pad data.

Download codes here

Stuffing all the parts

I realized that I did not have enough space for my extra board, so this wearable is gonna be a little tight.

IMG_4265 IMG_4266IMG_2323

Result

IMG_4367 IMG_4366 IMG_4361 IMG_4358 IMG_4348 IMG_4344

When you first turn on the device it will reset servo position and vibrate twice. The LED light would indicate the sending of the signal.

1476374_10102332136970701_2153040159854831260_n 1545121_10102332136900841_5601883077815476752_n 10846052_10102332136940761_1929283658247533045_n