Go Down

Topic: Graphite (Read 2691 times) previous topic - next topic

baum

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!

CrossRoads

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.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

tjbaudio

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.

baum

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.

baum

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

CrossRoads

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.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

mowcius

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 :)

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

baum

#7
Mar 27, 2011, 03:51 pm Last Edit: Mar 27, 2011, 04:37 pm by baum Reason: 1
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. :)

Thanks for all the help so far!

baum



Mowius:
Code: [Select]
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? :) Why don't you just buy a sun tracker?

Thanks!



focalist

#8
Mar 27, 2011, 04:49 pm Last Edit: Mar 27, 2011, 04:58 pm by focalist Reason: 1
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..
When the testing is complete there will be... cake.

baum

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

baum

But about the light pen:

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

focalist

#11
Mar 27, 2011, 05:04 pm Last Edit: Mar 27, 2011, 05:15 pm by focalist Reason: 1
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...
When the testing is complete there will be... cake.

baum

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?

focalist

#13
Mar 27, 2011, 05:20 pm Last Edit: Mar 27, 2011, 05:34 pm by focalist Reason: 1
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... ;)
When the testing is complete there will be... cake.

fkeel



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.

Code: [Select]

     
      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;
      }
 
http://embodimentlabs.tumblr.com/
http://paulstrohmeier.info/

Go Up