Interrupts in Arduino not working (for detecting zero crossing)

  • Thread starter Thread starter Wrichik Basu
  • Start date Start date
  • Tags Tags
    Arduino Zero
Click For Summary
The discussion centers on troubleshooting an Arduino setup for detecting zero crossings using an H11AA1 optocoupler and interrupts. The user initially faced issues with the Interrupt Service Routine (ISR) not being triggered, despite the optocoupler functioning correctly. Key points included the need to ensure the correct pin is used for interrupts, as not all pins support this feature. After changing the interrupt pin to pin 2, the code began to work as intended, allowing the inbuilt LED to light up upon detecting zero crossings. The conversation highlights the importance of verifying hardware compatibility when working with interrupts in Arduino projects.
Wrichik Basu
Science Advisor
Insights Author
Gold Member
Messages
2,180
Reaction score
2,721
In my previous thread, I learned about the H11AA1 optocoupler, which can be used instead of the 4N35 to detect zero crossings with Arduino.

Arduino has a specific function for detecting interrupts: attachInterrupt(digitalPinToInterrupt(pin), ISR, mode) This function is supposed to be used rather than the loop() function. Interrupt Service Routines (ISR) have to be short, but the code inside the loop() function can often be long, which will delay the next iteration and an interrupt can be missed.

The function allows the following four modes:
mode: defines when the interrupt should be triggered. Four constants are predefined as valid values:
  • LOW to trigger the interrupt whenever the pin is low,
  • CHANGE to trigger the interrupt whenever the pin changes value,
  • RISING to trigger when the pin goes from low to high,
  • FALLING for when the pin goes from high to low.

Code:

[CODE lang="c" title="Arduino"]const int PIN_INTERRUPT = 7;

void setup() {

Serial.begin(9600);

pinMode(LED_BUILTIN, OUTPUT);
pinMode(PIN_INTERRUPT, INPUT);

digitalWrite(LED_BUILTIN, LOW);

attachInterrupt(digitalPinToInterrupt(PIN_INTERRUPT), zeroCrossing, FALLING);
}

void loop() {
Serial.println(analogRead(A0));
}

void zeroCrossing(){
digitalWrite(LED_BUILTIN, HIGH);
}[/CODE]
The code is quite simple: the inbuilt LED is originally off, but the first time an interrupt is detected, it is turned on, and it stays on thereafter. I do not have an oscilloscope, so I am using the Arduino serial plotter and analogRead() to plot voltage values.

Circuit:

1608480792576.png

The diagram for the optocoupler follows from the Vishay datasheet.

Problem: Arduino is not detecting the interrupts: the inbuilt LED is not glowing, which implies that the ISR is not being called.

Output of Arduino serial plotter:

1608481068013.png

The above plot has interesting characteristics — it has a periodic pattern. The spikes almost always go below 300 (< 1.24V, LOW for arduino digital logic) from > 900 (> 4.41V, HIGH for Arduino digital logic), so these are the interrupts I want to see. This implies that the optocoupler is working fine, but Arduino still does not call the ISR.

I have tried many times before; this is the best graph I got. Now I don't know what to do. I cannot keep on using the loop() function because that will later be used for user input.

All help appreciated.
 
Engineering news on Phys.org
Dumb question, but for most microcontrollers (uCs), you have to "enable" the interrupt(s) before they work. I may have missed it, but I don't see mention of that in your code above...
 
berkeman said:
Dumb question, but for most microcontrollers (uCs), you have to "enable" the interrupt(s) before they work. I may have missed it, but I don't see mention of that in your code above...
Not a dumb question; I had thought about that before. It's supposed to be enabled by default in Arduinos. I also tried to specifically enable it by calling the interrupts() function, but nothing changed.
 
Wrichik Basu said:
The code is quite simple: the inbuilt LED is originally off, but the first time an interrupt is detected, it is turned on, and it stays on thereafter.
The LED is turned on by every zero crossing ISR, so it appears to stay on.
You are seeing a beat between the mains zero crossings and the loop routine.
Maybe count the ISR calls and copy the sixth bit of that counter to the LED. You should see 1/64'th of the interrupt rate.
 
Baluncore said:
The LED is turned on by every zero crossing ISR, so it appears to stay on.
You are seeing a beat between the mains zero crossings and the loop routine.
Maybe count the ISR calls and copy the sixth bit of that counter to the LED. You should see 1/64'th of the interrupt rate.
Maybe I was a bit unclear: the inbuilt LED is supposed to stay on, but it doesn't turn on at all.
 
Test the LED by turning it on and off with delays in the main Loop().
When you know you have the LED control OK, then try the interupt.
 
Baluncore said:
Test the LED by turning it on and off with delays in the main Loop().
When you know you have the LED control OK, then try the interupt.
Sorry, but I don't know if I fully understand what you are saying. If I use delay() in loop() in the above code, I will miss some of those spikes. I can use delayMicroseconds() instead, but I don't see why that is necessary. If you are asking me to test whether the LED is functioning properly, then the answer is yes; digitalWrite(LED_BUILTIN, HIGH) does turn on the LED.

Actually the LED is just a visual indicator that the ISR is being called; inside the ISR, I cannot use Serial.print(), so I am turning on the LED for debugging.
 
EUREKA! Found the problem. And the solution.

In Arduino, not all pins can receive interrupts:

1608588039327.png


Changed the interrupt pin to 2, and now the code works fine.
 
  • Informative
Likes Tom.G

Similar threads

Replies
5
Views
2K
  • · Replies 3 ·
Replies
3
Views
9K
  • · Replies 14 ·
Replies
14
Views
2K
  • · Replies 5 ·
Replies
5
Views
4K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 1 ·
Replies
1
Views
7K
  • · Replies 22 ·
Replies
22
Views
4K
  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 9 ·
Replies
9
Views
2K
Replies
138
Views
26K