The following code which I copied off the internet to dim a light bulb works perfectly but I don't understand the sequence of events. I'm assuming after a reset the processor executes the void loop() dim increment and then stays in a delay loop which gets interrupted by either the zero_cross_detect or dim_check. If it is the zero_cross_detect then i is set to zero and the output is driven low to turn off the light. Then you go back to void loop()? I just don't understand how the delay(60) is effected by the two interrupts. Could someone explain step by step how this program works. Thanks.
#include <TimerOne.h>
volatile int i=0; // Variable to use as a counter volatile as it is in an interrupt
int AC_pin = 4; // Output to Opto Triac
int dim = 0; // Dimming level (0-128) 0 = on, 128 = 0ff
int freqStep = 65;
void setup()
{
pinMode(AC_pin, OUTPUT); // Set the Triac pin as output
attachInterrupt(digitalPinToInterrupt(2), zero_cross_detect, RISING); // Attach an Interupt to Pin 2
Timer1.initialize(freqStep); // Interrupt every 65usec.
Timer1.attachInterrupt(dim_check);
}
void loop()
{
dim = dim + 1;
delay(60); // delay = msec. Larger the delay the slower the dimming
}
void zero_cross_detect() // Interrupt every 8.3msec.
{
i = 0; // if removed dimming is unstable
digitalWrite(AC_pin, LOW); // turn off light
}
void dim_check() // Interrupt every 65usec.
{
if(i >= dim) // Dim (0-128) 0 = on, 128 = 0ff
{
digitalWrite(AC_pin, HIGH); // turn on light
}
else
{
i = i + 1; // increment time step counter
}
}
I didn't completely analyze the code (and you don't show a schematic).
I just don't understand how the delay(60) is effected by the two interrupts.
The delay determines how quickly the light dims. The main loop (including the delay) is interrupted by the timer.
If it is the zero_cross_detect then i is set to zero and the output is driven low to turn off the light.
A TRIAC latches-on until current falls to zero. That's just the nature of how TRIACs (and SCRs) work and it's reason you have to use zero crossing instead of PWM.
There is a delay after the zero crossing before the TRIAC is triggered. (With a longer delay the lamp is dimmer and with a short delay or no-delay it's brighter)
The TRIAC is hit with a short trigger pulse to turn it on and it turns-off by itself at the next zero crossing.
There are really good descriptions of the Arduino code in the Arduino reference.
Try:
Google: Arduino Reference attachInterrupt (replace this with any instruction you do not know)
or start browsing for the calls here
Once you understand what each line of code does, go trough the code step by step. The processor can do only one thing at a time (really fast) but only one thing. Follow the code until you understand how it works. If a specific step is unclear and you cannot figure it out, ask a specific question. Make sure you read the "How to post" . Its at the beginning of each sub forum.