Checking for Consecutive Values above a Threshold in IF statement

Hello, I am working with an IR Distance Sensor on my Arduino Uno. For some reason, every few seconds the IR value shoots up to a single high value, then drops back to accurately measuring distance. This is a problem because when that value exceeds a certain number, it sends a signal to a vibration motor. I was curious if there is a way to make an if statement that essentially says, "if the distance value is above 150 for three consecutive values, then send signal to vibration motor". The if statement I am working with is the if (detect_object>150) in the below code. I wasn't sure if this required a counter or not, I was hoping maybe it was simpler than that but that's really the only way I can think to do it with my limited knowledge, and even if I did that I'm not entirely sure how it would work. Very new to Arduino so sorry for the messy code...thanks for any and all help!

#include <Wire.h>

int sensorPin = 0; //analog pin 0
int detect_object = 0; //distance sensor 
int IR = 0;
boolean new_step = false;
int sensorValue = analogRead(A0);




void setup(){
  Serial.begin(9600); //speed of 9600 bps
  pinMode(10, OUTPUT); //pin 10 is outputting value
  Wire.begin(); // Initiate Wire library, join I2C bus as slave

}
void loop() 
{
  // Read the input on analog pin 0:
  int pressureValue = analogRead(A1);
  
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = pressureValue * (5.0 / 1023.0);
  
  // Print out the value you read:
 //Serial.println(voltage);
    
  if(voltage<4.9){new_step=true;
}

if(voltage>4.9 ){
if(new_step==true){
 int detect_object = analogRead(sensorPin); //analog read is distance sensor
Serial.println(detect_object); //display distance values in serial monitor
if (detect_object>150){ //if obstacle distance values < 6 inches (approximately)
  digitalWrite(10, HIGH); //set vibrator motor on
  delay(500); //pause for 1/2 second
  digitalWrite(10, LOW);//set vibrator motor off
  new_step=false;
}
}
}
}

Do you want a time delay between readings? Or should the readings be in quick succession?

If you know that the distance only changes at a steady rate you could ignore any value that was not within the expected range.

You could take 3 (or 5) readings and average them - or discard the outlier.

...R

No time delay, want the readings in quick succession if possible.

Robin2:
If you know that the distance only changes at a steady rate you could ignore any value that was not within the expected range.

You could take 3 (or 5) readings and average them - or discard the outlier.

...R

How would I go about this? I don't particularly know how to "discard an outlier" in my if statement, sorry, still super new to this. The problem is that the value will go that high when it reads an object in close range, but there's something off because it will be reading, say, 50, and the sensor will be sitting 5 cm from an object. And then about every 3 seconds, it will shoot up to 280 for one value, and then go back to 50. So my thought process was that if there is a way to check 3 of those values and make sure they are all 280, then I know that is the accurate value. As far as how to program that in...a little bit confused. Thanks for any and all help!!!

static int sensorReadFiltered( void )
{
  int rv;
  float v;

  rv = 0;

  for ( uint8_t i=3; i > 0; --i )
  {
    v = analogRead(A1) * (5.0 / 1024.0);

    if ( v > 4.9 )
    {
      ++rv;
    }
    else
    {
      --rv;
    }
  }
  
  return( rv );
}

The return value is > 0 if the voltage is > 4.9 two (or more) times out of three samples.

haleyking:
I don't particularly know how to "discard an outlier"

because it will be reading, say, 50, and the sensor will be sitting 5 cm from an object. And then about every 3 seconds, it will shoot up to 280 for one value,

Whatever the current (correct) value is I suspect the next correct value will only be a little bigger or a little smaller.

Suppose the current value is 50, or 230, then you cold do something like this

int maxError = 30;
newVal = analogRead(sensorPin);
if (abs(newVal - currentVal) < maxError) {
   // this is a correct value so use it
}

You can adjust maxError to suit your situation.

...R

You're taking analog reads from different pins and the ADC charges a capacitor. I've read a few threads that suggest taking 2 consecutive reads when it switches to another pin. When reading from a different pin than previous, the second read should be valid as the capacitor will be charged to the correct level.

Try this:

#include <Wire.h>

int sensorPin = 0; //analog pin 0
int detect_object = 0; //distance sensor
int IR = 0;
boolean new_step = false;
int sensorValue = analogRead(A0);

void setup() {
  Serial.begin(9600); //speed of 9600 bps
  pinMode(10, OUTPUT); //pin 10 is outputting value
  Wire.begin(); // Initiate Wire library, join I2C bus as slave

}
void loop()
{
  // Read the input on analog pin 0:
  int pressureValue = analogRead(A1);
  pressureValue = analogRead(A1);

  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = pressureValue * (5.0 / 1023.0);

  // Print out the value you read:
  //Serial.println(voltage);

  if (voltage < 4.9) {
    new_step = true;
  }

  if (voltage > 4.9 ) {
    if (new_step == true) {
      int detect_object = analogRead(sensorPin); //analog read is distance sensor
      detect_object = analogRead(sensorPin); //analog read is distance sensor
      Serial.println(detect_object); //display distance values in serial monitor
      if (detect_object > 150) { //if obstacle distance values < 6 inches (approximately)
        digitalWrite(10, HIGH); //set vibrator motor on
        delay(500); //pause for 1/2 second
        digitalWrite(10, LOW);//set vibrator motor off
        new_step = false;
      }
    }
  }
}