PIR AC Phase Switch-Timing Issue

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

do you use the same schematics or did you modify something? Same parts?

Same parts with the exception of adding a parallax PIR. Same schematic using 2 incandescent bulbs, so using two triacs and optocouplers.

Lights seem to do ok for a short time but then start flashing and acting 'schizophrenic.'

Yes it will, this is because the dimming electronics is generating spikes and interference and causing the other dimmer to miss fire. While it is comparatively easy to fix in a low power DC system (see all about decoupling) it is very tricky to fix with an AC power system. The best bet is to try and introduce some chokes or snubber circuits in line with the load to slow down the di/dt (that is the rate of change of current with time). Again Google this.

I had this problem back in the 60's when triacs first came out and I tried to automate a theatre lighting rig with 16 dimmers. I had to install chokes in the mains leads to each lamp and separate the wiring to each lamp. Even then it sometimes had a fit.

You could try reducing the power of the lights as well.