Graphite

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.

But how can I use binary fractions? Are they integers? I haven't ever seen a "fraction" data type. Can you please paste some pseudo code so I can see what you mean?

Thanks!

baum

runningAverage -= runningAverage >> 3;   // multiply runningAverage by 7/8
runningAverage += newReading >> 3;       // add in 1/8 of the new reading.

I get it! Thanks!

see Fractions in binary in the link

However I don't think there is an answer to your original question as the false reading is the result of varying contact pressure. Therefore it is not false at all but real. So no amount of averaging will get rid of it.

But when I pull up the serial monitor, these "out of line" readings are only for 3-4 readings so averaging the readings should help.

just for the record, the code I posted will not work on your arduino (but I think thats been made clear anyway). I just posted it, so that you can take a look at the logic behind it ... as I said, you'll have to find your own implementation which works for your setup...

but i have used this approach to solve similar problems.

good luck

p.

The lowpass filter actually performs better than the averaging. averaging the data returns about 6~10 haywire readings after pen is lifted. Low pass filter gives none, sometimes 1.

Excellent!

Great. Averaging is probably the simplest form, but the low-pass will perform better for obvivous reasons. There's even implementations that use confidence intervals and standard deviations, if you go looking around... but they all have the same idea in mind.. smoothing out oddball data to make a dataset more usable..

You're going to have to use some sort of wired stylus device in conjunction with the graphite anyways to close the circuit. This stylus could integrate a spring loaded pushbutton that is only active when an adequate amount of pressure is applied to the point, thus telling the Arduino when to read and calculate stylus position.

I FIGURED IT OUT!!!!!! :slight_smile: :slight_smile: :slight_smile: :slight_smile: Yay!

Here's how:

Instead of having one alligator clip, I'll have two: one at each end of the line. Then I can take the average of these two values.
Think about it. With one clip, as I lift up, ? increases, arduino thinks I am touching farther away. With two clips, ? increases equally. So if I am in the middle, pressing down with the right amount of force (no idea how much force that is) I should get 512 or so on both sides. As I lift up, each side maybe increases too 600. then I do 1023-600 to get 423. the average of 423 and 600 is 511.5, so close enough.

For my touchpad, I'll just use 4 clips (one for each corner) and solve for 4 different triangles, taking the mean coordiantes.

Thanks for all the help!

baum

good for you :slight_smile:

the simplest solutions usually are the best...