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.,RISINGfor 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, orCHANGEdepending 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
volatileto 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.