The final project consist of what we learn over the course of the semester. My final project would cover
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
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.
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
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.
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
For composites, I designed the shape in SolidWorks, then using a shopBot to cut out the blue foam.
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.
I smoothed the surface using a fine sand paper.
I tested out the fit using the negative cut outs.
The shape is fairly simple, all I had to do was to cut the burlaps and canvas in rectangular shapes using a laser cutter.
I wrap and glue down the release film onto the foam and started to lay everything out, layer by layer.
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.
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.
At the meantime, I tried to print my other parts with a 3D printer…
I used a chop saw first to trim the ends to size.
I then used the table saw to trim the bottom to size.
For safety and speed, I didn’t have to cut the bottom too high.
All the leftover composites materials pop right out.
Note: I used the plastic table saw blade.
I dug out the blue foam using a chisel, and the release film made the process easy.
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.
Given more time, I would probably use 3D printer for prototyping, and ShopBot for final production.
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.
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.
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
I realized that I did not have enough space for my extra board, so this wearable is gonna be a little tight.
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.