Using micros() to Measure Phase Shift Difference on Analog input

So, I have this idea to use analog input to read the voltage shift difference on the system.

The Idea is simple, I will detect the zero value of each wave then calculate duration before the second wave hit the zero value (like suggested on Joe G on this article .

This is a fixed 50Hz electricity that I am measuring.

Using this function:

float getPs(){ //get Phase shift
  boolean boom=true;
  uint32_t psStart;
  uint32_t psStop ;
  
  while (boom==true){
    int v1Ps = analogRead(A0);
    boolean counting = false;
    //detect when v1=0
    if (v1Ps == 511) { 				//511 is the y=0 point of the measured wave
      
      counting = true;
      noInterrupts(); 				//for precision
      psStart = micros(); 			//record startingtime
    }
    while (counting == true) {
		
      while (micros()-psStart<= 5000){ // this is  the voltage shift limit which is 90degrees (5ms of 20ms Period) so the code will not read any zero value that occured after 5000us
		  
        int v2Ps = analogRead(A1);	//read 2nd port for other wave
        if (v2Ps==511){
          psStop = micros();
          counting=boom = false;	//breaking the loops
          interrupts();
        }
        break;
      }
    }
  }
  readPs = psStop - psStart;  		//read value got subtracted
  return readPs;					
}

But the value i got from reading it was:

[code]
548
556
556
556 <-- I try to shift the phase here. nothing changed
548
556
548
556
548

[/code]

the problem is that these code doesnt respond to any phase displacement I made.

anyone could help?
if tried reading these article1, article2, and many other article about voltage shift, but they seems to be needing other hardware that I cant make (I'm bad at electronics, and also I already overbudgeted for this project). i.e making ZCD and using the digital pin, or have something I dont understand how to apply.

Please help, any kind of suggestion would be appreciated.

if (v1Ps == 511)Really bad idea to compare for equality with an analogRead.

You realise that analogRead takes around 100us?

AWOL:
if (v1Ps == 511)Really bad idea to compare for equality with an analogRead.

You realise that analogRead takes around 100us?

Thanks for the reply. I didnt know this before.

Can I ask for suggestion aside from using the ISR and ZCD?

Thanks in advance.

If the frequency is a constant and you know when zero crossing occurs, then it is math to know at what moment what the phase angle will be from zero crossing.

Thanks all for the reply. I just tried tou Chaya's code with a little modification like this:

int led = 47;
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(115200);
  Serial.println();
  Serial.println();
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(led, OUTPUT);
  digitalWrite(led, HIGH);
  noInterrupts();
  attachInterrupt(0, in1, RISING);
  attachInterrupt(1, in2, RISING);
  interrupts();
}

void in1() {
  switch (i) {
  case 0:
    time1[i] = micros();
    i++;
    break;
  case 1:
    if (j == 1) {
      time1[i] = micros();
      i++;
      break;
    }
  }
}
void in2() {
  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)/ period1);
      i = 0;
      j = 0;
  }
}

void loop() {
  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("x = ");
      Serial.print(time2[0] - time1[0], 6);
      Serial.print("\t \t 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);
    } 
  delay(100);
}

But I only get something like this:

TIME1[0] = 140.000000 TIME1[1] = 0.000000 DEL1 = -140.000000
TIME2[0] = 0.000000 TIME2[1] = 0.000000 DEL2 = 0.000000
x = -140.000000 period1(ms) = 0.000000 period2(ms) = 0.000000
freq1 = 0.000000 freq2 = 0.000000 Phase Shift = 0.000000
TIME1[0] = 140.000000 TIME1[1] = 0.000000 DEL1 = -140.000000
TIME2[0] = 0.000000 TIME2[1] = 0.000000 DEL2 = 0.000000
x = -140.000000 period1(ms) = 0.000000 period2(ms) = 0.000000
freq1 = 0.000000 freq2 = 0.000000 Phase Shift = 0.000000
TIME1[0] = 140.000000 TIME1[1] = 0.000000 DEL1 = -140.000000
TIME2[0] = 0.000000 TIME2[1] = 0.000000 DEL2 = 0.000000
x = -140.000000 period1(ms) = 0.000000 period2(ms) = 0.000000
freq1 = 0.000000 freq2 = 0.000000 Phase Shift = 0.000000
TIME1[0] = 140.000000 TIME1[1] = 0.000000 DEL1 = -140.000000
TIME2[0] = 0.000000 TIME2[1] = 0.000000 DEL2 = 0.000000
x = -140.000000 period1(ms) = 0.000000 period2(ms) = 0.000000
freq1 = 0.000000 freq2 = 0.000000 Phase Shift = 0.000000

I already connected all the interrupt pin and make sure that the pin is connected to the ZCD and works fine.

I am using arduino nano At328p.
Why is it still failing?

  1. Convert reading to a signed value

  2. detect crossings by the sign reversing, not by comparing a specific value

  3. interpolate between sample instants to get fine-grained zero-crossing times - for instance
    if the value goes 20,5,-10,-25 you know the crossing point was 1/3 of a sample period after reading
    the 5.

Note that 2) and 3) can be done in a single routine that compares the latest value to the previous one,
and using the value of micros() for both samples allows a micro-second resolution time measurement
(best case theoretical).

  1. do not assume rising and falling crossings are exactly 180 degrees apart, either just use one
    kind of crossing, or separately measure phase difference with each and average the two.

Syukronalf:
Why is it still failing?

One obvious error is that you did not declare the variables written to in the ISRs as volatile. So that'd be at least i, j (terrible names for global variables) and the two time arrays. Maybe more, I didn't analyse in detail.

Next, you should do the math in loop(), not in the ISR. Don't do anything more in the ISR than what strictly has to be there. Set a flag so loop() can see there's data available. For responsiveness to this data, get rid of that delay(100).

  if (freq1 == freq2) {

It's extremely rare for float values to be exactly the same, unless they're set to zero or so (which in your case would happen if both period variables are zero). You normally compare floats by taking the difference, and checking whether that's smaller than an offset.

This are basic programming issues - I didn't check the algorithm you used, MarkT commented on that already in #5.