Measure time between rising and falling edge

Hi,

I am trying to measure the time between the rising and falling edge on the pin D2. I have attached a Sharp GP2Y0D815Z0F and it works quite good despite the bouncing.
Now i would like to know how long I hold my hand in front of the sensor. So i tried to use the interrupt function.

My current code:

unsigned long lastTriggerTime;
volatile unsigned long triggerTime;
volatile boolean triggered;
volatile boolean lastState;

void isr () 
{
  // wait until we noticed last one
  if (triggered)
    return;

  triggerTime = micros ();
  triggered = true;
}  // end of isr

void setup() 
{
  pinMode (D2, INPUT);  
  attachInterrupt(D2, isr, CHANGE);   
  Serial.begin (115200);
  Serial.println ("Started timing ...");  
}  // end of setup

void loop() 
{
  if (triggered == true && lastState == 0){
    
  
  unsigned long elapsed = triggerTime - lastTriggerTime;
  
  if (elapsed < 1000000L)
    {
    triggered = false;
    return;  // ignore if less than a second
    }
    
  lastTriggerTime = triggerTime;
  triggered = false;  // re-arm for next time
  lastState = 1;
  
  Serial.print ("Took: ");
  Serial.print (elapsed);
  Serial.print (" microseconds. ");
  
  unsigned long minutes, seconds, ms;
  
  minutes = elapsed / (1000000L * 60);
  elapsed -= minutes * (1000000L * 60);
  
  seconds = elapsed / 1000000L;
  elapsed -= seconds * 1000000L;
  
  ms = elapsed / 1000;
  elapsed -= ms * 1000;
  
  Serial.print (minutes);
  Serial.print ("m ");
  Serial.print (seconds);
  Serial.print ("s ");
  Serial.print (ms);
  Serial.println ("ms.");
  }
}  // end of loop

I am not really shure if it is doing what i would like to achieve. Or maybe there is a much simpler solution.
I think I am missing three possible combinations of triggered and lastState:
if (triggered == true && lastState == 0) //already done
if (triggered == true && lastState == 1)
if (triggered == false && lastState == 0)
if (triggered == false && lastState == 1)
But I think that my code should work for the first time I put my hand in front of the sensor.
I would be very grateful if you could have a look at my code and give me some advice :smile:

Kind regards,
Tom

Take a look at this topic

thank you very much for your pointer! However it does not seem to work properly.

My code:

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

    Serial.println("Setup");
    pinMode(D2, INPUT);     

}

void loop() {
    
    long duration;
    duration = pulseIn(D2, HIGH);
    
    Serial.print(duration);
    Serial.println(" ms");

}

/* 
 * pulseIn Function for the Spark Core - Version 0.1.1 (Beta)
 * Copyright (2014) Timothy Brown - See: LICENSE
 *
 * Due to the current timeout issues with Spark Cloud
 * this will return after 10 seconds, even if the
 * input pulse hasn't finished.
 *
 * Input: Trigger Pin, Trigger State
 * Output: Pulse Length in Microseconds (10uS to 10S)
 *
 */

unsigned long pulseIn(uint16_t pin, uint8_t state) {
    
    GPIO_TypeDef* portMask = (PIN_MAP[pin].gpio_peripheral); // Cache the target's peripheral mask to speed up the loops.
    uint16_t pinMask = (PIN_MAP[pin].gpio_pin); // Cache the target's GPIO pin mask to speed up the loops.
    unsigned long pulseCount = 0; // Initialize the pulseCount variable now to save time.
    unsigned long loopCount = 0; // Initialize the loopCount variable now to save time.
    unsigned long loopMax = 20000000; // Roughly just under 10 seconds timeout to maintain the Spark Cloud connection.
    
    // Wait for the pin to enter target state while keeping track of the timeout.
    while (GPIO_ReadInputDataBit(portMask, pinMask) != state) {
        if (loopCount++ == loopMax) {
            return 0;
        }
    }
    
    // Iterate the pulseCount variable each time through the loop to measure the pulse length; we also still keep track of the timeout.
    while (GPIO_ReadInputDataBit(portMask, pinMask) == state) {
        if (loopCount++ == loopMax) {
            return 0;
        }
        pulseCount++;
    }
    
    // Return the pulse time in microseconds by multiplying the pulseCount variable with the time it takes to run once through the loop.
    return pulseCount * 0.405; // Calculated the pulseCount++ loop to be about 0.405uS in length.
}

Do you have any idea?

Edit: I think it works but I have to debounce the sensor.

Edit 2: I didn’t have any luck so far :frowning:

The code seems to output random numbers when I put my hand in front of the sensor. I am also not exactly sure what the pulseIn code does. So any help would be greatly appreciated :smile:

Output:

0 ms
0 ms
0 ms
0 ms
0 ms
0 ms
1085424 ms
1087 ms
1701 ms
1700 ms
1702 ms
10203 ms
431 ms
1701 ms
552 ms
1695 ms
454 ms
1701 ms
1695 ms
3401 ms
481574 ms
1700 ms
1698 ms
11911 ms