Approach to detect sequential interrupts

Hi all wonderful people,

I am looking for guidance on logic to detect sequential signals coming on two different interrupt lines. Some examples of a valid signal sequence is shown in attached image. Here are some key details:

  1. The two signals are connected to D2 and D3 external interrupt pins on an UNO.
  2. The first pulse (either red or blue) wakes up the microcontroller and usually has a width between 100-400ms.
  3. The rising edge of the followup pulse should be within 1000 ms of the preceding rising edge for the entire sequence to be considered valid (alternatively should be within 30ms of the preceding trailing edge, however this is tricky to program as the order of two pulses is not fixed).

Here's what I have tried (unsuccessfully) so far:

Approach 1

  • attach both interrupts to detect the rising edge of the pulse
  • in corresponding ISR, detach the second pending interrupt
  • poll the second interrupt line for line change
  • return true condition if line change is detected withing 1000 ms <---this fails as I am using millis() which doesn't increment inside the ISR function.

Approach 2

  • Get current millis() in respective ISR - I realize this is not most accurate timekeeping, but it may be acceptable as I am working with pretty slow signals.
  • Keep a running difference of the two interrupts calls and if its less than 1000ms, qualify as a valid input
  • this approach suffers from two drawbacks
  1. uses loop() to keep a running total - this could be fixed
  2. in some edge cases, when an odd number of pulses show up in a valid sequence, this logic breaks (an example is shown in below image).

I have attached the .ino files for two approaches. I am looking for high-level guidance on how to approach this problem - may be there are better tools available that I am not aware of or known strategies to tackle such conditions.

I appreciate the help in pointing me in the right direction.

Thanks in advance.

approach_1.ino (4.43 KB)

approach_2.ino (2.36 KB)

What is generating the pulses?
What is the purpose of detecting them?

It is much easier to offer sensible advice when we know what the project is all about.

Is it possible for there to be two successive red (or blue) pulses before a valid blue (or red) pulse?

...R

Apologies for lacking details.

What is generating the pulses? It is much easier to offer sensible advice when we know what the project is all about.

I am trying to detect output of a window comparator - the blue line is pulled low when the analog signal is above high threshold (0.8Vcc) and red line is low when the signal drops below the low threshold (0.1Vcc). The analog signal is amplified output of a PIR sensor.

Is it possible for there to be two successive red (or blue) pulses before a valid blue (or red) pulse?

What is the purpose of detecting them??

A valid sequence - like the ones shown in the first image - will trigger a motor to actuate a pump.

It is possible, albeit rare - however this is an easier edge case as the interrupt will re-trigger on the second pulse.

thanks for asking the questions.

Considering the long length of the pulses I think you don't need interrupts at all. Poll the first pin for a LOW to HIGH change (rising), read millis(), poll the second pin for a LOW to HIGH then check to see if it is within 1000ms of the first.

ToddL1962:
Considering the long length of the pulses I think you don't need interrupts at all. Poll the first pin for a LOW to HIGH change (rising), read millis(), poll the second pin for a LOW to HIGH then check to see if it is within 1000ms of the first.

Thanks for the response. I need to wake up the microcontroller from deep sleep when a pulse is received (this will be a battery powered project). Therefore, I cannot be continuously polling for the pulses.

rahilj:
Thanks for the response. I need to wake up the microcontroller from deep sleep when a pulse is received (this will be a battery powered project). Therefore, I cannot be continuously polling for the pulses.

You could save the millis() timer when it wakes up and then poll for the second interrupt?

ToddL1962:
You could save the millis() timer when it wakes up and then poll for the second interrupt?

That's my approach as well as implemented in Approach1.ino. The second interrupt line should be pulled down within 1000ms to be a valid input. I am unable to time this polling requirement as I branch off the ISR which prevents millis() from increment. Perhaps, you can review my code and advise to structure it differently. Thanks so much.

Again, the point is that for such a long (many milliseconds) pulse width, interrupts are going to cause far more trouble than they are worth.

As Todd says, use the interrupt only to wake the processor. Instantly exit the interrupt routine. Poll the inputs to see which caused the interrupt and record millis(). Keep polling to see what changes and at what millis() time. Do your needful. When the dust settles, go back to sleep.

In deep sleep, timers and therefore millis() are not running. This does not matter in itself. There will be some delay however due to the waking process; if this (sleeping) is your scheme then you necessarily accept the resulting timing error. :grinning:

rahilj:
Apologies for lacking details.

I am trying to detect output of a window comparator -

[...]

A valid sequence - like the ones shown in the first image - will trigger a motor to actuate a pump.

It still seems to be a big secret. Is it something illegal or anti-social?

What is the input to the window comparator?
What is the pump for?
Why is there a pump?

...R

My wager is that it's for a school project. The screenshots show he's working with a P.O.S. Velleman O-Scope and are widely used in universities for some reason.

Robin2:
It still seems to be a big secret. Is it something illegal or anti-social?

What is the input to the window comparator?
What is the pump for?
Why is there a pump?

It still seems to be a big secret. Is it something illegal or anti-social?

What is the input to the window comparator?
What is the pump for?
Why is there a pump?

...R

Absolutely not. Apologies again - My intention to keep the discussion focused. I did mention that the analog input to the comparator is amplified output of a PIR sensor. The pump controls as touchless soap dispenser. My end goal is to make a PIR-based touchless soap dispenser. Optical sensors would have consumed too much power for this battry powered project.

My wager is that it's for a school project. The screenshots show he's working with a P.O.S. Velleman O-Scope and are widely used in universities for some reason.

Not a school project, but its a hobby project and I can only afford a USB scope.

Again, the point is that for such a long (many milliseconds) pulse width, interrupts are going to cause far more trouble than they are worth.

As Todd says, use the interrupt only to wake the processor. Instantly exit the interrupt routine. Poll the inputs to see which caused the interrupt and record millis(). Keep polling to see what changes and at what millis() time. Do your needful. When the dust settles, go back to sleep.

In deep sleep, timers and therefore millis() are not running. This does not matter in itself. There will be some delay however due to the waking process; if this (sleeping) is your scheme then you necessarily accept the resulting timing error. :grinning:

Got it! I like the idea. I will work on implementing this approach today and will reach out to the wonderful folks if I get stuck somewhere. Thanks for the advice.