compare sensor data range over time to shut off

I'm trying to compare if a sensor datas range stays the same over "x" amount of time, to do something. I'm kinda struggling on the syntax, so any help would be great. heres a basic ping sensor code I'm using:

int signalPin = 8;     // sensor signal pin connected to wiring pin 0
long elapsedtime = 0;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  elapsedtime = 0;
  pinMode(signalPin, OUTPUT);  // set signalPin as OUTPUT

  // Send 0-1-0 pulse to activate the sensor
  digitalWrite(signalPin, LOW);
  delayMicroseconds(2);
  digitalWrite(signalPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(signalPin, LOW);

  // Listen to pulse
  pinMode(signalPin, INPUT);               // set signalPin as INPUT
  elapsedtime = pulseIn(signalPin, HIGH);  // get the length of the pusle while it is HIGH

  // print value through Serial

  Serial.println(elapsedtime, DEC);
  delay(100);
}

Declare a variable to keep track of the last value read.
Declare a variable to keep track of the last time it changed.

After each reading, check it against the last read value. If it's different, set the last changed time to now.
Check how long it's been since it last changed, do whatever you want if it's greater than a given interval.

so i did a little quick mach up but i know I'm missing some key parts. I'm just confused on specific syntax to use. heres what i got:

boolean lastVal = 0;              //last reading
int change = 0;    

int sensorPin = 8;

if(sensorPin =! lastVal ){

//blink led or whatever action

}
else {

change //confused here on how to set the "change to now". use millis?

}
boolean lastVal = 0;              //last reading

Should be an int or short, unless the data that you are retrieving uses a library that returns a boolean.
int change = 0;
Time should be an unsigned long.

int sensorPin = 8;

Not necessary, but I was have this be a constant just to play it safe.

if(sensorPin =! lastVal ){

This says if the last value I read is not equal to the pin that I read my sensor from...
99.9999999% of the time, you're not going to be comparing a value to a sensor pin, so you'll need to read data from the pin, and compare it to that:

int value = digitalRead(sensorPin);
if (value =! lastVal) {
//blink led or whatever action
}
else {
change //confused here on how to set the "change to now". use millis?
}

You got the if/else blocks messed up. if the value is not the same as the last value, you want to reset the timer to the current time, and yes, use millis. If the values are the same, then you need to check if it's been long enough that an action should be performed.

how would i reset millis() ? how to apply it to sensor pin? I've read documentation and understand it, but i can't grasp how to apply it. to reset... and then it seems like i need some more logic?

how would i reset millis() ?

You don't. Why do you think you need to?

PaulS, im unclear then how to implement millis.

code thus far:

int lastVal = 0;
unsigned long change = 0;
int signalPin = 8;     
long elapsedtime = 0;

int led = 5;
void setup()
{

  Serial.begin(9600);
}




void loop()
{

  elapsedtime = 0;
  pinMode(signalPin, OUTPUT); 

  // Send 0-1-0 pulse to activate the sensor
  digitalWrite(signalPin, LOW);
  delayMicroseconds(2);
  digitalWrite(signalPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(signalPin, LOW);

  // Listen to pulse
  pinMode(signalPin, INPUT);               
  elapsedtime = pulseIn(signalPin, HIGH); 

  // print value through Serial

  Serial.println(elapsedtime, DEC);


  int valueCurrent = digitalRead(signalPin);
  if (valueCurrent =! lastVal) {  //should lastval be millis? 

    digitalWrite(led, HIGH); //do something

  }
  else {

    digitalWrite(led, LOW);

  }
}

danieljay:
how would i reset millis() ? how to apply it to sensor pin? I've read documentation and understand it, but i can't grasp how to apply it. to reset... and then it seems like i need some more logic?

Calling millis() returns the time it's been since the last reset. When you make a call like:

timeSinceChange = millis();

This is essentially a saying take a time stamp of right now and store it in the previously declared variable named timeSinceChange.

In your project specifically, you want to keep track of the last time the value has changed, so you need to set the "timestamp" whenever your reading is different from your last reading. If it is the same, you need to compare the time since the change (Hint: Millis() - timeSinceChange) to see if it's greater than a certain interval.

If it is the same, you need to compare the time since the change (Hint: Millis() - timeSinceChange) to see if it's greater than a certain interval.

i want to summarize that when this sensor value has not changed over a specific period of time, do something. I'm not understanding how what i quoted will do that. i may be wrong. i can't visually understand it.

danieljay:

If it is the same, you need to compare the time since the change (Hint: Millis() - timeSinceChange) to see if it's greater than a certain interval.

i want to summarize that when this sensor value has not changed over a specific period of time, do something. I'm not understanding how what i quoted will do that. i may be wrong. i can't visually understand it.

Here's an earlier project of mine that implemented pretty much exactly what you are asking:

If the garage door is left open for a certain period, action is taken.

int ultraSoundSignal = 8; // Ultrasound signal pin
int val = 0;
int oldDistance;
int newDistance;
int timecount; // Echo counter
int ledPin = 5;
int red = 9;
int blue = 10;
int count = 0;
unsigned long start, finished, elapsed;

void setup() {
 Serial.begin(9600);
 pinMode(ledPin, OUTPUT);
 int oldDistance = 0;
 pinMode(red,OUTPUT);
 pinMode(blue,OUTPUT);
//  oldDistance = read_the_sensor();
}
void displayResult()
{
  float h,m,s,ms;
  unsigned long over;
  elapsed=finished-start;
  h=int(elapsed/3600000);
  over=elapsed%3600000;
  m=int(over/60000);
  over=over%60000;
  s=int(over/1000);
  ms=over%1000;
  Serial.print("Raw elapsed time: ");
  Serial.println(elapsed);
  Serial.print("Elapsed time: ");
  Serial.print(h,0);
  Serial.print("h ");
  Serial.print(m,0);
  Serial.print("m ");
  Serial.print(s,0);
  Serial.print("s ");
  Serial.print(ms,0);
  Serial.println("ms");
  Serial.println();  
}

    void loop() {
      if(timecount > 0){
      digitalWrite(ledPin, HIGH);
    }

      oldDistance = read_the_sensor();
   
              delay(300);
      newDistance = read_the_sensor();
 

    //newDistance = timecount; //  echo pulse time to newDistance
    Serial.print("New Distance  = "); // Example identifier for the sensor
    Serial.print(newDistance);
    Serial.write(10);
    Serial.write(13);

    //oldDistance = timecount; //  echo pulse time to newDistance
    Serial.print("Old Distance  = "); // Example identifier for the sensor
    Serial.print(oldDistance);
    Serial.write(10);
    Serial.write(13);
    

    /* Lite up LED if any value is passed by the echo pulse
     * -------------------------------------------------------------------
     */
if (newDistance =! oldDistance){
    start=millis();
    delay(200); // for debounce    
    Serial.println("Started...");

    //digitalWrite(led, HIGH);
    
}else{
  
    
    finished=millis();
    delay(200); // for debounce
    displayResult();
    
}}
  
  
  
  //    //do our logic test
//    if(oldDistance > newDistance)
//      {
//        digitalWrite(red,HIGH);
//        digitalWrite(blue,LOW);
//      }
//      else
//    if(oldDistance < newDistance)
//      {
//        digitalWrite(red,LOW);
//        digitalWrite(blue,HIGH);
//      }
//
//    }



int read_the_sensor() {
timecount = 0;
val = 0;
pinMode(ultraSoundSignal, OUTPUT); // Switch signalpin to output

/* Send low-high-low pulse to activate the trigger pulse of the sensor
* -------------------------------------------------------------------
*/

digitalWrite(ultraSoundSignal, LOW); // Send low pulse
delayMicroseconds(2); // Wait for 2 microseconds
digitalWrite(ultraSoundSignal, HIGH); // Send high pulse
delayMicroseconds(5); // Wait for 5 microseconds
digitalWrite(ultraSoundSignal, LOW); // Holdoff

/* Listening for echo pulse
* -------------------------------------------------------------------
*/

pinMode(ultraSoundSignal, INPUT); // Switch signalpin to input
val = digitalRead(ultraSoundSignal); //  signal value to val
while(val == LOW) { // Loop until pin reads a high value
 val = digitalRead(ultraSoundSignal);
  }

while(val == HIGH) { // Loop until pin reads a high value
 val = digitalRead(ultraSoundSignal);
 timecount = timecount +1;            // Count echo pulse time
  }

return timecount;
}

I'm trying to disect your code, without much luck or understanding. am i on the right track with how I'm going about my sketch? something I'm missing? the time read just becomes continous and i want it to obviously change the second the new distance value changes. i know I'm missing somethingg quick but i can't get it.

This is the part of my code that relates to what you're doing:

unsigned long time = millis(); // Get the current time
  
if (garage.isClosed()) { // Check if the garage is closed 
  lastClosed = time; // It is, so set the time it was last read as closed to now
} else { // It's open, but we haven't tried to close it
  if ( (time - lastClosed) > (openTimeout * 1000) ) // Are we past out timeout for leaving it open
    tryToClose(); // We are, try to close it
}

trying to apply it to my code. not making sense. this is what i have:

//do our logic test
    if(oldDistance > newDistance)
      {
        digitalWrite(blue,HIGH);
      lastClosed = time;
      }
      else
    if((time - lastClosed) > (openTimeout ))
      {
       
        digitalWrite(blue,LOW);
      }

    }

danieljay:
trying to apply it to my code. not making sense. this is what i have:

//do our logic test

if(oldDistance > newDistance)
      {
        digitalWrite(blue,HIGH);
      lastClosed = time;
      }
      else
    if((time - lastClosed) > (openTimeout ))
      {
       
        digitalWrite(blue,LOW);
      }

}

Right now what that says is that if your readings are decreasing, then turn the LED on. If you're readings have increased or stayed the same for a certain amount of time, turn off the LED.

What exactly are you trying to accomplish with the LED?

i want the led off if the sensor reading stays at same value for "x" amount of time. if not, then i want it to be high. thats all. i can't get this logic down

when the sensor data stays the same over a range of time, turn led off. when it doesn't, turn on

when the sensor stays a certain range for "x" amount of time, turn off. else, leave on.

danieljay:
when the sensor stays a certain range for "x" amount of time, turn off. else, leave on.

So the only thing different about what you have and what you posted is you're are not looking for if the oldValue > newValue, you are looking for when they are not equal.