Zero cross interrupt not working

Hello, I have been trying to detect zero cross with interrupts but it does not work. If I use attachInterrupt it does function, however if i use this code, it does not:

bool zero_cross_detected = false;
int last_CH1_state = 0;

void setup() {

  Serial.begin(9600);

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

  digitalWrite(LED_BUILTIN, LOW);

  PCICR |= B00000100; // We activate the interrupts of the PD port
  PCMSK2 |= B00000100; // We activate the interrupts on pin D2
}

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

  if (zero_cross_detected)     
    {
     Serial.println("Zero cross!");
     zero_cross_detected = false;
  }
}

void zeroCrossing() {
  if(last_CH1_state == 0) {
   zero_cross_detected = true;
  }
  else if(last_CH1_state == 1) {
    zero_cross_detected = true;
    last_CH1_state = 0;
  }
}

ISR (PCINT2_vect) {
 if(PIND & B00000100) {
  if(last_CH1_state == 0) {
   zero_cross_detected = true;
  }
 }
  else if(last_CH1_state == 1) {
    zero_cross_detected = true;
    last_CH1_state = 0;
  }
}

PIN_INTERRUPT is not defined any where.
I think interrupts are enabled by default in arduino or you could use interrupts() function.
I don't see where last_CH1_state is ever set to 1.

Missed a line where PIN_INTERRUPT is defined, you are right, I did not set CH1 state to 1, I have some code for reference and it doesn't set CH1 to 1. Even then I should get the println that zero cross is detected. (the void zeroCrossing() is from when I used attachInterrupt btw.)

You forgot to mark 'zero_cross_detected' as 'volatile'.

Since you are enabling only one Pin Change Interrupt and you appear to want to set 'zero_cross_detected' each time the pin changes, you can simplify your ISR to:

ISR (PCINT2_vect)
{
    zero_cross_detected = true;
}

well, I followed what you said and it lead to the same result, nothing.

We can't see your updated code.

Does the interrupt happen if you disconnect your zero-crossing detector and manually connect Pin 2 to +5V or Gnd? That would indicate that your zero-crossing detector hardware isn't working.

The hardware is working, I already tested it with attachInterrupt(). The thing is using this code it does not function.

Pin D2 is INT0, so did you mean INT0_vect ?

according to this website: PCINT interrupts on Arduino - ElectroSoftCloud PCINT2 is D2

You do realize that, unless you have true zero-crossing detection hardware (some kind of comparator that can actually detect a zero-crossing, rather than just a TTL logic level), using a raw input pin will NOT give you a zero-crossing interrupt? The actual threshold will be more like 1-2V.

I have a 4n25, and I figured this out as well, I just used attachInterrupt and set CHANGE to have both rising and falling. My system works now.

No. The OP is enabling PCINT18 (Arduino UNO Pin 2), not INT0 (Ardiuno UNO Pin 2).

Same pin but a different interrupt.

  PCICR |= 1<<PCIE2;
  PCMSK2 |= 1 << PCINT18; 

Yes, I saw that. I haven't used pin change interrupts myself, so didn't realize there are 2 working interrupt methods for pin D2. The OP mentioned attachInterrupt works, which (I believe) uses INTO. Anyways, INT0 gets the highest priority for servicing interrupts if timing accuracy is a critical consideration ...

A 4N25 is also not a true zero-crossing detector...

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.