Interrupt works only on every second pulse

I am using an H11N1 opto-coupler/schmitt trigger to input zero-crossing pulses to an interrupt pin (pin 3). This will eventually drive some SCR's, but that's not important right now as I am still testing the interrupt function.

I am just simply trying to send pulses to an output pin to confirm the interrupt is working. The thing is the output is only pulsing on every second interrupt pulse. I have hooked up a scope and confirmed I am seeing clean pulses on the interrupt pin at 100Hz (twice the AC frequency as expected), but only pulses at 50Hz on the output. I don't understand why this is working but only with every second interrupt pulse.

I am using an arduino micro and here is my code:

 #define SCRtrigger   4
 
bool ZC = 0;

void setup(void) {
  pinMode(SCRtrigger, OUTPUT);
  attachInterrupt(1, ZC_risedetect, RISING);
  digitalWrite(SCRtrigger, LOW);
}
 
void ZC_risedetect() {
  ZC=1;
}

void loop() {
  if(ZC==1){
    digitalWrite(SCRtrigger, HIGH);
    delayMicroseconds(100);
    digitalWrite(SCRtrigger, LOW);
    ZC=0;
  }
}

you configured the interrupt on the RISING edge. did you want CHANGE?

change bool ZC = 0; to volatile bool ZC = 0;

Have you comment3ed out the code in

if(ZC==1){
    digitalWrite(SCRtrigger, HIGH);
    delayMicroseconds(100);
    digitalWrite(SCRtrigger, LOW);
    ZC=0;
  }

?

Such as

if(ZC==1){
    // digitalWrite(SCRtrigger, HIGH);
    delayMicroseconds(100);
    // digitalWrite(SCRtrigger, LOW);
    ZC=0;
  }

to see if the frequency of response changes?

I'd stick with the attacheinterrupt mode as you have it.

Did you try 200Hz?

You are waiting 100 microseconds before clearing ZC, so that if a second interrupt comes in during that delay
you will ignore it. Try this:

  if(ZC==1){
    ZC=0;
    digitalWrite(SCRtrigger, HIGH);
    delayMicroseconds(100);
    digitalWrite(SCRtrigger, LOW);
  }

And yes you need to declare ZC as volatile or the compiler could optimize it all away.

Thank you all. I have tried the changes suggested one by one. The thing that actually made a difference was changing attachInterrupt(1,,) to attachInterrupt(digitalPinToInterrupt(3),,).

So I am now getting 10ms output pulses that correspond to the 10ms input pulses. But why? The above change is recommended in the literature, I guess this is why, but if anyone can provide a deeper explanation?

#define SCRtrigger   4

volatile bool ZC = 0;

void setup(void) {
  pinMode(SCRtrigger, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(3), ZC_risedetect, RISING);
  digitalWrite(SCRtrigger, LOW);
}
 
void ZC_risedetect() {
  ZC=1;

}

void loop() {
  if(ZC==1){
    noInterrupts();
    ZC=0;
    digitalWrite(SCRtrigger, HIGH);
    delayMicroseconds(200);
    digitalWrite(SCRtrigger, LOW);
    interrupts();
  }
}

The thing that actually made a difference was changing attachInterrupt(1,,) to attachInterrupt(digitalPinToInterrupt(3),,).
But why?

I am using an arduino micro

On the 32u4 based platforms(e.g Leonardo, Micro), Interrupt 0 is pin3 and interrupt 1 is pin 2. The reverse of the AT328 arduinos.

See attachInterrupt() - Arduino Reference