1

Hi I was wondering if a digitalRead state change detection could be saved in a variable like counter++, just like you can do with an interrupt function.

arent these two operations almost the same?

like have an external circuit with a reed closed by a magnet, to take the place of a momentary push button,

2 Answers 2

1

The 2 techniques described in the question are commonly referred to as "polling" and "interrupt". Either will work. Polling is suggested for beginner programmers and when time is not important. Such as scanning an array of human controlled buttons. Whereas interrupts are usually reserved for when time is of the essence. Such as synchronizing a camera's release switch with a strobe flash.

Also, consider polling as a simple to understand, easy to test sequence of events that will always happen in the expected order. While interrupts can happen at any time and all interruptible code has to be written to tolerate being interrupted.

Often, debouncing is the more difficult problem when combining mechanical switches and microprocessors. A good fundamental exercise is to write your own debounce program. However, an Arduino debounce library is already available.

0

The fundamental difference between polling (digitalRead()) and interrupts is that of time. Yes, I know we discussed time and interrupts at length in another of your questions, but I'm not talking about recording time here.

With an interrupt you know (pretty much) when an input changed. With polling you can only know that it changed sometime in the past. An interrupt occurs at the moment an input changes state (what that change is depends on the type of interrupt). That makes it possible for your program to remember that time (by querying millis() for example).

With digitalRead() the only way you can know if an input has changed state is if you manually remember what the old state was and compare it, so all you can know is that it's changed since last time you examined the input, and if those times are far apart all you can say is "sometime in the past X milliseconds it changed state".

If your input changes faster than that polling time you won't know about it. For instance, if you end up polling every 10 milliseconds, and you have a pulse on your input pin that lasts 4 milliseconds (that's an eternity in microcontroller time) but occurs part way between two polls (say from 3ms to 7ms) you'll never see it.

To put it more formally, to detect a signal of frequency f Hz you have to sample the input at minimum 2f Hz (or a period of 1/(2f) seconds. This is known as the Nyquist-Shannon theorem and applies equally to both digital and analog sampling (digital sampling is merely 1-bit analog sampling).

With interrupts, since you're not sampling based on periodic checks, but instead using a hardware trigger to detect an edge (rising, falling, or changing), and assuming you have interrupts enabled at the time an edge arrives on the pin (some code disables interrupts, and interrupts can't trigger while another interrupt routine is running), you instantly know about it regardless of whatever else you are doing.

Interrupts are said to be asynchronous, whilst polling is known as synchronous.

Which method you should choose depends on many factors: the speed of your signals (pulses from sensors, buttons pressed by humans, etc), what else your program is doing, how critical it is that you detect an input state change, etc. For slow signals, like a button, polling is perfectly fine. For high speed signals, like a hall-effect sensor or a reed switch triggered by a bicycle wheel mounted magnet, interrupts are more suitable.

For some signals (especially things like revolution counters, frequency counters, etc) where you have a large number of brief pulses coming in over a period of time where all you want to do is count them, there are even better options than interrupts.

The internal timer peripherals of the chip can run in a number of modes that are designed just for this scenario. You can run a timer with the clock source as an IO pin. That means that on each incoming pulse to that IO pin the timer counts up by one. That happens completely independently of your program. You just read the current count from the timer and reset it to 0 to start counting again at a period to suit you.

Another mode is Input Compare mode. This combines normal interrupts with a timer. The timer runs in the background at a pre-defined rate, and as soon as a specific input changes state (each timer has specific inputs for this) the timer is frozen an interrupt is triggered. This gives highly accurate time measurement of incoming signals since it's not subject to the time taken to service the interrupt. The timer is frozen immediately and you can query that time when the system is able to service the interrupt.

There is no native support in Arduino for either of those timer modes, though, so you would have to either find an advanced library that configures the timers in that way for you, or read and understand the datasheet and manually configure the timers in the right way.

28
  • so, for example, a state change, like a button toggle, is this an example of polling of the digital pin that is being read by digitalRead()? like, if a momentary button is pushed, its useless for a toggle, but if you scan the pin for a change, a HIGH or LOW, and save that change, then toggle off that change, (latch) is this is an example of polling?
    – Jim
    Jan 17, 2018 at 3:32
  • Polling is merely the act of using digitalRead.
    – Majenko
    Jan 17, 2018 at 9:50
  • cool, so the MCU is polling when digitalRead is used, when there is a change, save the change, and thats the state change correct?
    – Jim
    Jan 17, 2018 at 13:09
  • Polling means "tell me the state of the port right now". What you do with that information is up to you. By comparing two polled states you can find a change in state.
    – Majenko
    Jan 17, 2018 at 13:13
  • so whats the difference between a state change and state detection change? How does the MCU tell the difference?
    – Jim
    Jan 17, 2018 at 13:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.