Hi all,
As the title says, im coding an AC Dimmer using the SparkInterval Library. The test code is as follows:
SYSTEM_THREAD(ENABLED);
// This #include statement was automatically added by the Particle IDE.
#include "SparkIntervalTimer/SparkIntervalTimer.h"
int AC_PIN = D3; // Output to Opto Triac
int PIN_ZERO_CROSS = D2;
unsigned int dimmerLevel = 5000;
IntervalTimer timerOn;
IntervalTimer timerOff;
void zero_cross_detect();
void setup()
{
Serial.begin(9600);
pinMode(AC_PIN, OUTPUT); // Set the Triac pin as output
timerOn.begin(turnOn, dimmerLevel, uSec);
timerOn.interrupt_SIT(INT_DISABLE);
timerOff.begin(turnOff, 9500, uSec);
timerOff.interrupt_SIT(INT_DISABLE);
pinMode(PIN_ZERO_CROSS, INPUT);
attachInterrupt(PIN_ZERO_CROSS, zero_cross_detect, RISING); // Attach an Interupt to Pin 2 (interupt 0) for Zero Cross Detection
}
void zero_cross_detect() {
timerOn.resetPeriod_SIT(dimmerLevel, uSec);
timerOn.interrupt_SIT(INT_ENABLE);
timerOff.resetPeriod_SIT(9500, uSec);
timerOff.interrupt_SIT(INT_ENABLE);
}
void turnOff() {
digitalWrite(AC_PIN, HIGH); // turn off TRIAC (and AC)
timerOff.interrupt_SIT(INT_DISABLE);
}
void turnOn() {
digitalWrite(AC_PIN, LOW); // turn on light
timerOn.interrupt_SIT(INT_DISABLE);
}
void loop() {
}
The main idea is that once the zero cross is detected i restart and enable a timer that will be called X usec after, acording to the dimming level i want. The maximum value, for 50Hz, is 10000 usec so i will set a maximum of 8000 and leave the last 2000 usec for other stuff.
Also when the zero cross is detected i restart another timer on a fixed time of 9500 usec that will turn off the AC_PIN before a new zero cross appears.
Now, i need a way of detecting and fixing losses of the zero cross, so something i was thinking about was using a third timer, also fired when a zero cross is detected and using a fixed time over 10000. So, as the timer is restarted with every zero cross, then it should never be fired unless the zero cross is not detected.
Something like this:
void setup()
{
Serial.begin(9600);
pinMode(AC_PIN, OUTPUT); // Set the Triac pin as output
timerOn.begin(turnOn, dimmerLevel, uSec);
timerOn.interrupt_SIT(INT_DISABLE);
timerOff.begin(turnOff, 9500, uSec);
timerOff.interrupt_SIT(INT_DISABLE);
**timerZeroCrossFix.begin(zeroCrossFix, 10050, uSec);**
pinMode(PIN_ZERO_CROSS, INPUT);
attachInterrupt(PIN_ZERO_CROSS, zero_cross_detect, RISING); // Attach an Interupt to Pin 2 (interupt 0) for Zero Cross Detection
}
void zero_cross_detect() {
timerOn.resetPeriod_SIT(dimmerLevel, uSec);
timerOn.interrupt_SIT(INT_ENABLE);
timerOff.resetPeriod_SIT(9500, uSec);
timerOff.interrupt_SIT(INT_ENABLE);
timerZeroCrossFix.resetPeriod_SIT(10050, uSec);
}
/************************************************************************/
void zeroCrossFix(){
timerOn.resetPeriod_SIT(dimmerLevel, uSec);
timerOn.interrupt_SIT(INT_ENABLE);
timerOff.resetPeriod_SIT(9500, uSec);
timerOff.interrupt_SIT(INT_ENABLE);
timerZeroCrossFix.resetPeriod_SIT(10000, uSec);
}
/************************************************************************/
But im having problems with this last code.
I would like to know if im doing something wrong.
- Am i using the timers correctly? Any ideas?
- Is there any delay when i restart the timers?
- Is there a problem with restarting a timer from the function called by that timer?
- Any considerations to take into account when using 3 timers at the same time¿?
- A better way of doing all this stuff?
I need the dimmer to be very precise, i cant see any blinking on the lights!
Thanks all in advance!