Phase Lock Loop - time sync issue

So here is the deal:
I’m working on a project that controls the firing sequence of 3 output pins. Each pin represents one electrical phase, and must fire twice over a whole period of the sine wave carrier in it’s phase once during the positive half of the wave and again during the negative half. For those of you who don’t know about power, a 3 phase system produces 3 identical sine waves of electricity, at some frequency and some amplitude, for my purposes, these are 60Hz & 120Vrms. They are identical to one another except that phase 1 is considered to be at 0o, phase 2 is 120o, and phase 3 at 240o, respectively. http://en.wikipedia.org/wiki/File:3_phase_AC_waveform.svg. Pin 10 follows phase 1, Pin 9 follows phase 2, Pin 6 follows phase 3.
I am attempting to pulse each switch on and off after some small delay so that they turn on after the Sine wave has become positive and then again after the sine wave has become negative. The way I am controlling the pins now is by calculating the delay with a certain formula and then submitting the microseconds to the function controlling the pin output, which is performing a hard coded form of PWM to the pins for set microsecond durations. The function waits for rise detection on Pin 7, which has a square wave that follows the input sine wave, then applies the delay and then puts out the six pulses as a train. At the detection of the rise after this, it begins this procedure as a loop until a lot of time has gone by, then it recalculates from the main program, making up for any major changes that have occurred.
The problem I am experiencing is that the output from the pins will not stay phase locked, or in sync with the input clock. Instead, they creep around the scope happening sometimes on, sometimes behind, and sometimes early. I believe the issue to be the result of minor fluctuations in the sine wave frequency that I read in as a square wave on pin 7, but I may be thinking of this too simplistically. I will gladly supply source code to any of the parts of the program if anyone is interested.

The function waits for rise detection on Pin 7, which has a square wave that follows the input sine wave, then applies the delay and then puts out the six pulses as a train. At the detection of the rise after this, it begins this procedure as a loop until a lot of time has gone by, then it recalculates from the main program, making up for any major changes that have occurred.
The problem I am experiencing is that the output from the pins will not stay phase locked

Well, I don't understand what the output is controlling, but the obvious (at least to me) question is why you don't sample the input signal a lot more often. If the drift occurs because you wait a long time to correct it, don't wait a long time to correct it. Of course, I could be all wrong.

Hey PaulS :slight_smile: The reasoning behind why I don’t sample a lot more often is that in order to force a PWM over a period of approximately 16,667 microseconds, with a duty ratio of 50%, I have to wait for almost the whole period to elapse before my pin ON/OFF sequence has completed it’s commands.

//this program defines the firing sequence for the TCR branch of a 3 phase SVC

void FiringSequence(unsigned long delayTime){
  int current = digitalRead (7); //current state of pin 7
  int last = current; //sets last state to the same as now
  
  do{ 

  while ((current != HIGH && last != LOW) || (current != HIGH && last != HIGH) || (current != LOW && last != LOW)){
   //basically states the 3 conditions that we are not allowed to move on from
   //first says if current state is low and the last state is high we are at a fall, check again.
   //second says if both are low we are in a low state, check again.
   //third says if both are high we are in a high state, check again.
   //the only condition on which we leave the loop is the fourth possible state:
   //the current state is high and the last one was low
   //indicating that we are seeing a rise time, so we exit
   last = current;
   current = digitalRead (7);
   }
    //this delay is to set the ON/OFF chain at a specific delay from the rise time detected on pin 7
    delayMicroseconds(delayTime);
    //these delays and on times are meant to cumulatively equal the duration of the period, which is approx ~ .016667 seconds, 60hz cycle
    //the 1000 mSec delays are there to slow the program down for visual confirmation that the firing sequence is phase coherent
    digitalWrite(10, HIGH);
    delayMicroseconds(1389); 
    //delay(1000);
    digitalWrite(10, LOW);
    delayMicroseconds(1389);
    //delay(1000);
    digitalWrite(9, HIGH);
    delayMicroseconds(1389);
    //delay(1000);
    digitalWrite(9, LOW);
    delayMicroseconds(1389);
    //delay(1000);
    digitalWrite(6, HIGH);
    delayMicroseconds(1389);
    //delay(1000);
    digitalWrite(6, LOW);
    delayMicroseconds(1389);
    //delay(1000);
    digitalWrite(10, HIGH);
    delayMicroseconds(1389);
    //delay(1000);
    digitalWrite(10, LOW);
    delayMicroseconds(1389);
    //delay(1000);
    digitalWrite(9, HIGH);
    delayMicroseconds(1389);
    //delay(1000);
    digitalWrite(9, LOW);
    delayMicroseconds(1389);
    //delay(1000);
    digitalWrite(6, HIGH);
    delayMicroseconds(1389);
    //delay(1000);
    digitalWrite(6, LOW);
    delayMicroseconds(1300);//this one is short to be sure we are done before the next cycle
    //at this point the program goes back to the while loop to make sure it's delaying after the next rise
    //keep in mind that all of these commands execute in slightly less than one period
    //therefore when we return to the while loop we should be in a low state and have a few microseconds before the next rise
  
}while(millis() < 12000000);
  
}

To all who posted on this thread:

Just wanted to say thanks again for all the good input. I appreciate the help a lot. I have finally got my sequence timing issue sorted. It's always the easiest answer thats the hardest one to find. I'm so stuck in what I've been taught for using C++ in visual basic that I'm not thinking like a microprocessor. I finally figured out that I can do the bulk of my programs work in the setup and then leave only the firing sequence as the main loop, which is the way it should be after all.
The whole loop is now just a series of on off commands to some switches, no major calculations and it's working super smooth.

Cheers!