0
0
AutocadHow-ToBeginner · 3 min read

How to Count Pulses Using Interrupt in Arduino

To count pulses using interrupts in Arduino, attach an interrupt to a digital pin with attachInterrupt() and increment a counter inside the interrupt service routine (ISR). This method ensures accurate pulse counting without missing pulses during other code execution.
📐

Syntax

The main function to use is attachInterrupt(digitalPinToInterrupt(pin), ISR, mode).

  • digitalPinToInterrupt(pin): Converts a pin number to the interrupt number.
  • ISR: The name of the function to call when the interrupt triggers.
  • mode: Defines when the interrupt triggers, e.g., RISING for a low-to-high pulse edge.

The ISR function should be short and only update variables marked volatile.

arduino
attachInterrupt(digitalPinToInterrupt(pin), ISR, RISING);

void ISR() {
  // code to run on interrupt
}
💻

Example

This example counts pulses on pin 2 using an interrupt and prints the count every second.

arduino
volatile unsigned long pulseCount = 0;

void setup() {
  Serial.begin(9600);
  pinMode(2, INPUT_PULLUP); // Use internal pull-up resistor
  attachInterrupt(digitalPinToInterrupt(2), countPulse, RISING);
}

void loop() {
  static unsigned long lastPrint = 0;
  if (millis() - lastPrint >= 1000) {
    noInterrupts(); // Temporarily disable interrupts to read safely
    unsigned long count = pulseCount;
    interrupts(); // Re-enable interrupts
    Serial.print("Pulse count in last second: ");
    Serial.println(count);
    pulseCount = 0; // Reset count for next second
    lastPrint = millis();
  }
}

void countPulse() {
  pulseCount++;
}
Output
Pulse count in last second: 15 Pulse count in last second: 12 Pulse count in last second: 18 ... (updates every second)
⚠️

Common Pitfalls

  • Not declaring the counter variable as volatile: This can cause incorrect counts because the compiler may optimize variable access.
  • Doing heavy work inside the ISR: The ISR should be very short to avoid missing pulses or blocking other interrupts.
  • Not disabling interrupts when reading shared variables: Reading multi-byte variables without disabling interrupts can cause corrupted values.
  • Using the wrong interrupt mode: Choose RISING, FALLING, or CHANGE depending on your pulse signal.
arduino
/* Wrong way: counter not volatile and heavy work in ISR */
int pulseCount = 0;

void countPulse() {
  delay(10); // Bad: delay inside ISR
  pulseCount++;
}

/* Right way: volatile counter and minimal ISR */
volatile int pulseCount = 0;

void countPulse() {
  pulseCount++;
}
📊

Quick Reference

Remember these tips for counting pulses with interrupts:

  • Use attachInterrupt() with the correct pin and mode.
  • Declare counters volatile to prevent compiler optimization issues.
  • Keep ISR code short and fast.
  • Disable interrupts briefly when reading shared variables.
  • Use internal pull-up resistors if your sensor output is open-drain or open-collector.

Key Takeaways

Use attachInterrupt() with digitalPinToInterrupt(pin) and a short ISR to count pulses accurately.
Declare pulse count variables as volatile to ensure correct updates inside interrupts.
Keep ISR code minimal to avoid missing pulses or blocking other interrupts.
Disable interrupts briefly when reading multi-byte shared variables to avoid corrupted reads.
Choose the correct interrupt trigger mode (RISING, FALLING, or CHANGE) based on your pulse signal.