Time between two pulses not accurate

im trying a code which measures time between 2 pulses of square waves , but the ideally the delay between the pulses should be zero ( no phase shift given) still the delay is between -4us to 8 us .`


enum MeasurementState {

  WAIT_FOR_PIN2_LOW,

  WAIT_FOR_PIN2_RISING,

  WAIT_FOR_PIN3_LOW,

  WAIT_FOR_PIN3_RISING,

  CALCULATE_DELAY,

  RESET_STATE

};

MeasurementState state = WAIT_FOR_PIN2_LOW;

const unsigned long timeoutMs = 5000;  

unsigned long previousMillis = 0;  /

unsigned long time1 = 0;  // timestamp of pin 2 rising edge (micros)

unsigned long time2 = 0;  // timestamp of pin 3 rising edge (micros)

void setup() {

  Serial.begin(115200);

  pinMode(2, INPUT);

  pinMode(3, INPUT);

  previousMillis = millis();
}

void loop() {

  unsigned long currentMillis = millis();

  switch (state) {

    case WAIT_FOR_PIN2_LOW:


      if (digitalRead(2) == LOW) {

        state = WAIT_FOR_PIN2_RISING;

        previousMillis = currentMillis;

      }

     

      else if (currentMillis - previousMillis > timeoutMs) {

        Serial.println("Timeout in WAIT_FOR_PIN2_LOW, retrying...");

        previousMillis = currentMillis;
      }

      break;

    case WAIT_FOR_PIN2_RISING:

 

      if (digitalRead(2) == HIGH) {

        time1 = micros();

        Serial.print("Pin 2 rising edge at: ");

        Serial.print(time1);

        Serial.println(" us -> WAIT_FOR_PIN3_LOW");

        state = WAIT_FOR_PIN3_LOW;

        previousMillis = currentMillis;

      }

      else if (currentMillis - previousMillis > timeoutMs) {

        Serial.println("Timeout in WAIT_FOR_PIN2_RISING, resetting...");

        state = WAIT_FOR_PIN2_LOW;

        previousMillis = currentMillis;
      }

      break;

    case WAIT_FOR_PIN3_LOW:

      // Wait until pin 3 is LOW

      if (digitalRead(3) == LOW) {

        Serial.println("Pin 3 is LOW -> WAIT_FOR_PIN3_RISING");

        state = WAIT_FOR_PIN3_RISING;

        previousMillis = currentMillis;

      }

      else if (currentMillis - previousMillis > timeoutMs) {

        Serial.println("Timeout in WAIT_FOR_PIN3_LOW, resetting...");

        state = WAIT_FOR_PIN2_LOW;

        previousMillis = currentMillis;
      }

      break;

    case WAIT_FOR_PIN3_RISING:

      // Wait for pin 3 to go HIGH (rising edge)

      if (digitalRead(3) == HIGH) {

        time2 = micros();

        Serial.print("Pin 3 rising edge at: ");

        Serial.print(time2);

        Serial.println(" us -> CALCULATE_DELAY");

        state = CALCULATE_DELAY;

      }

      else if (currentMillis - previousMillis > timeoutMs) {

        Serial.println("Timeout in WAIT_FOR_PIN3_RISING, resetting...");

        state = WAIT_FOR_PIN2_LOW;

        previousMillis = currentMillis;
      }

      break;

    case CALCULATE_DELAY:

      {

        long delayTime = (long)time2 - (long)time1;

        long finalDelay = 1000000 - delayTime;

        Serial.print("Delay: ");

        Serial.print(finalDelay);

        Serial.println(" us");

        state = RESET_STATE;

        previousMillis = currentMillis;
      }

      break;

    case RESET_STATE:

     

      if (currentMillis - previousMillis > 1000) {

        state = WAIT_FOR_PIN2_LOW;

        previousMillis = currentMillis;
      }

      break;

    default:

      
      state = WAIT_FOR_PIN2_LOW;

      previousMillis = currentMillis;

      break;
  }
}

According to the code the delay expected is a 100 ms rather than zero.

Taking in account that a minimal interval that can be measured with micros() is a 4us, your result is rather adequate.

That is true for 16MHz AVR Arduino. Is it true for Due?

oops
I always forget to look in which category the question is posted

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.