user-1: I have two square wave signals with the same frequency. I want to measure the phase shift between these two signals. There will be a small phase difference between two signals. (0-90 degree) and the frequency will vary in the range 100mHz - 50kHz. I am using an Arduino DUE (ATMEL ATSAM3X8E AU ,ARM)
I tried to use "micros()" for timer functionality to get 2 different times and then calculate the phase shift using the following code:
int led=47,count1=0,count2=0,temp=0;
int i=0,j=0;
float time1[3]={0,0};
float time2[3]={0,0};
float freq1=0,freq2=0;
float period1=0,period2=0;
float ps=0;


void setup()
{
      Serial.begin(9600);
      Serial.println();
       Serial.println();
      pinMode(31,INPUT);
      pinMode(33,INPUT);
      pinMode(led,OUTPUT);
      digitalWrite(led,HIGH);
      noInterrupts();  
      attachInterrupt(31,in1,RISING);
      attachInterrupt(33,in2,RISING);
      interrupts();
}

void in1()
{      noInterrupts();
       switch(i){
           case 0 : time1[i]=micros(); i++;  break;
           case 1 : if(j==1){time1[i]=micros(); i++; break;}
       }
       interrupts();
}
void in2()
{      noInterrupts();
       switch(j){
            case 0 : if(i==1){time2[j]=micros(); j++; break;}
            case 1 : if(i==2){time2[j]=micros(); j++; break;}
       }
           if(j==2){
             period1 = (time1[1]-time1[0]);
             period2 = (time2[1]-time2[0]);          
             freq1 = 1000.0/period1;         
             freq2 = 1000.0/period2;         
             ps = (((time2[1]-time1[1])*360.0)s/period1);
          if(freq1==freq2){
          Serial.println("");
          Serial.print("TIME1[0] = ");
          Serial.print(time1[0],6);
          Serial.print("\t TIME1[1] = ");
          Serial.print(time1[1],6);
          Serial.print("\t DEL1 = ");
          Serial.println(time1[1]-time1[0],6);
          Serial.print("TIME2[0] = ");
          Serial.print(time2[0],6);
          Serial.print("\t TIME2[1] = ");
          Serial.print(time2[1],6);
          Serial.print("\t DEL2 = ");
          Serial.println(time2[1]-time2[0],6);
          Serial.print("\t x = ");
          Serial.print(time2[0]-time1[0],6);
          Serial.print("period1(ms) = ");
          Serial.print(period1,6);
          Serial.print("\t period2(ms) = ");
          Serial.println(period2,6);
          Serial.print("freq1 = ");
          Serial.print(freq1,6);
          Serial.print("\t freq2 = ");
          Serial.print(freq2,6);
          Serial.print("\t Phase Shift = ");
          Serial.println(ps,6);
          } 
          else { 
          i=0;j=0;
          interrupts();
          }        
       }
       interrupts();
}
void loop()
{
       ;
}

When I run this code I am not getting any errors, but in high frequency (above 400 Hz) Ihave a problem. When I tested at 0 degrees, this code produced this output:
400 Hz 1.152 degree
500 Hz 1.440 degree
600 Hz 1.727 degree
700 Hz 2.015 degree
800 Hz 2.304 degree
900 Hz 2.592 degree
1 kHz  2.880 degree
2 kHz  5.760 degree
3 kHz  8.649 degree
.
.
.
10 kHz 28.8 degree

Each frequency has lowest degree that this code can calculate.
How can I fix this code? Is it possible to calculate the phase shift between two square wave signals this way?

user40: Even if your code worked perfectly, with zero processing latency, you still are working with a timer resolution of only 1 microsecond.  If I did my math correctly, that means at 50 kHz, the smallest phase difference you can detect is around 18 degrees.  At 100 MHz, 1 microsecond is 100 complete cycles.  You probably want to look into hardware specifically designed for phase detection.

user3508: Connect the two signals to the TIOA pins of two different timer/counter channels on the same timer/counter block (either TIOA0 and TIOA1, which are Arduino pins 2 and A7, or any two of TIOA6, TIOA7, and TIOA8, which are Arduino pins 5, 3, and 11, respectively).
Set the two timer channels to capture mode, "up" counting, and internal clocking at the fastest rate that seems appropriate (I don't see any reason not to use TIMER_CLOCK1 = 42MHz on the Due). Set them both to load RA on rising edge of TIOA, and RB on falling edge. Assuming TIOA0 and 1:
pmc_enable_periph_clk(ID_TC0);
TC_Configure(TC0, 0,
    TC_CMR_TCCLKS_TIMER1 |
    TC_CMR_WAVSEL_UP |
    TC_CMR_LDRA_RISING |
    TC_CMR_LDRB_FALLING
);

pmc_enable_periph_clk(ID_TC1);
TC_Configure(TC0, 1,
    TC_CMR_TCCLKS_TIMER1 |
    TC_CMR_WAVSEL_UP |
    TC_CMR_LDRA_RISING |
    TC_CMR_LDRB_FALLING
);

Set them both to generate interrupts on RA load:
TC0->TC_CHANNEL[0].TC_IER = TC_IER_LDRAS;
NVIC_EnableIRQ(TC0_IRQn);
TC0->TC_CHANNEL[1].TC_IER = TC_IER_LDRAS;
NVIC_EnableIRQ(TC1_IRQn);

Enable both clocks, and synchronize them so that they're both 0 at the same moment:
TC0->TC_CHANNEL[0].TC_CCR = TC_CCR_CLKEN;
TC0->TC_CHANNEL[1].TC_CCR = TC_CCR_CLKEN;
TC0->TC_BCR = TC_BCR_SYNC;

And handle the interrupts:
void TC0_Handler() {
    uint32_t status = TC0->TC_CHANNEL[0].TC_SR;
    if (status & TC_SR_LDRAS) {
        uint32_t tm = TC0->TC_CHANNEL[0].TC_RA;
        // rising edge of TIOA0 happened at "tm",
        // do something here to deal with it...
    }
}

void TC1_Handler() {
    uint32_t status = TC0->TC_CHANNEL[1].TC_SR;
    if (status & TC_SR_LDRAS) {
        uint32_t tm = TC0->TC_CHANNEL[1].TC_RA;
        // rising edge of TIOA1 happened at "tm",
        // do something here to deal with it...
    }
}

(Just defining functions with those names registers them as interrupt handlers, using weak-symbol magic).
If you choose to use TIOA6/7/8, the clock will be ID_TC6/ID_TC7/ID_TC8, and the EnableIRQ will be TC6_IRQn/TC7_IRQn/TC8_IRQn, but the TC_Configure calls will be TC2, 0 / TC2, 1 / TC2, 2, the SYNC will be issued to TC2, and the register accesses will be to TC2->TC_CHANNEL[0] / TC2->TC_CHANNEL[1] / TC2->TC_CHANNEL[2]. This is due to the way that the channels are grouped into blocks of three in the hardware. This is also why you have to use 0 and 1, or two of 6, 7, and 8; in order to sync the timers they have to be on the same block (and TIOA2 through TIOA5 aren't routed on the Due).
Because the clocks run at MClk/2 = 42MHz, the times you get will be in units of 1/42 microsecond, 42 times better than you get from micros(). Because the timer values are latched into the timer hardware before the interrupt is set, there isn't a problem if the two events come close to each other in time; you'll get the second interrupt after you finish handling the first, and the value in the register will still be valid (as long as you don't take so long that you miss more than one edge).
If you're interested in the falling edges, you can get those as well by setting the TC_IER_LDRBS bits and checking for status & TC_SR_LDRBS in your interrupt handlers.
Final advice: set your serial baud rate higher than 9600 if you can, you'll greatly decrease the amount of time you spend in Serial.print!

user4143: With 0° you have two inputs triggering interrupts at the same time.  That can't happen.  You can't run two interrupts at the same time, so the second one gets queued up until the first has finished.
With all that serial printing in there there's going to be quite a delay between one interrupt triggering and the next one being allowed to trigger - giving you skewed results.
I would suggest passing your signal through an XOR gate so that you end up with a single small pulse that represents the phase shift between the two signals.

-1: <p>I have two square wave signals with the same frequency. I want to measure the phase shift between these two signals. There will be a small phase difference between two signals. (0-90 degree) and the frequency will vary in the range 100mHz - 50kHz. I am using an Arduino DUE (ATMEL ATSAM3X8E AU ,ARM)</p>

<p>I tried to use "micros()" for timer functionality to get 2 different times and then calculate the phase shift using the following code:</p>

<pre><code>int led=47,count1=0,count2=0,temp=0;
int i=0,j=0;
float time1[3]={0,0};
float time2[3]={0,0};
float freq1=0,freq2=0;
float period1=0,period2=0;
float ps=0;


void setup()
{
      Serial.begin(9600);
      Serial.println();
       Serial.println();
      pinMode(31,INPUT);
      pinMode(33,INPUT);
      pinMode(led,OUTPUT);
      digitalWrite(led,HIGH);
      noInterrupts();  
      attachInterrupt(31,in1,RISING);
      attachInterrupt(33,in2,RISING);
      interrupts();
}

void in1()
{      noInterrupts();
       switch(i){
           case 0 : time1[i]=micros(); i++;  break;
           case 1 : if(j==1){time1[i]=micros(); i++; break;}
       }
       interrupts();
}
void in2()
{      noInterrupts();
       switch(j){
            case 0 : if(i==1){time2[j]=micros(); j++; break;}
            case 1 : if(i==2){time2[j]=micros(); j++; break;}
       }
           if(j==2){
             period1 = (time1[1]-time1[0]);
             period2 = (time2[1]-time2[0]);          
             freq1 = 1000.0/period1;         
             freq2 = 1000.0/period2;         
             ps = (((time2[1]-time1[1])*360.0)s/period1);
          if(freq1==freq2){
          Serial.println("");
          Serial.print("TIME1[0] = ");
          Serial.print(time1[0],6);
          Serial.print("\t TIME1[1] = ");
          Serial.print(time1[1],6);
          Serial.print("\t DEL1 = ");
          Serial.println(time1[1]-time1[0],6);
          Serial.print("TIME2[0] = ");
          Serial.print(time2[0],6);
          Serial.print("\t TIME2[1] = ");
          Serial.print(time2[1],6);
          Serial.print("\t DEL2 = ");
          Serial.println(time2[1]-time2[0],6);
          Serial.print("\t x = ");
          Serial.print(time2[0]-time1[0],6);
          Serial.print("period1(ms) = ");
          Serial.print(period1,6);
          Serial.print("\t period2(ms) = ");
          Serial.println(period2,6);
          Serial.print("freq1 = ");
          Serial.print(freq1,6);
          Serial.print("\t freq2 = ");
          Serial.print(freq2,6);
          Serial.print("\t Phase Shift = ");
          Serial.println(ps,6);
          } 
          else { 
          i=0;j=0;
          interrupts();
          }        
       }
       interrupts();
}
void loop()
{
       ;
}
</code></pre>

<p>When I run this code I am not getting any errors, but in high frequency (above 400 Hz) Ihave a problem. When I tested at 0 degrees, this code produced this output:</p>

<pre><code>400 Hz 1.152 degree
500 Hz 1.440 degree
600 Hz 1.727 degree
700 Hz 2.015 degree
800 Hz 2.304 degree
900 Hz 2.592 degree
1 kHz  2.880 degree
2 kHz  5.760 degree
3 kHz  8.649 degree
.
.
.
10 kHz 28.8 degree
</code></pre>

<p>Each frequency has lowest degree that this code can calculate.</p>

<p>How can I fix this code? Is it possible to calculate the phase shift between two square wave signals this way?</p>
 40: <p>Even if your code worked perfectly, with zero processing latency, you still are working with a timer resolution of only 1 microsecond.  If I did my math correctly, that means at 50 kHz, the smallest phase difference you can detect is around 18 degrees.  At 100 MHz, 1 microsecond is 100 complete cycles.  You probably want to look into hardware specifically designed for <a href="http://en.wikipedia.org/wiki/Phase_detector" rel="nofollow">phase detection</a>.</p>
 3508: <p>Connect the two signals to the TIOA pins of two different timer/counter channels on the same timer/counter block (either TIOA0 and TIOA1, which are Arduino pins 2 and A7, or any two of TIOA6, TIOA7, and TIOA8, which are Arduino pins 5, 3, and 11, respectively).</p>

<p>Set the two timer channels to capture mode, "up" counting, and internal clocking at the fastest rate that seems appropriate (I don't see any reason not to use <code>TIMER_CLOCK1</code> = 42MHz on the Due). Set them both to load RA on rising edge of TIOA, and RB on falling edge. Assuming TIOA0 and 1:</p>

<pre><code>pmc_enable_periph_clk(ID_TC0);
TC_Configure(TC0, 0,
    TC_CMR_TCCLKS_TIMER1 |
    TC_CMR_WAVSEL_UP |
    TC_CMR_LDRA_RISING |
    TC_CMR_LDRB_FALLING
);

pmc_enable_periph_clk(ID_TC1);
TC_Configure(TC0, 1,
    TC_CMR_TCCLKS_TIMER1 |
    TC_CMR_WAVSEL_UP |
    TC_CMR_LDRA_RISING |
    TC_CMR_LDRB_FALLING
);
</code></pre>

<p>Set them both to generate interrupts on RA load:</p>

<pre><code>TC0-&gt;TC_CHANNEL[0].TC_IER = TC_IER_LDRAS;
NVIC_EnableIRQ(TC0_IRQn);
TC0-&gt;TC_CHANNEL[1].TC_IER = TC_IER_LDRAS;
NVIC_EnableIRQ(TC1_IRQn);
</code></pre>

<p>Enable both clocks, and synchronize them so that they're both 0 at the same moment:</p>

<pre><code>TC0-&gt;TC_CHANNEL[0].TC_CCR = TC_CCR_CLKEN;
TC0-&gt;TC_CHANNEL[1].TC_CCR = TC_CCR_CLKEN;
TC0-&gt;TC_BCR = TC_BCR_SYNC;
</code></pre>

<p>And handle the interrupts:</p>

<pre><code>void TC0_Handler() {
    uint32_t status = TC0-&gt;TC_CHANNEL[0].TC_SR;
    if (status &amp; TC_SR_LDRAS) {
        uint32_t tm = TC0-&gt;TC_CHANNEL[0].TC_RA;
        // rising edge of TIOA0 happened at "tm",
        // do something here to deal with it...
    }
}

void TC1_Handler() {
    uint32_t status = TC0-&gt;TC_CHANNEL[1].TC_SR;
    if (status &amp; TC_SR_LDRAS) {
        uint32_t tm = TC0-&gt;TC_CHANNEL[1].TC_RA;
        // rising edge of TIOA1 happened at "tm",
        // do something here to deal with it...
    }
}
</code></pre>

<p>(Just defining functions with those names registers them as interrupt handlers, using weak-symbol magic).</p>

<p>If you choose to use TIOA6/7/8, the clock will be <code>ID_TC6</code>/<code>ID_TC7</code>/<code>ID_TC8</code>, and the <code>EnableIRQ</code> will be <code>TC6_IRQn</code>/<code>TC7_IRQn</code>/<code>TC8_IRQn</code>, but the <code>TC_Configure</code> calls will be <code>TC2, 0</code> / <code>TC2, 1</code> / <code>TC2, 2</code>, the <code>SYNC</code> will be issued to <code>TC2</code>, and the register accesses will be to <code>TC2-&gt;TC_CHANNEL[0]</code> / <code>TC2-&gt;TC_CHANNEL[1]</code> / <code>TC2-&gt;TC_CHANNEL[2]</code>. This is due to the way that the channels are grouped into blocks of three in the hardware. This is also why you have to use 0 and 1, or two of 6, 7, and 8; in order to sync the timers they have to be on the same block (and TIOA2 through TIOA5 aren't routed on the Due).</p>

<p>Because the clocks run at MClk/2 = 42MHz, the times you get will be in units of 1/42 microsecond, 42 times better than you get from <code>micros()</code>. Because the timer values are latched into the timer hardware <em>before</em> the interrupt is set, there isn't a problem if the two events come close to each other in time; you'll get the second interrupt after you finish handling the first, and the value in the register will still be valid (as long as you don't take so long that you miss more than one edge).</p>

<p>If you're interested in the falling edges, you can get those as well by setting the <code>TC_IER_LDRBS</code> bits and checking for <code>status &amp; TC_SR_LDRBS</code> in your interrupt handlers.</p>

<p>Final advice: set your serial baud rate higher than 9600 if you can, you'll greatly decrease the amount of time you spend in <code>Serial.print</code>!</p>
 4143: <p>With 0° you have two inputs triggering interrupts at the same time.  That can't happen.  You can't run two interrupts at the same time, so the second one gets queued up until the first has finished.</p>

<p>With all that serial printing in there there's going to be quite a delay between one interrupt triggering and the next one being allowed to trigger - giving you skewed results.</p>

<p>I would suggest passing your signal through an XOR gate so that you end up with a single small pulse that represents the phase shift between the two signals.</p>
