Speed Calculator Project

So I am trying to get my Speed Calculator to work but I having some trouble. The two sensors I am using (one digital PIR sensor and one analog PIR sensor) seem to keep detecting motion after a vehicle or person or whatever passes. So in my case the digital sensor will create extra pulses after motion is detected so I basically need to delay it but I can’t delay(500); because that stops the whole program which I need for the next sensor detection. So I need to delay without using delay(). I was thinking to use either a do…while with millis() or something along those lines.

The idea would to delay 400-500 ms so the sensor can settle and thus return to the original loop. The code below is in progress so I apologize for poor coding skills as I am not an expert at this, yet. If anyone can shed some light on how to delay without using delay(). Also I have looked at blink without delay tutorial and either I can’t apply or it doesn’t work with my system.

void loop() {
  
  lcd.setCursor(0,0);

  analogVal = analogRead(A0);
  delay(10);
  digitalVal = digitalRead(digitalPin);
  delay(10);
  
  if (analogVal <= 400 || analogVal >= 600) {
    
        t0 = micros();
        String message1 = "Analog Detected";
        Serial.println(message1);
        
        do {
         
        unsigned long currentMillis = millis();
          
        }
        
        while (currentMillis - previousMillis > 3000){  //wait 3s until Analog Pin is stable
        
        previousMillis = currentMillis;
        
        newAnalog = analogRead(analogPin); // check to see motion is done
        newAnalogVal = newAnalog + 500; // absolute value idea
                
            if (newAnalogVal < 600){ // conditional for check case
            }
        }
        
        computeData_0();
  }
 
    
  else if (digitalVal == HIGH) {
        
        unsigned long timeout1 = 0;
        timeout1 = millis();
        
        t1 = micros();
        
        String message2 = "Digital Detected";
        Serial.println(message2);
        
        if (millis()  - timeout1 > 3000){ // wait 3s until Digital Pin is LOW
        
        newDigital = digitalRead(digitalPin); // Check to see that digital sensor is done detecting
          
          if (newDigital == LOW){    
          }
          
    }
          computeData_1();  
}

Here is the datasheet for the sensors and i am using an Arduino Leonardo

Spot Detection Type (both digital and analog)

Have you tried putting the digital sensor code inside an IF statement that tests for the passage of 500mS based on values returned from millis() ? (using an elapsed time variable that you read millis() into )

There are a couple of ways you could tackle this problem.

If you know which order you expect the two events to occur, you can use a simple blocking approach. This is simplest to understand but gives you a fairly restrictive solution. Restructure your code so that it works like this:

Wait for first input event to occur. Record time of first event. Wait for second input event to occur. Record time of second event. Do any calculations you need from these times. Wait long enough for both sensors to have returned to idle state.

The second approach is to use a non-blocking approach. This is a bit more complicated but gives you a much more powerful solution. With this approach you would poll both inputs, and use the sort of logic demonstrated in the debounce example sketch to ignore subsequent changes in the input until it had settled.

So the idea is to create a system that can detect either directions first so I could tell where the vehicle is coming from (i.e which direction), the speed, and vehicles/min. But back to the original question, would the code below effectively work in my scenario.

void loop() {
  
  lcd.setCursor(0,0);

  analogVal = analogRead(analogPin);
  delay(10);
  digitalVal = digitalRead(digitalPin);
  delay(10);
  
  if (analogVal <= 400 || analogVal >= 600) {
    
        t0 = micros();
        String message1 = "Analog Detected";
        Serial.println(message1);
        
        timeout0 = millis(); //timestamp for delay
        
        if ((millis() - timeout0) > 400){ // wait 400ms until Analog Pin is LOW
        
        newAnalog = analogRead(analogPin); // check to see motion is done
        newAnalogVal = newAnalog + 500; // absolute value idea
                
            if (newAnalogVal < 600){ //check case to see if analogRead is below 600
            }
        }
        
        computeData_0();
  }
 
    
  else if (digitalVal == HIGH) {
        
        String message2 = "Digital Detected";
        Serial.println(message2);
        t1 = micros(); //timestamp for calulating speed, concentration
        timeout1 = millis(); //timestamp for delay
        
        if ((millis()  - timeout1) > 400){ // wait 400ms until Digital Pin is LOW
        
        newDigital = digitalRead(digitalPin); // Check to see that digital sensor is done detecting
          
          if (newDigital == LOW){ // Once LOW, compute our data    
          }
          
    }
          computeData_1();  
}

So my if ((millis() - timeout1) > 400){ should keep taking a timestamp until its greater than 400ms then sample the analogRead/digitalRead pins to see if the sensor is still HIGH or in the analog case over the the threshold voltage. Once LOW or below my threshold, I go into my computeData() function which computes a bunch of data.

Is this correct in my thinking? Will the above code do this?

niema045:
I could tell where the vehicle is coming from (i.e which direction), the speed, and vehicles/min

Will the above code do this?

No, I don’t think so.

I think you want to detect the initial rising edge for each input, and record the time it happens, and then when you have seen both rising edges compare the two times to work out direction and speed. Then wait for long enough for both inputs to settle, and finally go back to the idle state where you’re looking for the next rising edge. It could look roughly like this:

// incomplete, uncompiled

int leftValue = analogRead(leftSensorPin);
if((leftTime == 0) and ((leftValue < 400) or (leftValue > 600)))
{
   // left pulse detected
    leftTime = millis();
}
if((rightTime == 0) and (digitalRead(rightSensorPin) == HIGH))
{
    // right pulse detected
    rightTime = millis();
}
if((leftTime > 0) and (rightTime > 0))
{
    // both signals detected, determine direction and speed
    speed = distance / (rightTime - leftTime); //positive speed means left-to-right, negative means right-to-left
    count++; // I don't know whether you want to count each direction separately

    delay(500); // wait long enough for both sensors to settle down
    leftTime = 0;
    rightTime = 0;
}