Go Down

Topic: Prototype PMU: measure phase difference of two sine waves using arduino (Read 3359 times) previous topic - next topic

Sudi

I want to measure phase difference of two sine waves using arduino uno, the waves that will be given as analog i/p are voltage and current waveform respectively of 50hz both. I am trying to do so by zero crossing method as I think this is simplest one. Can any one help me with the code as soon as possible.

Grumpy_Mike

What size are these signals?
That is how much voltage peak to peak?
What sort of accuracy are you looking for?
Have you biased the analogue inputs?

johnwasser

You could use the Input Capture Register of Timer1.  Have one zero crossing cause an interrupt that clears TCNT1 and have the other zero crossing trigger the input capture.  The value of TCNT1 gets saved in ICR1 and an interrupt occurs.  The value in ICR1 is the phase time difference in 16000000ths of a second.  There will be a zero crossing 100 times a second (every 90°) so you have 160000 ticks in 90°.  That gives you 0.0005625° resolution
Send Bitcoin tips to: 1G2qoGwMRXx8az71DVP1E81jShxtbSh5Hp

Sudi

What size are these signals?
That is how much voltage peak to peak?
What sort of accuracy are you looking for?
Have you biased the analogue inputs?
the voltage that will be used is 230V 50Hz Ac, I am not bothering about accuracy and I am using a 230v/6v transformer and a devider cicuit to make the voltage 3v before giving it to the analog pin of arduino.

Code: [Select]
 
    int led=13;       //select the pin for led//
    volatile unsigned long time1;
    volatile unsigned long time2;
    volatile float ps=0;
    
    
    void setup()
    {
          Serial.begin(9600);
          Serial.println();
          pinMode(A2,INPUT);    //voltage signal as analog input
          pinMode(A3,INPUT);    //current signal as analog input
          pinMode(led,OUTPUT);
          digitalWrite(led,HIGH);
          noInterrupts();           //disable interrupts
          attachInterrupt(A2,in1,RISING);     //enable ISR1 for voltage signal at rising from zero crossing
          attachInterrupt(A3,in2,RISING);     //enable ISR2 for current signal at rising from zero crossing
          noInterrupts();
          ps = (((time2-time1)*360.0)/20000);
          //calculate the phase shift from measured time difference
          interrupts();      //enable interrupts
              Serial.print("\t Phase Shift = ");
              Serial.println(ps,6);
              Serial.print("degree");
    }
    
    void in1()
    {
               detachInterrupt(A4);
               time1=micros();    //measure time in micro second for first zero crossing ISR1
    }
    void in2()
    {    
               detachInterrupt(A5);
               time2=micros();    //measure time in micro second for first zero crossing ISR2
    }
          
    void loop()
    {
           ;
    }



I don't know if this code will work. Please tell me where should I modify the code

DrDiettrich

Please use code tags </> to present code.

The Arduino inputs only accept voltages in the range 0-5V, no negative voltages as occur in an AC signal. The voltage divider may happen to protect the inputs, depending on its resistance.

Don't use Serial in an ISR. Set a flag instead, and do the output inside loop() when the flag was set.
Actually your program will crash, when the next interrupt exceeds the array bounds (j>0).

For exact timing a positive square wave signal is required on the interrupt pins, not an AC sine wave.

Also consider that a transformer or wave shaper (schmitt trigger...) will introduce a phase shift. You have to determine the phase shift of your sensor circuits, and adjust the output value accordingly. And handle negative phase shifts properly.

dave-in-nj

are you trying to monitor phase difference for 3-phase ?    this is something you can find on openenergymonitor.



Grumpy_Mike

Also in addition to the above, there is a lot more wrong with that code.
Time variables should not be floats but unsigned long types. You should not disable and enable interrupts inside an ISR, that happens automatically in a much better way than you can do it yourself.

If both signals go through the same processing circuits any shift will be cancled.

Quote
am not bothering about accuracy
Yes you are, otherwise don't bother measuring it just say it is 10 degrees, that is accurate +/- 180 degrees.

Grumpy_Mike

Quote
Is that alright now?
No.

1) The code is not in code tags. I will not post again on this thread until you address that problem.

2) Why are the time variables arrays of length one? Makes no sense at all.

3) You have been told not to do a serial print inside an ISR. You are still doing it.

4) Your calculation of the phase is not in any function and so will not be called. It won't even compile will it?

Sudi

No.

1) The code is not in code tags. I will not post again on this thread until you address that problem.

2) Why are the time variables arrays of length one? Makes no sense at all.

3) You have been told not to do a serial print inside an ISR. You are still doing it.

4) Your calculation of the phase is not in any function and so will not be called. It won't even compile will it?
I got the point you are trying to tell....calculation of phase shift should be within the main function and the serial print should be outside the ISR and it should be also in main function.
I want to know will it work if i use variable instead of array for measuring the time by micros??

Grumpy_Mike

Quote
1) The code is not in code tags. I will not post again on this thread until you address that problem.

Sudi

No.

1) The code is not in code tags. I will not post again on this thread until you address that problem.

now I have included code tags in the just above code...please check sir

DrDiettrich

@Sudi please reduce your quotes to the really required information. Quoting code is not normally required.

Where did you include code in code tags? Look at your reply #7, where no code tags are noticeable. Don't edit inside quoted text, instead add your comments and code outside quoted passages.

As an exercise you can go back to your reply #5, click More and Modify, to open the reply for editing. Then select the contained code and click </>, to enclose the selected code in code tags.

Sudi

I have modified the code using code tag. Now please check where I need to modify the code itself for measuring the phase difference. I am using a 230V/9V transformer and divider circuit to reduce the peak to peak within 5V(safe limit for arduino analog pin input). I can't use any other device as for zero crossing detector device or opamps for biasing. What I have to do is modify the code as much as possible. Thanks in advance.

DrDiettrich

A negative voltage is not good for the Arduino inputs. AC does not only have positive peeks, but also negative peaks of the same amplitude.

Sudi

Yeah I know but...would it damage the arduino if the rms voltage is 3V as input?? Any other way you suggest for the phase shift measurement...main problem is that I can not afford to buy any other device for the project.

Go Up