Superman x-y sensor
by KristyKat
I created a touchpad sensor from conductive thread, fabric and the lilypad.
Prototypes
Prior to creating the sensor, I had several prototypes.
General Technique Description: Each prototype is composed of knitted swatches that include conductive thread. With a darning needle, I sewed strips of highly conductive thread along two edges. The two edges were then connected to A0 and A1 ports of the Lilypad Arduino. The A0 and A1 corresponded to measuring the resistances along the y and x axes, respectively.
Sensor 1: I handknitted sensor 1. Initial testing of this sensor showed that the resistance in the y direction (direction of knit) had small-almost-non-detectable changes while the resistance in the x direction (knitted rows) had somewhat larger changes, but not enough to reliably detect which side the finger glove was on.
Sensors 2 -3: So, I created larger sensors ( 2 and 3 ) with the knitting machine at a smaller guage. Sensor 3 measured approximately 3″ x 4″. Initial test of this sensor showed more changes in resistance, but, before completely testing this sensor thoroughly for possible implications of fabrication — I made a another bigger sensor.
Sensor 4: This sensor measured approximately 6″x6″. At the time that I made this sensor, I could better detect the changes in resistance in x and y directions.
Problems: To detect the changes in resistance in the x and y directions, I initially kept creating larger sensors. In testing sensors 3-4, however, I realized that my fabrication method was creating additional problems. The combination of knitting non-conductive with conductive thread resulted in a partial display of the conductive thread. This discontinuity would result in inaccurate measurements (i.e. lower resistance would be read in areas distant from the axis because more conductive thread was showing and vice versa).This discontinuity can be better seen in sensors 1-3.
Superman Sensor:
So, I decided to create another sensor that had a more uniform conductive-thread fabrication. Using a knitting machine, I knitted conductive thread which I then (attempted) to uniformly stretch over felt fabric.
This sensor, however, still had problems. This may again be due to imperfections in the fabrication such as discontinuity in the knitting, the uneven contact with the conductive fabric, and non-smooth felt fabric surface. However, through this sensor, I was able to build more code in arduino and processing for detecting the x and y coordinates. See YouTube video
Arduino Code:
void setup() {
// initialize the serial communication:
Serial.begin(9600);
analogReference(INTERNAL);
digitalWrite(A0, HIGH);
digitalWrite(A1, HIGH);
}
void loop() {
// send the value of analog input 0:
Serial.print(analogRead(A0)); //Y-axis
Serial.print(“\t”);
Serial.println(analogRead(A1)); //x-axis
// wait a bit for the analog-to-digital converter
// to stabilize after the last reading:
delay(10);
}
Processing Code:
// Graphing sketch
// This program takes ASCII-encoded strings
// from the serial port at 9600 baud and graphs them. It expects values in the
// range 0 to 1023, followed by a newline, or newline and carriage return
// Created 20 Apr 2005
// Updated 18 Jan 2008
// by Tom Igoe
// This example code is in the public domain.
PImage front, back, superman, superman2, superman3;
import processing.serial.*;
Serial myPort; // The serial port
int xPos = 1; // horizontal position of the graph
float oldinByte = 0; // previous inByte value
float inByteX = 0;
float newinByteX = 0;
float origInByteX = 0; // intial inByte value before mapping/scaling
float inByteY = 0; //inital x position for plotting
float newinByteY = 0; //inital x position for plotting
float origInByteY = 0; // intial inByte value before mapping/scaling
//for AVERAGING
int numReadings = 15;
int index = 0; // the index of the current reading
float[] readingsX = new float[numReadings]; // the readings from the analog input
float totalX = 0; // the running total
float averageX = 0; // the average
float[] readingsY = new float[numReadings]; // the readings from the analog input
float totalY = 0; // the running total
float averageY = 0; // the average
void setup () {
// set the window size:
size(600, 600);
back = loadImage(“supercity-background.jpg”); // Load an image into the program
superman3 = loadImage(“superman3.gif”);
// List all the available serial ports
println(Serial.list());
myPort = new Serial(this, Serial.list()[0], 9600);
myPort.bufferUntil(‘\n’); // don’t generate a serialEvent() unless you get a newline character:
background(0); // set inital background:
}
void draw () {
// everything happens in the serialEvent()
}
void serialEvent (Serial myPort) {
translate(0, 600);
// get the ASCII string:
String inStringY = myPort.readStringUntil(‘\t’);
String inStringX = myPort.readStringUntil(‘\n’);
if (inStringY != null) {
inStringX = trim(inStringX);
inStringY = trim(inStringY);
inByteX = float(inStringX); //set inbyte value from reading
inByteY = float(inStringY); //set inbyte value from reading
origInByteX = inByteX;
origInByteY = inByteY;
String inByteValX = “” + inByteX;
String inByteValY = “” + inByteY;
//Test to make sure I’m getting both values from A0 and A1
print(“ ” + inByteValX);
print(“ ” + inByteValY);
print(“\n”);
/********** remap X & Y values ***************/
inByteX = map(inByteX, 0, 1023, 0, width); //x position
inByteY = map(inByteY, 0, 1023, 0, height); //y position
//highest x value seems to be about 50
//lowest x value seems to be about 20
//neded to map between these values
if(inByteX > 50) {
inByteX = 50;
}
if (inByteX < 20) {
inByteX = 20;
}
newinByteX = round(map(inByteX, 20,50, 0, width)); //x position for plotting
//highest y value seems to be about 80
//lowest y value seems to be about 20
//neded to map between these values
if(inByteY > 80) {
inByteY = 80;
}
if (inByteY < 20) {
inByteY = 20;
}
newinByteY = map(inByteY, 20,80, 0, height); //x position for plotting
//newinByteY = -newinByteY; //make negative for graphing purposes
newinByteY = round(newinByteY*-1);
//Test to make sure I’m getting both values from A0 and A1
/*String inByteValX = “” + inByteX + “ (“+newinByteX +”) “;
String inByteValY = “” + inByteY + “ (“+newinByteY +”) “;
print(“ ” + inByteValX);
print(“ ” + inByteValY);
print(“\n”);*/
/*************/
//take the average of prevoius 10
//output position
// VARIABLES:
// newinByteX, newinByteY
// readingsX[numReadings], totalX , averageX
// readingsY[numReadings], totalY , averageY
//store values into an array
readingsX[index] = newinByteX;
readingsY[index] = newinByteY;
totalX = totalX + readingsX[index]; //calculate totals X
totalY = totalY + readingsY[index]; //calculate totals Y
index = index + 1;
//when reach 10, DO
if (index >= numReadings) {
averageX = totalX / numReadings;
averageY = totalY / numReadings;
String testX = “” + averageX;
String testY = “” + averageY;
print(“ index set to 0″);
print(“ “+testX+” “+testY + “\n”);
index = 0;
totalX = 0;
totalY = 0;
}
/*************/
String inByteVals = “ “+averageX+”, “+averageY;
text(inByteVals, averageX, averageY); //show x & y value value
stroke(0,0,0);
text(inByteVals, averageX, averageY); //erase text
image(superman3, averageX, averageY);
text(inByteVals, averageX, averageY);
delay(10);
//background(0);
image(back, 0, 0);
}
}