Hello,
I have been playing around with some proof of concept code by modifying AC Phase Control which I found in the Playground. I previously tried something almost exactly the same but just attaching and detaching interrupts without any "state" variables.
The entire code is below for reference. It works as expected in the current configuration but if I set the state variable directly to 2 (i.e. tell the Timer1 ISR to do work on the next interrupt) it causes the output to stay high. To me, this should be the equivalent of letting the Loop do the same thing.
Could anybody provide an insight into why this does not work?
Thanks in advance.
#include <Bounce2.h>
#include <TimerOne.h>
//Constants
const int AC_PIN = A5;
const int ZCD_IN = 2;
const int BUTTON_IN = 3;
//These are all in microseconds
const int DELAY_MIN = 1000;
const int DELAY_MAX = 8000; //If this value is too high, triggering will not occur within a single half cycle resulting in erratic behaviour
const int DELAY_JUMP = 4000;
//Globals
volatile unsigned int offTime = DELAY_MIN;
volatile byte state = 0; // controls what interrupt should be attached or detached while in the main loop
Bounce buttonDebouncer = Bounce(BUTTON_IN, INPUT_PULLUP, 10);
void setup()
{
pinMode(AC_PIN, OUTPUT); // Set the Triac pin as output
attachInterrupt(digitalPinToInterrupt(ZCD_IN), zero_cross_detect, FALLING);
Timer1.initialize();
Serial.begin(9600);
}
void loop()
{
//Code doesn't seem to work without this
if(state == 1)
{
state = 2;
}
//Cycle through various delays for each button press
if (buttonDebouncer.update() && buttonDebouncer.fell())
{
if (offTime < DELAY_MAX)
{
offTime += DELAY_JUMP;
}
else
{
offTime = DELAY_MIN;
}
Serial.println(offTime);
}
}
void zero_cross_detect()
{
//Reset the Timer and reattach its interrupt
Timer1.restart();
Timer1.attachInterrupt(nowIsTheTime, offTime);
//Setting state directly to 2 seems to make it do nothing
state = 1;
//state = 2;
}
void nowIsTheTime ()
{
if (state == 2)
{
//Trigger the triac
digitalWrite(AC_PIN,HIGH);
delayMicroseconds(30); //Allow enough time for the triac to react (datasheet says about 25us for the current physical configuration)
digitalWrite(AC_PIN,LOW);
Timer1.detachInterrupt();
state = 0;
}
}