Interrupts for sensors

Hi,

I am sort of new with arduino and not really great at programming. I am learning interrupt routines and i wanted to ask if we can write interrupt routine for sensor output.

I want write program in which when a button is pressed it will start reading the output from the analog pin and when the button is pressed it should stop the process.

Is this possible ?

Please help me with this

It is possible, but probably unnecessary.

AWOL:
It is possible, but probably unnecessary.

I suspect that means that @AWOL thinks that interrupts are unnecessary for detecting button presses - and I agree.

On the other hand if @pk22 just wishes to create a program to learn how to use interrupts a button-press is as good as anything.

...R

Robin2:
On the other hand if @pk22 just wishes to create a program to learn how to use interrupts a button-press is as good as anything.

...until @pk22 discovers switch bounce

AWOL:
until @pk22 discovers switch bounce

To my mind that is an ordinary part of learning about using interrupts

...R

pk22:
I am sort of new with Arduino and not really great at programming. I am learning interrupt routines and i wanted to ask if we can write interrupt routine for sensor output.

What sort of sensor? Why do you think this is related to interrupts? If you are indeed that new to programming, interrupts should not be of any concern to you for a very long time! :roll_eyes:

pk22:
I want write program in which when a button is pressed it will start reading the output from the analog pin and when the button is pressed it should stop the process.

So you are asking two entirely unrelated questions? For this second project, you need to explain a bit more about what it is you want to measure, what you want to do with the readings and how you have so far figured it out; what experiments you have tried in code?

AWOL:
...until @pk22 discovers switch bounce

Robin2:
To my mind that is an ordinary part of learning about using interrupts

For me it's in the category of "why not to use interrupts for buttons".
The debouncing (ignore state changes for xx ms) is the same... but instead of a simple digitalRead() it's done through an interrupt.

wvmarle:
For me it's in the category of "why not to use interrupts for buttons".

In general I agree, and I'm sure I have said as much in other Threads.

But in this case I am conscious of these words in the Original Post

I am learning interrupt routines

...R

Correct me if I am wrong, but there is a major and fundamental problem with proposing to use interrupts to de-bounce inputs (which is to say, switches, buttons, contacts or anything else.)

An interrupt responds to an event - contact closure or release - or both.

OK, the essence of de-bounce is to determine when the event has become "stable" - that is to say, is in the opposite state to its previous recorded state, and has been so for a specific time interval such as 5 milliseconds.

Well, by definition, you cannot wait for this within the interrupt because the interrupt itself blocks the timing mechanism - the interrupt that updates millis() - and even if it could, because it blocks all other actions as well which is unacceptable. :astonished:

So how can you de-bounce using interrupts? Consider - no bounce at all. A switch - perhaps a mercury switch - closes and generate an interrupt. The interrupt routine makes a note of this and returns, but there are no further interrupts because the switch remains closed. After a certain time, it is clearly "de-bounced", but how will you ever know?

Paul__B:
OK, the essence of de-bounce is to determine when the event has become "stable" - that is to say, is in the opposite state to its previous recorded state, and has been so for a specific time interval such as 5 milliseconds

I can see how that might be needed in some situations but the cases where I needed "debounce" the problem was simpler - detect the first contact closure and ignore the subsequent "bounce" open/close actions for long enough until they had stopped.

That can easily be achieved by getting an ISR not to report triggers within the bounce period which does not require a long time to be spent within the ISR. A slightly more complex option is to get the button ISR to start a Timer that will cause another interrupt after T millisecs and then turn its own interrupt off. When the Timer interrupt fires it will turn the button ISR back on.

...R

Robin2:
That can easily be achieved by getting an ISR not to report triggers within the bounce period which does not require a long time to be spent within the ISR.

And how would you do that? What sort of period would that be?

Paul__B:
And how would you do that? What sort of period would that be?

Something like this

void myISR() {
   if (millis() - timeOfLastUsefulInterrupt < 50) {
      return;
   }
   timeOfLastUsefulInterrupt = millis();
   newButtonPress = true;
}

...R

So it bounces twice within 50 ms and stays closed - what happens now?

Paul__B:
So it bounces twice within 50 ms and stays closed - what happens now?

Isn't that what you want to happen?

...R

Robin2:
Isn't that what you want to happen?

Well, maybe, but because all bounces were within the 50 ms period, "newButtonPress" is still false and there has been no other interrupt.

So - what happens now? :astonished:

The ISR works well for detecting button press. But bouncing at button release (does it happen?) may cause false button press. This may be solved by something like

if (buttonPressed) timeOfLastUsefulInterrupt=millis();

in loop.

Paul__B:
Well, maybe, but because all bounces were within the 50 ms period, "newButtonPress" is still false and there has been no other interrupt.

So - what happens now? :astonished:

My intention with my untested code in Reply #11 is that the first time it detects a switch closure it sets newButtonPress to true and then it stays silent for the following 50 msecs. Is that not how you read it? Maybe I have a mistake in my code?

...R

Paul__B:
Well, maybe, but because all bounces were within the 50 ms period, "newButtonPress" is still false and there has been no other interrupt

Only if that happens in the first 50 ms the sketch runs.

After that, no problem. Upon the first interrupt, timeOfLastUsefulInterrupt gets set to the current millis() value, and newButtonPress is set to true. The following 50 ms the interrupts are ignored - maybe loop() has already handled the event and cleared newButtonPress, but that's irrelevant at this point.

Any new press event (or bounce) after that 50 ms is recorded as new press.

OK, so I read that wrong.

So this de-bounce uses a different algorithm to what I use - it immediately registers any transient as a "press" irrespective of whether it is sustained or not and "re-arms" after 50 ms.

As Smajdalf points out, this would also include bounce on release of the button so he suggests regularly re-setting the timer in the loop whenever the button is found to be pressed which will work as long as the loop takes less than 50 ms to cycle.

I now have Déjà vu - I recall going through this exercise a number of years ago. :grinning:

I normally debounce by ignoring presses (button going low) for 20-50 ms after the first. Easiest and very effective. No way a human can press a button 20 times a second (and most buttons won't be up to that abuse either :-))