Hello Everyone,
Im working on an installation of continuously fading on and off incandescent lights based on the work of Ryan McLaughlin and his posts on the forum. I'm utilizing a PIR to trigger momentary switches of which lights fade on and off.
So far, I'm able to fade on and off and have the PIR trigger a different bulb but timing issues plague me. Lights seem to do ok for a short time but then start flashing and acting 'schizophrenic.' I may be utilizing the timerOne library completely wrong (What can I say, I am an artist not a coder).
Here is the mix-matched code I've come up with. Any feedback would be greatly appreciated.
/*
PIR AC Phase Control
Geoff Riggle <rigglegw@muohio.edu>
Special thanks to:
Ryan McLaughlin arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1230333861
There has got to be a better way to do this...its dirty, but it works, kinda.
*/
#include <TimerOne.h>
volatile int i=0; // Variable to use as a counter
volatile boolean zero_cross= 0; // Boolean to store a "switch" to tell us if we have crossed zero
int AC_pin[2] = {9,10}; // Output to Opto Triac
//int AC_pin2 = 10; // Output to Second Opto Triac
int dim = 128; // Dimming level (0-128) 0 = on, 128 = 0ff
int freqStep = 65; //for 60 mhz
int delay1 = 9; //delay for fade lightOn
//int delay2 = 9; // delay for fade lightOff
int a = 25; // timmer limit for lightOn
int b = 20; // timmer limit for lightOn/lightOff switch
int c = 45; // timmer limit for lightOff
//int LED = 13; //for testing purposes
int PIR = 4; // the PIR sensor will be plugged at digital pin 4
int state = 0; // variable to store the value read from the sensor pin
boolean lowHigh = false;
void setup() // run once, when the sketch starts
{
pinMode(AC_pin[0], OUTPUT); // Set the light control pin as output
pinMode(AC_pin[1], OUTPUT); // Set the second light control pin as output
//pinMode(LED, OUTPUT); // Set the LED pin as output
pinMode(PIR, INPUT); // declare the PIRSensor as as INPUT
//Timer1.initialize(freqStep);
attachInterrupt(0, zero_cross_detect, RISING); // Interupt for zero-cross detection
Timer1.initialize(100000); // Initialize TimerOne library for the timer
Timer1.attachInterrupt(timer, 100000); // Use the TimerOne Library for timer
// Serial.begin(9600); //serial for debugging
}
///////////////////////////////PRIMARY LIGHT/////////////////////////////////////////////////////////////
void primaryLight(){
if(i <= a){
lightOn();
}
if(i > b && i<= c){
lightOff();
}
if(i > c){
i=0;
zero_cross = 0;
}
}
void lightOn() // function to be fired at the zero crossing to fade light on
{
int fadeUpTime = (64.5*dim); // eval the proper pause to fire the triac to fade on
delayMicroseconds(fadeUpTime); // delay the fade up time
digitalWrite(AC_pin[0], HIGH); // fire the Triac
delayMicroseconds(delay1); //28 pause briefly to ensure the triac turned on
digitalWrite(AC_pin[0], LOW); // turn off the Triac gate (triac will not turn off until next zero cross)
}
void lightOff() // function to be fired at the zero crossing to dim the light
{
int dimtime = (freqStep*dim); // eval the proper pause to fire the triac to dim
delayMicroseconds(dimtime); // delay the dim time
digitalWrite(AC_pin[0], HIGH); // fire the Triac
delayMicroseconds(delay1); //5 pause briefly to ensure the triac turned on
digitalWrite(AC_pin[0], LOW); // turn off the Triac gate (triac will not turn off until next zero cross)
}
//----------------------------END PRIMARY LIGHT--------------------------------------------------------//
///////////////////////////////SECONDARY LIGHT/////////////////////////////////////////////////////////////
void secondaryLight(){
if(i <= a){
secondLightOn();
}
if(i > b && i<= c){
secondLightOff();
}
if(i > c){
i=0;
zero_cross = !zero_cross;
}
}
void secondLightOn() // function to be fired at the zero crossing to fade light on
{
int fadeUpTime2 = (64.5*dim); // eval the proper pause to fire the triac to fade on
delayMicroseconds(fadeUpTime2); // delay the fade up time
digitalWrite(AC_pin[1], HIGH); // fire the Triac
delayMicroseconds(delay1); // pause briefly to ensure the triac turned on
digitalWrite(AC_pin[1], LOW); // turn off the Triac gate (triac will not turn off until next zero cross)
}
void secondLightOff() // function to be fired at the zero crossing to dim the light
{
int dimtime2 = (freqStep*dim); // eval the proper pause to fire the triac to dim
delayMicroseconds(dimtime2); // delay the dim time
digitalWrite(AC_pin[1], HIGH); // fire the Triac
delayMicroseconds(delay1); // pause briefly to ensure the triac turned on
digitalWrite(AC_pin[1], LOW); // turn off the Triac gate (triac will not turn off until next zero cross)
}
//----------------------------END SECONDARY LIGHT--------------------------------------------------------//
void zero_cross_detect(){
zero_cross = 1;
}
void timer(){ //timer
i++;
}
void loop(){ //loop for fade on/off; May need tweeked depending of variant AC frequency
state = digitalRead(PIR);
while(state == 0 && zero_cross == 1){
primaryLight();
}
while(state != 0 && zero_cross == 1){
secondaryLight();
}
}
Thanks,
geoff