Go Down

### Topic: Prototype PMU: measure phase difference of two sine waves using arduino (Read 1 time)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

#1
##### Nov 16, 2016, 03:54 pm
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

#2
##### Nov 17, 2016, 01:58 am
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

#3
##### Nov 18, 2016, 09:09 amLast Edit: Nov 22, 2016, 08:54 pm by 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

#4
##### Nov 18, 2016, 10:57 am
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

#5
##### Nov 18, 2016, 11:36 am
are you trying to monitor phase difference for 3-phase ?    this is something you can find on openenergymonitor.

#### Grumpy_Mike

#6
##### Nov 18, 2016, 11:38 am
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
Yes you are, otherwise don't bother measuring it just say it is 10 degrees, that is accurate +/- 180 degrees.

#### Grumpy_Mike

#7
##### Nov 18, 2016, 02:37 pm
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

#8
##### Nov 18, 2016, 03:39 pm
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

#9
##### Nov 18, 2016, 05:31 pm
Quote
1) The code is not in code tags. I will not post again on this thread until you address that problem.

#### Sudi

#10
##### Nov 21, 2016, 05:24 am
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

#11
##### Nov 21, 2016, 11:44 am
@Sudi please reduce your quotes to the really required information. Quoting code is not normally required.

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

#12
##### Nov 21, 2016, 02:10 pmLast Edit: Nov 21, 2016, 02:20 pm by 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

#13
##### Nov 21, 2016, 02:46 pm
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

#14
##### Nov 21, 2016, 02:55 pm
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

Please enter a valid email to subscribe

To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy