Arduino中断异常:方波边沿触发函数未稳定输出串口信息
Hey there! Let's break down why your interrupt setup isn't working as expected and fix it up.
The Core Problem
When you call attachInterrupt() twice on the same pin, the second call completely overwrites the first one. So your initial setup for the rising edge (RISING trigger calling udara()) gets erased when you set the falling edge (FALLING trigger calling blank()). That's why you're seeing inconsistent or missing serial outputs for one of the edges.
The Fix: Use CHANGE Trigger + Level Checking
Instead of trying to bind two separate interrupts to the same pin, use the CHANGE trigger (which fires on both rising and falling edges) and add a quick check inside the interrupt service routine (ISR) to determine which edge just occurred.
Also, a critical rule: never use Serial.print() inside an ISR! Serial communication relies on interrupts, which are disabled during ISR execution—this can cause deadlocks, data loss, or unstable behavior. Instead, use volatile global flags to signal the main loop() to run your functions.
Working Code Example
Here's a revised version of your code that addresses these issues:
const byte interruptPin = 2; // Volatile flags to signal edge events (prevents compiler optimization bugs) volatile bool risingEdgeDetected = false; volatile bool fallingEdgeDetected = false; void setup() { Serial.begin(9600); // Set pin mode (use INPUT_PULLUP if your circuit lacks external pull resistors) pinMode(interruptPin, INPUT_PULLUP); // Attach interrupt for ANY edge change attachInterrupt(digitalPinToInterrupt(interruptPin), handleEdgeChange, CHANGE); } void loop() { // Check flags in main loop and run your custom functions if (risingEdgeDetected) { udara(); risingEdgeDetected = false; // Reset flag after handling } if (fallingEdgeDetected) { blank(); fallingEdgeDetected = false; // Reset flag after handling } } // Interrupt Service Routine (ISR) - keep this as short as possible! void handleEdgeChange() { if (digitalRead(interruptPin) == HIGH) { // This was a rising edge risingEdgeDetected = true; } else { // This was a falling edge fallingEdgeDetected = true; } } // Your custom functions void udara() { Serial.println("Rising edge triggered!"); } void blank() { Serial.println("Falling edge triggered!"); }
Key Notes for Stability
- Volatile Variables: The flags are marked
volatilebecause they're modified in the ISR and read in the main loop—this tells the compiler not to optimize their values, ensuring consistency between the two contexts. - Pin Mode: Use
INPUT_PULLUPif your external signal doesn't have built-in pull resistors. This prevents floating pins (which can cause false interrupt triggers). If your signal uses external pull-down resistors, useINPUTinstead. - Short ISRs: Keep your ISR (
handleEdgeChange()) as minimal as possible. Only set flags here—all heavy lifting (like Serial prints or complex logic) should happen in the mainloop().
内容的提问来源于stack exchange,提问作者Udara Hasantha

