Count Number of Times Finger Taps Force Resistor?

Hi I am new Arduino user so please forgive me if I haven’t explained or formatted something properly.

I have a force resistor hooked up to my Arduino UNO, with an LED. I want to count the rate at which my finger taps the force sensor after a minute. The main problem I have is that when I press the sensor, multiple samples have a nonzero value for each sensor press, causing the count of finger taps to be skewed. Ideally, I would be able to count the number of peaks in the serial plotter output. Any idea of how I can do this? Here is what I am currently working with:

Thanks!!

//Constants:
const int ledPin = 3;     //pin 3 has PWM funtion
const int sensorPin = A0; //pin A0 to read analog input

//Variables:
int value; //save analog value
int start;
unsigned int count = 0;

void setup() {
  pinMode(ledPin, OUTPUT);  //Set pin 3 as 'output'
  Serial.begin(9600);       //Begin serial communication
}

void loop() {
  value = analogRead(sensorPin);       //Read and save analog value from potentiometer
  //Serial.println(value);               //Print value
  value = map(value, 0, 1023, 0, 255); //Map value 0-1023 to 0-255 (PWM)
  analogWrite(ledPin, value);          //Send PWM value to led
  delay(100);                          //Smal

  if (analogRead(sensorPin) > 600)
  {
    Serial.println("Beginning Count... ");
    start = millis(); // take the start time
    count = 0; // reset couter
    while (millis() - start < 6000)
    {
      if (analogRead(sensorPin) > 0)
      {
        count++;
        value = analogRead(sensorPin);       //Read and save analog value from potentiometer
        Serial.println(value);
        //Serial.println(value);               //Print value
        value = map(value, 0, 1023, 0, 255); //Map value 0-1023 to 0-255 (PWM)
        analogWrite(ledPin, value);          //Send PWM value to led
        //delay(100);                          //Smal
      }
      delay(100);
    }
    Serial.println("Total Count Is: ");
    Serial.print(count);
    delay(500);
    analogWrite(ledPin, 0);
    exit(1);
  }
  else
  {
    Serial.println(analogRead(sensorPin));
  }
}

You seem to be reading the analog value multiple times when, I suspect, you should read it once and save the value. For example in this piece

if (analogRead(sensorPin) > 0)
      {
        count++;
        value = analogRead(sensorPin);

the number used in the IF will be different from the number stored in the variable value

I suggest you do this

 value = analogRead(sensorPin);
 if (value > 0)
      {
        count++;

...R
Edited to remove a superfluous ) as pointed out in Reply #2

... except that the syntax is wrong, and also that value is always updated.

Syntax should be

  value=analogRead(sensorPin);
  if (value>0)
    {
      count++;
      // et cetera
    }

If it is undesirable to update value, then another variable should be introduced.

What does your serial output look like?

Among other things, I'm wondering if tapping the sensor once actually sends it a "shockwave" so it has a peak, and then lesser readings and then you're counting each of those lesser readings as a "tap".

E.g. your readings look like
100
0
20
0
10
0
0
0
0

and you're counting the "20" and the "10" and you shouldn't be. As a hack, maybe look at typical readings, and only count something as a tap if it's above some threshhold.

I also don't understand entering that one loop if you get a reading about 600. What is that. . .like you're going to start counting if you "start it" with a heavy press?

Here is the circuit I used (from Instructables)

FOTPUUBIEV84N5O.MEDIUM.jpg

You see this line. . .

//Serial.println(value); //Print value

change it to

Serial.println(value); //Print value

You'll see your values. This will give you an idea of what's going on.

Thanks for the responses!

The problem with setting a threshold is that there is often a series of output values/a curve associated with a press - so for example, for a single press I might get (from the serial monitor)

0
0
0
(press now)
300
350
348
250
(finger removed)
0
0
0

The difference between say, 350 and 348 is so minute that it's hard to set a reasonable threshold that can yield an accurate count. In the above hypothetical serial monitor output, I would get a count of 4, when in reality I want a count of one. The serial plotter output however, would be a curve - with a peak at 350.

Is there a peak count function/existing code I could use?

I get it. The problem is not a "shockwave". It's that your "tap" is so long that it keeps registering it as separate taps.

Well, there's a few ways to handle it. A way I don't like is to build a delay into the reading once the button has been pressed to give you time to take your finger off it.

But, what you really want is this :

  1. count a press when the sensor is pressed.
  2. don't count another press until I take my finger off and press again.

The question is how to handle that in code.

What you want is something like

boolean bHasReset = true;

setup() {//do stuff}

loop()
{

//read sensors and stuff

  if (value > 0) 
  { 
     if (bHasReset)
     {
        count++;
        bHasReset = false;
     }   
 }
 else  //value now equals 0
 {
   bHasReset = true;
 }
}

So, your program is going to start. bHasReset is true.

It's going to be running along with "value = 0;"

When you press the button, value goes to 300 and you go into the "if".

bHasReset is true. Counter is increased. bHasReset is false.

now, when it comes back around, it reads 350, and it goes into "if (value >0)", but now, bHasReset is false so it doesn't increase count.

Now, it goes to 348, same thing. Now, it goes to 250, same thing.

Now, it goes to 0 and bHasReset goes back to "true" and next time you press, it's going to go back into the counter.

I haven't tested this. That should work, though.

That's a good lesson in why you should look at your data. I thought it was "shockwaves". That's a totally different problem than what you have.

Also, there's a tighter way to write that ode. My way is just an explicit way to show it.