Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 4 of 4

Thread: attachInterrupt CHANGE - how to check if the change was a HIGH or LOW

  1. #1

    attachInterrupt CHANGE - how to check if the change was a HIGH or LOW

    I am using attachInterrupt on a teensy 3.2.
    Inside my interrupt function I need to know if the CHANGE was due to a pin going HIGH or LOW. Because inside the function then measure the time difference for the HIGH state and LOW state.

    Is it ok to do a digitalRead to get the pin state or will that not be accurate as the CHANGE already occurred?
    Would it be better to use two attachInterrupt(), one for FALLING and one for RISING?

    Thanks for any advice.

    Code:
    void setup(){
    attachInterrupt(digitalPinToInterrupt(HAND_INPUT), handInput_interrupt, CHANGE);
    }
    
    void handInput_interrupt() {
      pulse = digitalRead(HAND_INPUT);
    }

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,607
    digitalReadFast with a constant for the pin # will be good and fast to use :: pulse = digitalReadFast(HAND_INPUT);

    Depending on the initiator it might be bouncing? But if you track the prior state you can also toggle that yourself if every change is trapped. AFAIK there is only a single interrupt vector for each pin - so doing one of each won't work. If the pin input doesn't make a single clean transition - there will be multiple interrupts possible.

  3. #3
    Member
    Join Date
    Oct 2018
    Location
    London
    Posts
    55
    The name hand input suggests the use of a button press. If so, the action of pressing will cause signal bounce. If the purpose is to measure the time a user held the button, then the event will trigger FALLING and RISING a few times at the start and then a few times at the end of the press.

    The first fall will indicate the start of the press, but button press completion is a little trickier, since we don't know whether bouncing will still occur (implying contact). If we define the press release as the last time contact were made, then we can start a timer interrupt within the CHANGE interrupt to callback a short time after the last RISING event.

    FALLING events will kill the timer, and RISING event will start the timer afresh. A short time after the last RISING event we would receive the timeout callback signifying the end of the press.

    We could calculate the press timing by storing the timestamp of the first press FALLING event and update the timestamp of the the latest FALLING event. In the callback function we find the difference of the two.

    Before the press, the press timestamp is set to zero, when the value is non zero, we don't set this value again, since we are still within the press event period. We set the press timestamp to zero once we are in the callback function.

    To know which phase we are seeing (RISING / FALLING) for simple (clean digital) systems you might get away with toggling a boolean, since presumably we always receive both events in sequence. But, for noisy (or super fast) input, I couldn't say whether you could rely on always receiving a rise after a fall after a rise etc.

    As defragster stated you can't attach two interrupts to the same pin. But, you can connect two input pins together, attach the RISING interrupt to one pin and the FALLING interrupt to the other pin.

    defragster: What can you tell us about the reliability of events? Is it possible to receive two RISING events in a row without a corresponding FALLING event in between?

    Maybe this will be another experiment to play with tomorrow...

  4. #4
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,607
    Speculation and solving a potential problem can be fun - hopefully @stephanshulz can provide details - like if the input can bounce … what is the expected duration of the event?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •