Graphite

I'm using graphite as a variable resistor. I drew a thick (1/4") line on a piece of paper and made tick marks at various points. Each tick mark corresponds to a certain analog reading. All this is working fine, but it turns out that the resistance of graphite varies with pressure. So I have a solid reading when my "pen" (an alligator clip) is touching the line, but when I lift it up, the resistance increases. When the resistance increases, the Arduino thinks that I am touching a different tick mark and outputs a faulty reading. An idea how I could work around this problem?

Thanks!

Sounds like you need a way to come up with steadier pressure up & down the line.
I am thinking draw your line in a circle. In the center have a vertical rod. Attach an arm extending from a couple inches up the rod down to your line, with a light spring that pulls the arm down to the bottom of the rod.

Depends on why you are using graphite. If it is because you do not have a pot then get a pot.

Is time delay ok in your app? If so set up a timer. Any reading must hold for a few seconds to register. That way when you change from touching to not touching then your program just remembers the last touch.

What I was thinking of eventually doing is making a graphite touch screen. I have all the math and such worked out, but I just can't fix this problem. CrossRoad's idea would work if the line was the end product, but its not. Here's what I want in the end:

[attached]

The changes are large enough that they would negatively effect the mouse coordinates.

touchpad.png

And I obviously have a voltage divider on the analog pins.

Where does the incoming voltage come from?
I would think you'd need a grid to capture X/Y coordinates - with graphite being a conductor, how do you create seperate lines for A0 & A1 to read?

Maybe if you had seperate lines going right to left, with a different frequency on each line, and the probe picks up the frequency to determine the line being touched, and the level of signal would tell you how far down the line you are.
Or maybe a simpler time multiplex method - I think the A/D conversion time would be the limit as to how fast you detect position tho.

Well as a concept, the graphite touch screen's fine but in reality, you might as well spend less on beer/sweets and buy a $10 or so touch screen :slight_smile:

What do you want to use this graphite touch screen for?

First, to answer Cross Roads:

On the above poorly-drawn diagram, the alliagators are a set distance apart: let's say 10cm. They are set up like this:

alligator ------- > A0 and alligator ------- > A1
|
/ /
\ \
/ /
| |
GND GND

Then I have a "pen" connected to 5V. Touching the pen anywhere on the grid completes two separate voltage divider with the alligator clips. Now I have a "distance constant" which is a floating point number I multiply the analog reading by to get the distance in cm from each alligator. I haven't yet figured that out. Now I have a triangle: [see attached]

Then I use heron's formula:

To calculate the area of my triangle.

Then I can use

substituting "b" for 10cm and my area for the output of heron's formula.

Now I have the height, aka the X coordinate.

Then I can use Pythagoras theorem to calculate the other side of the triangle, or the y coordiantes. These two coordinates are sent over serial to a processing sketch, which scales them to my display size and controls the mouse accordingly.

Sorry if that was a bit unclear-- open for questions. :slight_smile:

Thanks for all the help so far!

baum

Mowius:

Well as a concept, the graphite touch screen's fine but in reality, you might as well spend less on beer/sweets and buy a $10 or so touch screen

Then why do you have an arduino? :slight_smile: Why don't you just buy a sun tracker?

Thanks!

Hmm.. you have a wired pen, and a display behind it. Ever heard of a light pen? Been
playing around with an arduino-based lightpen project for a few weeks.

Traditional light pens used CRT scan timing to determine location, but since video-based
LCD's don't "scan", the original light pen technology doesn't work, software wise, but
the circuit (a phototransistor on an analog read or a comparator) is the same.

Currently, I've got it working doing a "manual" raster scan, but it's visible and very
slow (on a LCD monitor from a DVD player).. but I've got a few ideas (like zone estimation routines)
that may make it at least usable at something like 64x32, on a 7" screen.. that's using
the TVout Lib you'll find posted around.

Some type of light pen arrangement may be a more workable answer than a resistive touch screen..
the basic idea is simple: blink a location off and on, and if the phototransistor is in front of
that location, there's a change in the phototransistor's analog output. Since you control both the
blink and the read, "noise" is actually not as bad a problem as you might think. Phototransistors
work better than LDR's, due to speed as well as tight angle of view on transistors makes for
better resolution/less error.

Finding the location optically also removes the display constraints in some regards-- nothing
needs to change (for an NTSC video setup) between a 7" LCD and a 50" Plasma screen..
it all "scales" automatically..

The whole key is to flash FAST so it's not seen by the person, only the phototransistor..

But I'm asking if there is a way to take out the faulty readings.

But about the light pen:

what if you have a rectangle of LEDs and quickly flash those?

Then you are looking for something like a data smoothing routine, methinks.

One really simple way to do this is to sample average. Basically, take ten samples (for example) and add them
together.. then divide by ten.. and use that as your "read". That way, a single value way out of line with the
rest doesn't skew the output all over the place.

There's also a data smoothing and debouncing library in the playground area, with really good explanations
as to good ways to clean up data, like what you are trying.

Just be aware that's an awfully tricky thing, fabricating reliable resistors..

And yes, that would work too. It's all about taking a read, turn on a light, see if the reading changed or not..
then prgressing to the next location. Pretty simple, actually.. the only issue is usually resolution and speed.
If you are only trying to sense a relatively low resolution "grid", lightpens are cheap and easy..

Last but not least, been thinking about using four phototransistors in a corner configuration, with a "dumb"
pen with an IR emitter (maybe even laser). Relative levels between the sensors should be able to provide
a way to sense location on at least a rudimentary level, assuming the screen has a bit of diffusion of
incoming light (IR) as well as visible light output...

Do you know how fast the arduino would be able to sample and average 10 data points? Do you think this time would be visible when being used as a touch screen?

Pretty fast..

My audio spectrum analyzer project does 128 analog samples per "read",
performs a FFT on the data, and displays it by generating video in realtime-
a 32-band EQ display- and does all that roughly thirty times a second. There's
no external active hardware.. just the arduino, a microphone/preamp, and
the couple of resistors required to use the TVout lib.

The sampling rate on the Arduino can be stunning.. ten zones:

Video frames for reliable read (typically) seems around 3.. but I'm working
on that. Assume three for now, and that means ten zones, three frames per,
makes thirty video frames per "scan", or a sample rate of half a second at
a worst-case scenario with decent discrimination. That's assuming the worst-
using a TVout Lib implementation on a small LCD. If you are using something
like a LED array, then you control the refresh rate and your lag just becomes
the phototransistor and A/D settle times, which are TINY. Most of the time
my project just is waiting for the TV to update- which for scanning purposes,
is woefully slow at 60hz..

so Yeah, it can do that... :wink:

use a low pass filter instead of the sample avaraging. in my experience that works better.

here is some processing code which does that. Basically k defines how strong your filter is 1 -> input == output, 0 -> constant signal, no change.

I have not tested the code, it should work, but I dont really remember ... but take a look at it, and implement your own version. should do the trick.

      float k = 0.8; //alpha level for lowpass function
      float cleanSignal; // output signal
      void setup() 
      {
      cleanSignal = 0; //initialize global value for lowpass function
      }
      
      void draw() 
      {
      lowpass ( ___ insert input from arduino here ___ , k);
      }
      
      float lowpass(float signal, float k) 
      {                     //is k set globally? is cleansignal initialized globally and declared in setup?
      float oldSignal = cleanSignal;
      cleanSignal = oldSignal + (k * (signal - oldSignal));
      return cleanSignal;
      }

void draw()

You may wish to omit that from your Arduino sketch.

And I should be able to port this over to Arduino? I wanted to put all the math on the arduino and as little as possible on processing.

And I should be able to port this over to Arduino?

Yes, though you may wish to not use float, and use binary fractions instead.
Depends on how much processing (with a small "p") you need to do.

binary fractions

???

Instead of multiplying the running average by 0.8 and adding in 0.2 times the new reading, subtract from the running average a fraction (found by dividing (by shifting) the running average by 2/4/8/16/32), and add in the appropriate fraction of the new reading.