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
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.