Go Down

Topic: Creating a paper touch pad  (Read 2441 times) previous topic - next topic

gtkid1990

Jan 01, 2017, 10:40 pm Last Edit: Jan 01, 2017, 10:48 pm by gtkid1990
Hey guys,

A few years ago someone posted a demo on youtube for a "paper trackpad" which is basically an alternative for your laptop mouse (see here
). This particular project uses Arduino as a microcontroller. Unfortunately, I was unable to get any schematics from the creator because the post was so old however, I did find a diagram of the circuit. ((see here
)

In the video description, the person has also posted their code.
int a, b, c, d, x, y, xout, yout, i;
int xbuffer[10];
int ybuffer[10];

void setup() {
  analogReference(DEFAULT);
  Serial.begin(9600);
}

void loop() {
  //read the four corners
  a = analogRead(0);
  b = analogRead(1);
  c = analogRead(2);
  d = analogRead(3);
  //

  x = (2.0663707*c + 2.0544114*a - 1.1423724*b - 1.5299211*d - 1266.8639) / 1.5; //do the x magic
  y = (2.6366761*b + 3.5104709*a - 0.41156325*c - 1.3292001*d - 3814.8667) / 1.5; //do the y magic
  //(the above formulas are derived from the properties of MY piece of paper + graphite and probably won't work well with any other)

  //buffering stuff to smooth mouse motion
  xbuffer[0] = x;
  ybuffer[0] = y;
 
  xout = 0;
  yout = 0;
 
  for(i=0; i<9; i++)
  {
    xout = xout + xbuffer;
    yout = yout + ybuffer;
  }
 
  xout = xout / 10;
  yout = yout / 10;
 
  for(i=1; i<9; i++)
  {
    xbuffer = xbuffer[i-1];
    ybuffer = ybuffer[i-1];
  }
  //end of buffering
 
  //send x y positions to the computer. A program of your own is required to receive this and interpret it into mouse movement.
  Serial.print("x");
  Serial.print(xout);
  delay(25);
  Serial.print("y");
  Serial.print(yout);
  Serial.print("e");
  delay(25);
}

I have tried to run this code for the past 3 days and seem to fail each time. In the code, the person has written a function for the x and y coordinates. I did some experimentation myself with the analog write values to derive an equation (it failed). I am stuck and can't figure out what to do. Also, I am using c# to change the coordinates for the mouse.
Can someone please offer their guidance?

This is the link to the original project.

Paul_KD7HB

How well did you study the tutorials on analog use in the Arduino? How about: https://www.arduino.cc/en/Tutorial/AnalogInput. You might find your answers here.

Paul

gtkid1990

I think I figured it out. The whole time I was using the digital pins rather than analog pins. I think that is my problem.

gtkid1990

How well did you study the tutorials on analog use in the Arduino? How about: https://www.arduino.cc/en/Tutorial/AnalogInput. You might find your answers here.

Paul
I read through the whole document but still the values I am getting don't make sense. It's not that there are any problems with my breadboarding. Can you please help?

Paul_KD7HB

I read through the whole document but still the values I am getting don't make sense. It's not that there are any problems with my breadboarding. Can you please help?
Now you are using the analog pins, what is being returned for a,b,c,d? Surely you have printed those values on the screen.

Paul

gtkid1990

Now you are using the analog pins, what is being returned for a,b,c,d? Surely you have printed those values on the screen.

Paul
I am getting values however I don't know how to use these values to come up with a function for the x and y coordinates.

Here are the values I got for the top left, top right, bottom left and bottom right corner.

TL : 987 919 930 969
TR : 983 928 947 972
BL : 983 915 945 969
BR : 967 897 920 954

I have tried to formulate system of equations using these values:

987a +  919b +  930c +  969d = 0
983a +  928b +  947c +  972d = 1200
983a +  915b +  945c +  969d = 0
967a + 897b + 920c + 954d = 1200

I solved for each individual value and formulated an equation out of each as shown in the program in the previous posts.

The problem is, the values I am getting don't match the position my finger is on the grid meaning the function is wrong. I know I am doing something wrong for sure but not sure what.

jremington

#6
Jan 05, 2017, 03:15 am Last Edit: Jan 05, 2017, 03:15 am by jremington
The "paper" has to be somewhat conductive for that to work. Carbon copy paper (for old fashioned typewriters) might work.

What are you trying to use?

gtkid1990

Currently, I am using graphite (as shown in the video in the previous posts). So pencil graphite thoroughly shaded on paper.

jremington

#8
Jan 05, 2017, 05:58 am Last Edit: Jan 05, 2017, 06:27 am by jremington
The values you are printing are all about the same, which means no current is flowing in the conductive paper.

Are you touching the paper with your finger and is the rest of you somehow connected to the Arduino ground as shown in the schematic?

gtkid1990

I did two tests. One with just a grounded wire the other where a ground rust strap is attached. Also I forgot to mention that when not touching the paper the values are:      1023 1023 1023 1023. So there is considerable change when touching the paper.

gtkid1990

Currently, I am using graphite (as shown in the video in the previous posts). So pencil graphite thoroughly shaded on paper.
I tried using carbon paper today however, it dosen't seem to work very well.

jremington

The video did not give the impression that the author's idea worked well.

What is the point of this project?

gtkid1990

The video did not give the impression that the author's idea worked well.

What is the point of this project?
I was wondering if I could make a touchpad from regular paper. I was really interested in the video and felt that this would be a great project, however, I am having problems with calibration as well creating a function for the x, y coordinates. I don't know what exactly I should do to get this touchpad working.


jremington

#13
Jan 08, 2017, 05:33 am Last Edit: Jan 08, 2017, 05:34 am by jremington
The idea does work well if you have a sheet (or two) of uniformly conductive material and a way of making good connections to the edges.

That is the basis for resistive touchscreens, as discussed in this application note.

gtkid1990

#14
Mar 18, 2017, 06:10 am Last Edit: Mar 18, 2017, 06:15 am by gtkid1990
Hey guys,



I started working on a project where instead of graphite paper I started using velostat instead. I get analog values from a resistive touchscreen and turn them into intersection points.

Here is an example:


Here is my code for the data collection using an Arduino Uno and construction of the points using tool called processing.



   #define side1 2
   #define side2 3
   #define side3 4
   #define side4 5
   #define contact A0

   void setup() {
     pinMode(contact, INPUT);
     pinMode(side1, OUTPUT); 
     pinMode(side2, OUTPUT); 
     pinMode(side3, OUTPUT); 
     pinMode(side4, OUTPUT); 
     Serial.begin(9600);
   }

   void loop() {
     int sensorValue1;
     int sensorValue2;
     int sensorValue3;
     int sensorValue4;
 
     // SENSOR VALUE 1:
     digitalWrite(side1, LOW);
     digitalWrite(side2, HIGH);
     digitalWrite(side3, HIGH);
     digitalWrite(side4, HIGH);
     delay(5);
     for (int i = 0; i < 10; i++){
       sensorValue1 = analogRead(contact);
     }
 

     // SENSOR VALUE 2:
     digitalWrite(side2, LOW);
     digitalWrite(side3, HIGH);
     digitalWrite(side4, HIGH);
     digitalWrite(side1, HIGH);
     delay(5);
     for (int i = 0; i < 10; i++){
       sensorValue2 = analogRead(contact);
     }


     // SENSOR VALUE 3:
     digitalWrite(side3, LOW);
     digitalWrite(side2, HIGH);
     digitalWrite(side4, HIGH);
     digitalWrite(side1, HIGH);
     delay(5);
     for (int i = 0; i < 10; i++){
       sensorValue3 = analogRead(contact);
     }


     // SENSOR VALUE 2:
     digitalWrite(side4, LOW);
     digitalWrite(side3, HIGH);
     digitalWrite(side2, HIGH); 
     digitalWrite(side1, HIGH);
     delay(5);
     for (int i = 0; i < 10; i++){
       sensorValue4 = analogRead(contact);
     }

     Serial.print(sensorValue1);
     Serial.print(",");
     Serial.print(sensorValue2);
     Serial.print(",");
     Serial.print(sensorValue3);
     Serial.print(",");
     Serial.print(sensorValue4);
     Serial.println();
   }

This is the Processing code for the construction of the graph.

<!-- language: java -->

   import processing.serial.*;


   Serial myPort;  // The serial port
   int maxNumberOfSensors = 4;   
   float[] sensorValues = new float[maxNumberOfSensors];
   float sensorValueX;
   float sensorValueX1;
   float sensorValueY;
   float sensorValueY1;
   int scaleValue = 2;

   void setup () {
     size(600, 600);  // set up the window to whatever size you want
     //println(Serial.list());  // List all the available serial ports
     String portName = "COM5";
     myPort = new Serial(this, portName, 9600);
     myPort.clear();
     myPort.bufferUntil('\n');  // don't generate a serialEvent() until you get a newline (\n) byte
     background(255);    // set inital background
     smooth();  // turn on antialiasing
   }


   void draw () {
     //background(255);
     //noFill();
     fill(100,100,100,100);
     ellipse(height,0, scaleValue*sensorValues[0], scaleValue*sensorValues[0]);
 
     ellipse(0,width, scaleValue*sensorValues[1], scaleValue*sensorValues[1]);
     ellipse(height,width, scaleValue*sensorValues[2], scaleValue*sensorValues[2]);
     ellipse(0,0, scaleValue*sensorValues[3], scaleValue*sensorValues[3]);
     //ellipse(sensorValueY, sensorValueX, 10,10);
     //println(sensorValueY,sensorValueX);
     sensorValueX = ((sensorValues[3]*sensorValues[3])-(sensorValues[2]*sensorValues[2])+600*600)/2000;
     sensorValueX1 = ((sensorValues[0]*sensorValues[0])-(sensorValues[1]*sensorValues[1])+600*600)/2000;
   sensorValueY = ((sensorValues[3]*sensorValues[3])-(sensorValues[2]*sensorValues[2])+(600*600))/2000;
     sensorValueY1 = ((sensorValues[1]*sensorValues[1])-(sensorValues[0]*sensorValues[0])+(600*600))/2000;
 
     line(0, scaleValue*sensorValueX, height,scaleValue* sensorValueX);
     line(scaleValue*sensorValueY, 0, scaleValue*sensorValueY, width);
     ellipse(scaleValue*sensorValueY, scaleValue*sensorValueX, 20,20);
     line(0, scaleValue*sensorValueX1, height,scaleValue* sensorValueX1);
     line(scaleValue*sensorValueY1, 0, scaleValue*sensorValueY1, width);
     ellipse(scaleValue*sensorValueY1, scaleValue*sensorValueX1, 20,20);
     println(scaleValue*sensorValueX,scaleValue*sensorValueY);
   }


   void serialEvent (Serial myPort) {
     String inString = myPort.readStringUntil('\n');  // get the ASCII string

     if (inString != null) {  // if it's not empty
       inString = trim(inString);  // trim off any whitespace
       int incomingValues[] = int(split(inString, ","));  // convert to an array of ints

       if (incomingValues.length <= maxNumberOfSensors && incomingValues.length > 0) {
         for (int i = 0; i < incomingValues.length; i++) {
           // map the incoming values (0 to  1023) to an appropriate gray-scale range (0-255):
       
           sensorValues = map(incomingValues, 0, 1023, 0, width);
           //println(incomingValues+ " " + sensorValues);
         }
       }
     }
   }

I was wondering how I could convert the intersection of those points to a coordinate? Currently, I am using trilateration but it seems to be ineffective. Example: in the image, I showed you, I set the parameters for the dimensions to be (600,600). Is it possible to change that intersection are to a coordinate value? Currently, my code is printing out coordinates however they are diagonals such at the x and y values are equal. I want the coordinates of x and y to have different quantities so that I can get coordinates for different sides in the square. Can somebody help?

Go Up