Close

Zero Crossing Tweaks

A project log for BRTRO-420 Better Blazin' Mod

Modify the BRTRO-420 reflow oven to have an Arduino based reflow firmware, serial interface and cold junction compensation.

bleckyBlecky 11/15/2019 at 12:160 Comments

The mod boards also have a zero crossing detection circuit built in. The detection code is really simple, basically the zero detection pin from the optocoupler is connected to an interrupt line:

  attachInterrupt(digitalPinToInterrupt(ZER_D), zeroCrossing, RISING);

 And when the interrupt is triggered by the pulses generated by the optocoupler circuit, it changes the output state of the output solid state relays on the board:

void zeroCrossing()
{
  if (frontState == 1) //Turn on
  {
    digitalWrite(FRONT_HEATER, 0);
  } else { //Turn off
    digitalWrite(FRONT_HEATER, 1);
  }
  if (backState == 1) //Turn on
  {
    digitalWrite(BACK_HEATER, 0);
  } else { //Turn off
    digitalWrite(BACK_HEATER, 1);
  }
  if (convectionState == 1) //Turn on
  {
    digitalWrite(CONVECTION, 0);
  } else { //Turn off
    digitalWrite(CONVECTION, 1);
  }
  if (exhaustState == 1) //Turn on
  {
    digitalWrite(EXHAUST, 0);
  } else { //Turn off
    digitalWrite(EXHAUST, 1);
  }
}

I finally got my hands on a differential probe to actually take some measurements to see how well it was working.

Oh, so it's firing a bit too soon. It looks like the optocoupler/solid state relay circuit fires the AC line a bit earlier than the expected output. No matter, by the looks of things, we could fire this on the falling edge of the output instead.

 attachInterrupt(digitalPinToInterrupt(ZER_D), zeroCrossing, FALLING);

That's pretty close to bang on, but still not perfect as the turn off function will be late now (it will have a similar spike to the previous RISING condition). We could put a timer function in there to shift this and deal with both conditions that way, however different mains frequencies will change these timings slightly and require tuning and/or timing code.

Honestly I prefer simplicity, so the other way to deal with different conditions for off and on is to service both rising and falling interrupts to handle the different turn on and turn off states:

attachInterrupt(digitalPinToInterrupt(ZER_D), zeroCrossing, CHANGE);
void zeroCrossing()
{
  int state = digitalRead(ZER_D);

  if (state == 0) //We're in falling
  {
    if (frontState == 1) //Turn on
    {
      digitalWrite(FRONT_HEATER, 0);
    }
    if (backState == 1) //Turn on
    {
      digitalWrite(BACK_HEATER, 0);
    }
    if (convectionState == 1) //Turn on
    {
      digitalWrite(CONVECTION, 0);
    }
    if (exhaustState == 1) //Turn on
    {
      digitalWrite(EXHAUST, 0);
    }
  } else { //We're in rising
    if (frontState == 0)
    { //Turn off
      digitalWrite(FRONT_HEATER, 1);
    }
    if (backState == 0)
    { //Turn off
      digitalWrite(BACK_HEATER, 1);
    }
    if (convectionState == 0)
    { //Turn off
      digitalWrite(CONVECTION, 1);
    }
    if (exhaustState == 0)
    { //Turn off
      digitalWrite(EXHAUST, 1);
    }
  }
}


Done!

Discussions