Arduino Software Interrupts



Here’s a simple Arduino Tachometer project for measuring and displaying speed of rotation. You can find similar projects everywhere on the web but this one has some unique features. First off, the idea is based on a square type inductive proximity sensor SN04-N from RiKo. The SN04-N is a low cost, stable, and waterproof inductive proximity sensor with a normally-open (N/O) NPN transistor output, surprisingly with an internal pull-up resistor that’s not clearly mentioned in the datasheet!

  • Arduino timer interrupts allow you to momentarily pause the normal sequence of events taking place in the loop function at precisely timed intervals, while you execute a separate set of commands. Once these commands are done the Arduino picks up again where it was in the loop. Interrupts are useful for.
  • The number of external interrupts possessed by microcontrollers differs from one microcontroller to the other. For example, the Arduino boards, from UNO to Duemilanove, have only two interrupts which are located on digital pins 2 and 3. Other boards like the Arduino Mega has 6 while the esp8266 (ESP 12e) has about 16 interrupt pins.
  • Software Interrupts − They occur in response to an instruction sent in software. The only type of interrupt that the “Arduino language” supports is the attachInterrupt function. Using Interrupts in Arduino Interrupts are very useful in Arduino programs as it helps in solving timing problems.
  • An interrupt signal is used here which has the highest priority of all. There are software and Hardware interrupts: Hardware Interrupts - These occur in response to an external event, like a pin going high or low. Software Interrupts - These occur in response to a software instruction.

Using software pin change interrupt by using a library such as PciManager library. Only for Arduino devices (Atmga328 and Atmage2560) Software interrupts. Using the hardware external interrupts usually results in better and more reliable performance but software interrupts will work very well for.

Arduino Software Interrupt Deutsch

Hardware: This project requires three key hardware parts as listed below.

  • Inductive Proximity Sensor (SN04-N)
  • Arduino (Rev3)
  • Arduino LCD Shield (DFR0009)

As can see in the below diagram, the hardware frame-up is extremely simple, and calls only one bare I/O of Arduino (Pin 2) to complete the entire setup. Pin 2 of Arduino Uno, used here as the ‘Pulse Input’ pin, is its ‘Interrupt 0’ pin that enables us to run some code only when a level change happens there. The second interrupt – ‘Interrupt 1’ of Uno is on Pin 3. Just to recap, interrupts are a nice way to make the system more tractable to time tender tasks. They also helps to free up the main loop to look at the primary task in the system. For more details, check out this documentation on interrupts – https://www.arduino.cc/en/Reference/attachInterrupt

Arduino Timer Interrupt Tutorial

Arduino uno software interrupts

Arduino Software Interrupt Library

Interrupts

Software

The code strictly follows the common Arduino Sketch style and uses the standard interrupt 0 on pin 2 (D2). As you can see in the code, the interrupt triggers on ‘falling’ edge of the input pulse. Copy the below code in your Arduino IDE software to program your Arduino.

In the code, the interrupt will increment a variable each time the signal at INT0 is falling, and interrupts are disabled during the computation time. Take note on the code line ” uint32_t rpm = rev * 60000 / (millis() – measureTime);” as it’s tailored for interrupts occurred once per revolution. You can modify this line to suit your specific ‘sensor and target’ setup. The given code works better only if the RPM is greater than 60 as at least one rotation per second must happen for accurate RPM display.

Rotational Speed Monitor

As stated, an inductive proximity sensor is used for rotational speed monitoring here by counting relevant pulses in a non-contact way. Sensing range of SN04-N is 4mm but a distance (gap) close to 3.2mm is recommended between the stationary head (proximity sensor) and the orbiting target (ferrous object).

The entire setup must be powered from a regulated 5V dc supply. First of all, route the ground lead of the power supply to the ground rail (GND) of Arduino, and to the ground wire (blue) of SN04-N. Similarly extend the positive lead to the regulated dc input (5V) pin of Arduino, and to the positive wire (brown) of SN04-N. Finally, connect the output (black) of SN04-N to D2 (INT0) of Arduino (refer next figure). For short-time experiments, powering up the Arduino through its dc input jack (or Vin) by a 9-12V unregulated dc supply lets you take the regulated 5V output from Arduino board to run the inductive proximity sensor (be careful).

According to “Automation Insights” blog (https://automation-insights.blog), the best target in general for an inductive proximity sensor is a flat piece of ferrous metal. Other non-ferrous target materials can still be detected by an inductive sensor (of course with lesser sensitivity), but ferrous steel is a proven target material with a cheerful sensing range.

Don’t Kill Your Arduino! Somebody might wonder why I wanted to run SN04-N sensor from a 5V regulated dc supply instead of the recommended 10-30V dc input. It’s because I noticed that output (black) of the SN04-N sensor (what I got from an online seller is a cheap one, may be another clone) is internally tied to its unregulated positive rail through a 10K pull-up resistor. So its output will give the same inputted positive voltage in idle state and that will kill the Arduino. Although with a little trick it’s easy to drop down the output voltage to TTL level, my laziness forced me to try a 5V regulated dc supply input for SN04-N, and it worked.

More Interrupts?

Arduino uno interrupt example

Arduino Software Interrupt Tutorial

If you want one more sensor in the same setup, luckily Arduino Uno has 2 external interrupts, so you can try the same strategy as in the code, i.e. just make another interrupt function for the second sensor and attach it on interrupt 1 (pin 3). Thankfully, using the “PinChange Interrupt” library, we can configure any pin on Arduino an interrupt pin. As always you can go through the external link for more details https://www.brainy-bits.com/make-any-arduino-pin-an-interrupt-pin/

And, here’s a useful documentation especially for those interested to learn more about Arduino RPM measurement techniques http://elimelecsarduinoprojects.blogspot.com/2013/06/measure-rpms-arduino.html

Arduino Interrupt Software Serial

I've seen software debouncing code that didn't use interrupts but used the main loop. It would only trigger some action if the state had changed, and then remained unchanged for a period of time. E.g. if 10 consecutive readings (one reading each millisecond) return the same (new) state, then do the action. I guess in some cases it could be good to do it this way, to prevent some spurious triggering (maybe due to some noise / glitch?), rather than do the action on first state change, then ignore further actions for a given time like your solution does. What do you think?
Do you think it would be feasible to implement this approach using interrupts? I'm guessing part of the code would have to go in the main loop, don't see a way around it.