# How to calculate phase shift between two square wavefroms with Arduino DUE

I have two square wave signals with same frequency. I want to measure phase shift between two signals. There will be a small phase difference

between two signals. (0-90 degree) and I vary frequency in range 100mHz - 50kHz. I am using Arduino DUE (ATMEL ATSAM3X8E AU ,ARM)

I try to use "micros()" for timer functionality to get 2 different times and then calculated in equation using the following code.

``````    int led=47,count1=0,count2=0,temp=0;
int i=0,j=0;
float time1={0,0};
float time2={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-time1);
period2 = (time2-time2);
freq1 = 1000.0/period1;
freq2 = 1000.0/period2;
ps = (((time2-time1)*360.0)s/period1);
if(freq1==freq2){
Serial.println("");
Serial.print("TIME1 = ");
Serial.print(time1,6);
Serial.print("\t TIME1 = ");
Serial.print(time1,6);
Serial.print("\t DEL1 = ");
Serial.println(time1-time1,6);
Serial.print("TIME2 = ");
Serial.print(time2,6);
Serial.print("\t TIME2 = ");
Serial.print(time2,6);
Serial.print("\t DEL2 = ");
Serial.println(time2-time2,6);
Serial.print("\t x = ");
Serial.print(time2-time1,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 (upper 400 Hz) have a problem. When I test at 0 degree this code show me that...

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.
I'm a student and this is the first time I'm using Arduino so I don't know how can I amend this code? or I can't use this code for calculate phase shift

between two square wavw signals ? Any suggestions please. Many Thanks.

1 degree of “phase shift” at 400 Hz is 7 uS.

At 10kHz, 1 degree of phase shift is 0.3 uS.

micros() returns the time with a granularity of 4 uS. (i.e., you only get 4,8,12…)

See a problem?

I see. But do you have any suggestion? Dose it have other function besides "micros()" ?

One approach that may be possible is to trigger two timers, one from each signal, and

There is a lot wrong with that code.
Variables that are used inside and outside an interrupt service routine (ISR) must be declaired as volitile.

You should not disable and enable the interrupts inside an ISR

You declair a float array with three elements yet you only initialise two.

Never print inside an ISR.

Your ISRs are way too long.

Basically you are doing it wrong. To get more precision just count the number of times you have gone round a while loop between one edge and the other.

Another approach would be to use an external phase comparator with analog output and read its value with ADC.

pito:
Another approach would be to use an external phase comparator with analog output and read its value with ADC.

You can make one with an exclusive or gate, one signal in each input and then smooth the output with an RC filter and feed it into the analogue input.