Go Down

Topic: how fast a contact can a linear soft potentiometer detect? (Read 4 times) previous topic - next topic


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.


Mar 10, 2014, 10:40 pm Last Edit: Mar 10, 2014, 10:58 pm by helmutapplebaum Reason: 1

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

Code: [Select]


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

void setup(){
 digitalWrite(softpotPin, HIGH); //enable pullup resistor

void loop(){
 int softpotReading = analogRead(softpotPin);
 if (analogRead(softpotPin)>=1000){digitalWrite(LED,LOW);}
 if (analogRead(softpotPin)<=1000){digitalWrite(LED,HIGH);}
 //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.


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.


Test Setup

Arduino Uno, 1 Linear Softpot and multiple IR sensors (1 for test), both to detect air hockey puck striking walls.
Arduino sends sensor data to Processing over serial in bytes (9600), Processing sorts multiple values into array.
Processing sends a byte to Arduino for each reading of array of multiple sensors to keep them in order.

I got the Softpot and ir sensors to send data to Processing almost immediately, so I thought I was home free!

What Works
Both SoftPot and IR sensors work separately when tested in Arduino with Led and serial monitor.

Arduino and Processing
When I press the softpot with the puck, it registers in Arduino and Processing, ...same with IR.
However, when I strike the softpot with the puck (as in normal play) it does not register 90% of the time.
See 1st video above...

My conclusion is that it strikes too quickly, and the reading is lost somewhere between the Arduino and Processing. I believe it is a combination of baud rate and serial "handshake" time

Baud Rate
Upping the baud rate to 115200 in Arduino makes the puck register on the softpot when striking rapidly, so no problems there.
See 2nd Video above....

Arduino to Processing "Handshake" for sorting multiple sensor readings to Processing Array
I believe the culprit is the fact that processing and the arduino have to exchange a byte over serial to begin reading the multiple sensors into a processing array. I am using this code;

As Riva said, perhaps it is sending too many bytes, more than required? Perhaps if it just does so at beginning, then all data is synced in order,  I can stop sending and 'A' for each array of data?

Code: [Select]

void serialEvent(Serial myPort) {
// read a byte from the serial port:
int inByte = myPort.read();
// if this is the first byte received, and it's an A,
// clear the serial buffer and note that you've
// had first contact from the microcontroller.
// Otherwise, add the incoming byte to the array:
if (firstContact == false) {
if (inByte == 'A') {
  myPort.clear();   // clear the serial port buffer
  firstContact = true;  // you've had first contact from the microcontroller
  myPort.write('A');  // ask for more
else {
// Add the latest byte from the serial port to array:
serialInArray[serialCount] = inByte;
// If we have 3 bytes:
if (serialCount > 2 ) {
  xpos = serialInArray[0];
  ypos = serialInArray[1];
  fgcolor = serialInArray[2];
  // print the values (for debugging purposes only):
  println(xpos + "\t" + ypos + "\t" + fgcolor);
// Send a capital A to request new sensor readings:
  // Reset serialCount:
  serialCount = 0;

// Send a capital A to request new sensor readings:

Might this be the problem? (along with 115200 baud rate needed). Is this baud rate ok with bytes?


Mar 11, 2014, 10:21 am Last Edit: Mar 11, 2014, 11:06 am by Riva Reason: 1

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 code was not meant for talking to processing but to just display an idea of what the dead range of an untouched pot strip is. If the readings hovered around 1024 end of the scale the min value would be put into the other code threshold (and code altered to read less than). If it hovered at the 0 end then max would be used as threshold. And if it sat in the middle then the code would need to check for values above or below the min/max (dead zone) range. From the values you posted the results are inconclusive.

EDIT: After further reading I now see why you needed to turn on internal pullup. Increasing baud rate to 115200 increases serial communications considerably.
What other sensors (and how many) are you talking about and what readings are you expecting from them. For example, with the soft pot do you want to just register a hit (yes/no) or do you need the analogue read value to determine where the puc hit?
The way you send data over serial will make a vast difference to serial speed. Doing 'Serial.println(softpotReading,DEC);' will be sending between 3 & 5 bytes of data (1- 3 for reading between 0 & 999 + CR + LF). Sending the same data as a pure int value makes it only 2 bytes. If you need the serial reading but are not to bothered with high accuracy you could divide it by 4 so it fits in a single byte. Going further than this, if you only need yes/no answers from your sensors then you can send 8 sensors in 1 byte by doing bit packing.


That's great stuff!
The info you have supplied is very interesting.

Yes, I do need the number value for the softPot, and no, it does not need to be accurate, so I will try the /4 in a byte.
I would like 8 other IR sensors with digital readings (0 and 1 only). bit packing sounds great.
So maybe I can get it down to 2 bytes (1 for SoftPot value 0-255, and 8 binary values?

Just to recap, I have tried the sensor in 115200, and it registers fast hits in Arduino alone (led display). so some progress..... :)

So far I have tried the following with processing;
1. Serial Call and Response
My original code - Tried with SoftPot and IR, 9600 - will try 115200 and just SoftPot, but I suspect by its nature it will not work, though the code seems to be sending just one byte? softPotReading = analogRead(softPot)/4; (1 byte?)
Try with eliminate byte call and response?
2. Basic Serial Send
Serial.println(softPotReading,DEC); (3 & 5 bytes of data)
Works, not fast enough 90% of time (tried 115200)
Try with softPotReading = analogRead(softPot)/4; (1 byte?)?
3. Split on String (multiple sensors)
(halfway down page - non firmata code)
Works, not fast enough 90% of time (tried 115200)
Try - Changing it would probably make it a basic serial send of byte - check against above...
4. Firmata
(IS this any good?)

Thanks for your persistence


Mar 11, 2014, 05:08 pm Last Edit: Mar 11, 2014, 05:59 pm by helmutapplebaum Reason: 1
I feel so close!

I have code that works with bytes, If I can make it efficient, I can determine once and for all if the puck is just too fast for the serial connection to processing.

I am running at 115200 and can detect the fast puck strike in Arduino according to the led.

In processing,  I have some interesting values for the sensor (below 0 resting,... 128 in middle right to 0 on input side, then -128 in the middle left to -0 on the far side), but I can tell that is just something silly I am doing. Otherwise I can see that touch position is detected along the pot, but a fast puck strike does not show up.

Here is the Arduino code;
Code: [Select]
int led = 2;
int softPot = A0; //analog pin 0
int softPotReading = 0;

void setup() {
 digitalWrite(softPot, HIGH);

void loop() {
 if (analogRead(softPot)>=1000){digitalWrite(led,LOW);}
 if (analogRead(softPot)<=1000){digitalWrite(led,HIGH);}
 softPotReading = analogRead(softPot)/4;

And here is the Processing code;

Code: [Select]
Serial myPort;
//int psoftPot = 0;
int psoftPotReading = 0;
color c = color(0,0,0);

void setup() {
 size(1000, 500);
 myPort = new Serial(this, Serial.list()[0], 115200);

void draw(){
  byte[] inBuffer = new byte[1];
  while (myPort.available() > 0) {
  inBuffer = myPort.readBytes();
  if (inBuffer != null) {
     psoftPotReading = inBuffer[0];
      if (psoftPotReading<=0) {background(100,100,100);} //refresh at softPot resting value
      else if (psoftPotReading>=100 && psoftPotReading<=128){ fill(c); rect((width-width/10),400,100,100);}
      else if (psoftPotReading>=90 && psoftPotReading<=99){ fill(c); rect((width-(2*(width/10))),400,100,100);}
      else if (psoftPotReading>=80 && psoftPotReading<=89){ fill(c); rect((width-(3*(width/10))),400,100,100);}
      else if (psoftPotReading>=70 && psoftPotReading<=79){ fill(c); rect((width-(4*(width/10))),400,100,100);}
      else if (psoftPotReading>=60 && psoftPotReading<=69){ fill(c); rect((width-(5*(width/10))),400,100,100);}
      else if (psoftPotReading>=50 && psoftPotReading<=59){ fill(c); rect((width-(6*(width/10))),400,100,100);}
      else if (psoftPotReading>=40 && psoftPotReading<=49){ fill(c); rect((width-(7*(width/10))),400,100,100);}
      else if (psoftPotReading>=30 && psoftPotReading<=39){ fill(c); rect((width-(8*(width/10))),400,100,100);}
      else if (psoftPotReading>=20 && psoftPotReading<=29){ fill(c); rect((width-(9*(width/10))),400,100,100);}
      else if (psoftPotReading>=10 && psoftPotReading<=19){ fill(c); rect((width-(10*(width/10))),0,100,100);}
  //bitpacking for IRs?

If I can troubleshoot any glaring errors in the code above, I can have a definitive test I think....
I wonder if I can eliminate the buffer.


Wont have time to look at your code tonight (maybe tomorrow at work) but if it registers on the LED then it should register in processing if your sending the correct data.

Another way to improve things may be to send data when values change from last time they were sent.


You could speed up the Arduino code a tiny bit by only reading the analogue once instead of the three times you read it now.
Code: [Select]
int led = 2;
int softPot = A0; //analog pin 0
int softPotReading = 0;

void setup() {
  digitalWrite(softPot, HIGH);

void loop() {
  softPotReading = analogRead(softPot) >> 2;
  if (softPotReading >= 1000){
  else {

In processing,  I have some interesting values for the sensor (below 0 resting,... 128 in middle right to 0 on input side, then -128 in the middle left to -0 on the far side), but I can tell that is just something silly I am doing. Otherwise I can see that touch position is detected along the pot, but a fast puck strike does not show up.

I'm not so good with processing but the negative values are probably because your using the wrong data type. psoftPotReading should maybe be defined as unsigned. The value you get from the arduino soft pot may not be a true reflection of where or how hard the puc hit as it depends on when in the process of the puc hitting the ADC happens.

As I say I'm not very good on processing but could you put the serial read in serialEvent and just leave the draw() routine to continually update from your buffer if data has changed.


Thanks for your attention to this.

I think I'm coming to the end of it, I will try the things you just mentioned, then move on to firmata and see if that works instead.


My choice has just been made easier.

I tried firmata and the test code fried my softpot. :( :( :(

I'm on to my fallback position of IR pairs, which I cannot get to go above 4 pair :(
Subject of another topic....

Many thanks to those who helped on this one, I will be reccing you appropriately. :)





Hi, you may find this thread interesting, I only just saw this subject about the soft pot today, and I have not been able to see anybody referring to INTERRUPT.
The problem as I understand it is, that a fast bump is being detected by the sensor, but because the sketch is not looking at the input at the right time it is not detected.

Two solutions
1) You build a circuit that takes the output of the sensor and when triggered, produces a fixed output pulse, so no matter how short or long the hit, it will produce a single pulse output long enough for the timing of the arduino, this circuit is called a monostable timer/oscillator.
2) Program an Interrupt on the analog input pin, this way when ,at anytime, there is an input the program is Interrupted and the input read and stored, then the program goes back to what it was doing.

I am no expert on interupts but the topic may help.

Tom...... :)
Everything runs on smoke, let the smoke out, it stops running......VK3DMK

Go Up