how fast a contact can a linear soft potentiometer detect?

I'm using a linear soft potentiometer in a project;

The project involves mounting the soft pot on the side of an air hockey table and registering where the puck strikes.
As the Softpot registers a different value for where it is pressed on the sensor, it seems a good way to get this sort of data in with a minimum of fuss (one sensor covers 50cm, accuracy is quite precise, the puck bounce is unimpeded and there is only set of cables to deal with for install).

My concern before I tried it was the puck would strike too hard and damage the sensor. However, in practice, the sensor does not get damaged, but the puck seems to strike it too fast for a contact to register. (BTW, I also tried it without the paper over top)

I wonder if there is any advice someone can give me? is faster sampling a solution?
I am currently tying this :
http://forum.arduino.cc/index.php/topic,6549.0.html

If this doesn't work, I can do a series of ir pairs, but it gets messier....many thanks for any input

Any better advice?

Right, I tried the faster analog read:
http://forum.arduino.cc/index.php/topic,6549.0.html
but no luck.

It will help if you tell us what Arduino you have (UNO, MEGA etc). Draw or describe how the sensor is connected and show us the code you tried. I'm sure the arduino can do the job but maybe analogue read is not the answer and you may need to try a comparator input.

Thanks for the advice, that sounds promising!

Sorry to forget, I am using an Arduino Uno.

From the sensor there is just one wire for 5v, one ground, and one going into A0;


image from http://bildr.org/2012/11/touch-sliders-with-a-softpot-arduino/
and here is the code for the Arduino;

int softPot = A0; 
int softPotReading = 0;
int inByte = 0; 

void setup() {
Serial.begin(9600);
digitalWrite(softPot, HIGH); //enable pullup resistor 
establishContact();
}
void loop() {
  if (Serial.available() > 0) {
    inByte = Serial.read();
    softPotReading = analogRead(softPot)/4;
    Serial.write(softPotReading);
  }
}
void establishContact() {
 while (Serial.available() <= 0) {
 Serial.print('A'); // send a capital A
 delay(300);
}
}

From here, it goes into processing where the serial output is read into an array and a rect is displayed according to the value from the pot.
It all works, bar the fast puck contact.

Any thoughts very welcome....

I cannot see what the need of inByte is for in your code and because the analogue pot is read only when a byte is received from processing your not going to read very quickly. No need to turn on internal pullup on the analogue input pin.
A better idea would be to have a threshold value that sits just above/below (depends if reading increases/decreases when puc hits) the reading you get when the strip is inactive and read the analogue pin as fast as you can. If the reading goes under/over the threshold value (a puc has hit it) then send it to processing over serial. Speed up the serial from 9600 to 115200 will also make reaction time quicker.

int softPot = A0; 
byte softPotReading = 0;

int threshold = 512 >> 2;

void setup() {
  Serial.begin(115200);
  establishContact();
}
void loop() {
  softPotReading = analogRead(softPot) >> 2;
  if (softPotReading > threshold) {  // Assume reading increases when puc hits
    Serial.write(softPotReading);
  }
}
void establishContact() {
  while (Serial.available() <= 0) {
    Serial.print('A'); // send a capital A
    delay(300);
  }
}

Thanks,

I have inByte, as I have other sensors other than the Pot and am sending multiple values over serial.
I have code from the link below in processing to detect the start of data to get the incoming data into the correct slots in an array in processing;

void serialEvent(Serial myPort){
  int inByte = myPort.read();
  if (firstContact==false){
    if (inByte=='A'){
      myPort.clear();
      firstContact = true;
      myPort.write('A');
    }
  }
  else {
    serialInArray[serialCount] = inByte;
    serialCount++;
    if (serialCount > 1){
      psoftPotReading = serialInArray[0];
      pir1Reading = serialInArray[1]; 
      println("psoftPotReading = " + psoftPotReading);
      println("pir1Reading = " + pir1Reading);
      myPort.write('A');
      serialCount = 0;
    }
  }

it made some sense to me!

I'm trying out your example, many thanks for the help

If analog reading doesn't work, you may need to design some kind of special detector circuit to detect impacts on the pot. This is certainly possible but would require quite a bit of expertise and a lot of trial and error.

What you would need to do, is design some combination of opamps, capacitors and diodes which will :

(a) detect deviation from the quiescent state
(b) capture and hold the peak level of the deviation
(c) signal the arduino by interrupt to collect the peak level of the deviation
(d) reset in preparation for the next impact.

Detecting events is quite easy, it is a bit harder to capture the peak level of the event, which you need to do in this case because it represents the position along the strip.

Thanks for the great suggestion and examples.

Unfortunately, due to my low level of skill and short timeframe (two weeks), I will have to do something a bit more manageable than that.
I was hoping the softpot would be a fairly straightforward solution, as I have to do some construction as well.

As it is, I am trying the solution by Riva, without much luck at the moment, but it looks more hopeful....

thanks for all your input.

helmutapplebaum:
As it is, I am trying the solution by Riva, without much luck at the moment, but it looks more hopeful....

For a start forget linking with processing and just run the below sketch and view the results in the serial monitor. Without touching the pot strip you should get a slightly fluctuating readings. After a few seconds make a note of the min/max values and let us know. When you press the strip the min/max reading should change.

int softPot = A0; 
int softPotReading = 0;
int minReading = 1024;
int maxReading = 0;

void setup() {
  Serial.begin(115200);
  softPotReading = analogRead(softPot);
  
}
void loop() {
  softPotReading = analogRead(softPot);
  if (softPotReading > maxReading){
    maxReading = softPotReading;
  }
  if (softPotReading < minReading){
    minReading = softPotReading;
  }
  
  Serial.print("MAX:");
  Serial.print(maxReading);
  Serial.print("\t");
  Serial.print("MIN:");
  Serial.println(minReading);
  delay(10);
}

just saw this, thanks, will try!

I was just sorting my other sensors - ir pairs, thanks for sticking with it.

Thanks,

When I first try your code, I get gibberish in the serial monitor. By changing the baud rate to 9600, I get sensible output.

Max values start anywhere between 800 and 200, and stay stable until touching a few times.
Min start just below Max and decreases quickly, then very slowly after 250

When I touch it, it sometimes eventually defaults to 1023 Max or 0 Min, and touching gives some Min (and sometimes Max) values (but not very responsive at all, and sometimes the values don't make complete sense) until it decides to stop working. Total Max and Min is 1023 and 27 (rest is hidden in corner).

I can still get it to work with my old code going to processing. The readings there are stable at about 250 (/4 in Arduino code) until I press, then they spit out a number in the 10-245 range (corner), and go back to 250. Works fine except for the speed , and anything over 245 I have do nothing,)

Ok, I think I see what the code is doing now, somehow the max or minReadings are sent in the next step?
Not 100% sure

It seems less responsive than the other code though....

The problem with rivas code, is that you are probably only looking at the device about once every 14 milliseconds. The impact even would come and go between readings, and you would not even know that it has happened.

The other issue that I can forsee, is that when there is an impact, the "wiper" contact of the pot is pushed against the long linear resistor, and will return the voltage, which at that point should be proportional along the length of the resistor.

it is not clear, what voltage will be present on the sensor terminal of the device at other times. It may be floating randomly if it is not in contact with anything. You may need to connect the sensor terminal to one of the other terminals of the device to provide a definite state when there is no contact - this is similar concept to using a pull-up or pull-down resistor on a switch.

Thanks,
That might explain the responsiveness issue, ....

BTW, there is no wiper, and the pot is not floating, so no problem there...

I don't care what you call it. The sensor contact of the device, what is it's voltage when there is no pressure on any part of it making contact with the resistor between the other two terminals ? I read through the datasheet for the device, it is very vague on that issue.

A quote from the datasheet you linked to:

SoftPot(TM) design and construction:
The SoftPot is simple: a wiper potentiometer that is sealed. It has three traces extending from the resistive active area, one acting as a wiper, another trace showing voltage from one side of the pot, and the third trace from the other side of the active area as diagramed.

So, there is no wiper. Hmm. OK.

Read on.

" The SoftPot operates as a voltage divider, once the top and bottom circuits close." Yeah ok.

".... sending resistance signals from the contact point in opposite directions using separate lower trace ". Eh ? This bit was written by an idiot.

Hey,

This works in the Arduino. So speed of sensor is not the issue.

//bildr.org/2012/11/touch-sliders-with-a-softpot-arduino/

int softpotPin = A0; //analog pin 0
#define LED 2

void setup(){
  digitalWrite(softpotPin, HIGH); //enable pullup resistor
  Serial.begin(115200);
  pinMode(LED,OUTPUT);
  digitalWrite(LED,LOW);
}

void loop(){
  int softpotReading = analogRead(softpotPin); 
  if (analogRead(softpotPin)>=1000){digitalWrite(LED,LOW);}
  if (analogRead(softpotPin)<=1000){digitalWrite(LED,HIGH);}
  Serial.println(softpotReading,DEC);
  //delay(10); //just here to slow down the output for easier reading
}

Now the issue ( as before) is getting it into processing.

Since I have other sensors, I have to have Processing and Arduino exchange bytes over serial so Processing knows when to start reading and storing the various sensors in an array.. That seems to be the blockage.

michinyon:
I don't care what you call it. The sensor contact of the device, what is it's voltage when there is no pressure on any part of it making contact with the resistor between the other two terminals ? I read through the datasheet for the device, it is very vague on that issue.

Yes, sorry, I am not always right in my terminology. I think most people use it with a physical wiper attached, I am just using the puck striking it. The voltage floats if there is no contact, so I have used a pullup resistor to fix it at 1024 until the puck strikes...

So, does communication between the arduino and processing work for other sensors, and not for this one ?

Or did you not get it working at all ?

The first time I used processing, I had quite a lot of trouble to get it to work. Mostly, getting the laptop to access the serial port.