Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

three phase volt measurement using resistor network method

Status
Not open for further replies.

kavin_eees

Member level 3
Joined
May 11, 2012
Messages
57
Helped
2
Reputation
4
Reaction score
2
Trophy points
1,288
Activity points
1,842
hi all
right now am designing three phase protection circuit
for that i planned to measure the voltage using resistor net work method, herewith i had attached my circuit and my volt measuring code,
everything working good but in sometimes the R phase connected to AN0 pin shows high reading, kindly go through my code and give your valuable suggestions.

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
#include "Includes.h"
 
__CONFIG (DEBUGDIS & LVPDIS & BOREN & MCLRDIS& PWRTDIS & WDTDIS & INTIO ); //MCLREN
//__CONFIG (DEBUGDIS & LVPDIS & BOREN & MCLRDIS& PWRTDIS & WDTDIS & EXTIO  ); //MCLREN
 
//#define _XTAL_FREQ   20000000  
 
#define Tank RB7
#define Sump RB6
#define Auto RB0
 
#define Off RB5
#define On RB4
 
#define Inc RB3
#define Dec RB2
#define Menu RB1
 
#define Mon RC0
#define Dry_run RC2
#define Over_load RC1
#define Volt_error RC5
#define Tank_full RC6
#define Sump_empty RC7
#define Buzz RE2
 
void Menu_Set();
void delay(int);
void Buzz_delay_small();
//unsigned int GetVolt();
unsigned int GetCurrent();
void InitADC(void);
float GetADCValue(unsigned char Channel );
int GetVolt(unsigned char C );
void GetVolt3();
 
void Motor_On();
void Motor_Off();
//void display(unsigned int);
void display(unsigned int disp);
void displaycurrent(float value);
void displayamps(unsigned int disp1);
void InitTimer1();
void InitTimer0();
void Motor_amps_status();
void Phase_seq();
void Dry_pump();
 
char temp=0;
//unsigned int ADC_value = 0;
int ADC_value = 0;
int a,b,l=0,t1=0,t2=0;
float ADC_value2 = 0, Current=0,Ol_amp=0,Dry_amp=0,Raw_Byte;
unsigned int ADC_value1 = 0;
unsigned int digit1, digit2, digit3,VloByte,VhiByte,Vlow,Vhigh,i,k=0;
 unsigned int Volt=220 ,Dry_time=0,Volt_R=0,Volt_Y=0,Volt_B=0,Menu_temp=0;
char amp_temp,Dry_temp=0,pwr=0,Volt_temp=0,Seq_temp=0;
//char Tank_temp=0,Sump_temp=0;
//char int_temp=0;
 
unsigned int temp0=0;
unsigned max_point0 = 0;
 
 
void main(void)
{
TRISB=0xCF;
PORTB=0xCf;
TRISA=0xFF;
PORTA=0x00;
TRISC=0X00;
//TRISD=0X00;
PORTC=0X00;
//PORTD=0X00;
 
INTEDG=0;
INTCON=0x00;
GIE=1;
PEIE=1;
//INTE=1;
//INTF=0;
//RBPU=0;
OSCCON=0x75;
ANSELH=0x00;
//ANSEL=0X0F;
ANSEL=0Xff;
//C1ON=C2ON=0;
Auto=0;
 
InitTimer1();
InitADC();
ADCON1  = 0x80;
Buzz=1;
__delay_ms(500);
Buzz=0;
 
InitLCD();                          // Initialize LCD in 4bit mode
    
ClearLCDScreen();                   // Clear LCD screen
    while(1)
    {
        ADCON1  = 0x80;
        __delay_ms(250);
        GetVolt3();
        WriteCommandToLCD(0xcc);
        display(Volt_R);
        Volt_R=Volt_R*1.732;
        Volt_Y=Volt_Y*1.732;
        Volt_B=Volt_B*1.732;
        WriteCommandToLCD(0x80);
        WriteStringToLCD("V-");
        WriteCommandToLCD(0x82);
        display(Volt_R);
        WriteCommandToLCD(0x86);
        display(Volt_Y);
        WriteCommandToLCD(0x8a);
        display(Volt_B);
            
        if((Volt_R>=Vhigh || Volt_R<=Vlow) || (Volt_Y>=Vhigh || Volt_Y<=Vlow) || (Volt_B>=Vhigh || Volt_B<=Vlow))
        {
        Volt_error=1;
        Volt_temp=1;
        }
        else
        {
        Volt_error=0;
        Volt_temp=0;
        }
 
 
        if(Volt_temp==1 && temp==1)
        {
        //On=0;
        //Off=1;
        //delay(1);
        //Off=0;
        //Mon=0;
        temp=0;
        //WriteCommandToLCD(0xc0);
        //WriteStringToLCD("M-OFF");
        Motor_Off();
        }
        
 
        
 
    
 
    }
}
 
 
 
void interrupt isr(void)
{
 
  if (TMR1IF)
    { 
    TMR1IF = 0;
    TMR1H    = 0x3c;
    TMR1L    = 0xb0;
    k++;
    if(k==300)
        {
        Dry_time--;
        k=0;
        }
    }
 
    if(T0IF)
    {
     T0IF    = 0;
     TMR0        = 6;
     l++;
    }
}
 
 
void InitTimer1()
{
  T1CON  = 0x31;
  TMR1IF     = 0;
  TMR1H  = 0x3c;
  TMR1L  = 0xb0;
  TMR1IE     = 1;
  INTCON     = 0x00;
 
  //INTCON   = 0xC0;
}
 
 
void InitTimer0()
{
  OPTION     = 0x83;
  TMR0       = 6;
  //INTCON   = 0xA0;
  INTCON     = 0x00;
}
 
 
 
 
 
 
void InitADC(void)
{
    //ADCON1  = 0xB0;     // amps   // Make PORTA and PORTE analog pins      // Also, Vref+ = 5v and Vref- = GND
//  ADCON1  = 0x80;  // volt            
    TRISA   = 0xff;      // Make RA5, RA3, RA2, RA1, RA0 input
    TRISE   = 0x0B;      // Make RE0, RE1 and RE2 input
    //ADCON0  = 0x81;        // Turn on the A/D Converter
}
 
 
 
 
 
int GetVolt(unsigned char C )
{
ADC_value1=0;
ADC_value2=0;
ADC_value=0;
 
ADCON0  = 0x81; 
        
 
                ADCON0 &= 0xc7;         // Clear Channel selection bits
                ADCON0 |= (C<<2); // Select channel pin as ADC input
                __delay_us(50);         // Time for Acqusition capacitor 
                                        // to charge up and show correct value
                GODONE  = 1;            // Enable Go/Done
            
                while(GODONE);        // Wait for conversion completion
 
                ADC_value= ((ADRESH<<8)+ADRESL);   // Return 10 bit ADC value
                
return  ADC_value;
}
 
 
void GetVolt3()
{
 
max_point0 = 0;
      for(i=0;i<1000;i++)
      {
          //ADCON0 = 0b00000001;
          if(temp0 = GetVolt(0),temp0>max_point0)  //find the peak point
          {
             max_point0 = temp0;
          }
        Volt_R=max_point0*1.16;
    
      }
max_point0 = 0;
      for(i=0;i<1000;i++)
      {
          //ADCON0 = 0b00000001;
          if(temp0 = GetVolt(1),temp0>max_point0)  //find the peak point
          {
             max_point0 = temp0;
          }
        Volt_Y=max_point0*1.145;
    
      }
 
max_point0 = 0;
      for(i=0;i<1000;i++)
      {
          //ADCON0 = 0b00000001;
          if(temp0 = GetVolt(4),temp0>max_point0)  //find the peak point
          {
             max_point0 = temp0;
          }
        Volt_B=max_point0*1.089;
    
      }
}
 
 
void displaycurrent(float value)              // Assume value = 123.456
{
       a = value;              // a = 123
      value = (value - (float)a) * (10);       // value = 45.6
       b = a;              // b = 45
 
      displayamps(a);
       WriteDataToLCD('.');
        b = value;
            WriteDataToLCD(b+0x30);
      //displayamps(b);
}
 
 
 
 
void display(unsigned int disp)
{
    digit1 = (unsigned int)(disp/100);                                   // Calculate digit1 of ADC_value
        digit2 = (unsigned int)((disp - digit1*100)/10);                         // Calculate digit2 of ADC_value
        digit3 = (unsigned int)(disp - (digit1*100+digit2*10));          // Calculate digit3 of ADC_value
        //digit4 = (unsigned int)(disp - (digit1*1000+digit2*100+digit3*10));    // Calculate digit4 of ADC_value
 
        WriteDataToLCD(digit1+0x30);        // Display digit1 of ADC_value on LCD
        WriteDataToLCD(digit2+0x30);        // Display digit2 of ADC_value on LCD
        WriteDataToLCD(digit3+0x30);        // Display digit3 of ADC_value on LCD
        //WriteDataToLCD(digit4+0x30);      // Display digit4 of ADC_value on LCD
 
}
 
 
 
void delay(int x)
{
for(i=0;i<x;i++)
{
__delay_ms(1000);
}
}
 
void Buzz_delay_small()
{
__delay_ms(1);
Buzz=1;
__delay_ms(100);
Buzz=0;
}

 

Attachments

  • 3ph digital starter.PDF
    68.3 KB · Views: 137

Hi,

327 lines of undocumented code. Thanks for this riddle.

You want us to find the error around "AN0" but there is no "AN0" in your code.

"Three phase" makes me assume you talk about "AC" .... then you talk about "shows high reading"
* is it logic level HIGH?
* or high DC analog voltage?
* or is it high calculated AC amplitude?

We don't know about: the used microcontroller, schematic, compiler....

--> give useful and complete informations.

Klaus
 

hi Klausst
thanks for your reply.
i ill tell you clearly am going to sense Three phase AC voltage using resistor divider method,

Three phases say R Y B am converting high voltage AC to controller accepted voltage using resistor network and then i fed into PIC16f887 RA0(Rphase), RA1(Yphase), RA5(B phase)

Phases Y and B are giving correct value but the trouble is in R phase which is connected to microcontroller Pin RA0( ADC input 0). some time its gives correct value say 415, but in sometimes the values goes upto 520 like that and after some time its shows the correct value...

if there is and bug in my code kindly give your suggestion. i ill post the voltage measuring code here.... and also i attached the circuit in my previous post.



Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
void main(void)
{
TRISB=0xCF;
PORTB=0xCf;
TRISA=0xFF;
PORTA=0x00;
TRISC=0X00;
//TRISD=0X00;
PORTC=0X00;
//PORTD=0X00;
 
INTEDG=0;
INTCON=0x00;
GIE=1;
PEIE=1;
//INTE=1;
//INTF=0;
//RBPU=0;
OSCCON=0x75;
ANSELH=0x00;
//ANSEL=0X0F;
ANSEL=0Xff;
//C1ON=C2ON=0;
Auto=0;
 
InitTimer1();
InitADC();
ADCON1  = 0x80;
Buzz=1;
__delay_ms(500);
Buzz=0;
 
InitLCD();                          // Initialize LCD in 4bit mode
    
ClearLCDScreen();                   // Clear LCD screen
    while(1)
    {
        ADCON1  = 0x80;
        __delay_ms(250);
        GetVolt3();
        WriteCommandToLCD(0xcc);
        display(Volt_R);
        Volt_R=Volt_R*1.732;
        Volt_Y=Volt_Y*1.732;
        Volt_B=Volt_B*1.732;
        WriteCommandToLCD(0x80);
        WriteStringToLCD("V-");
        WriteCommandToLCD(0x82);
        display(Volt_R);
        WriteCommandToLCD(0x86);
        display(Volt_Y);
        WriteCommandToLCD(0x8a);
        display(Volt_B);
            
 
 
        
 
    
 
    }
}
 
 
 
 
 
 
 
 
void InitADC(void)
{
    //ADCON1  = 0xB0;     // amps   // Make PORTA and PORTE analog pins      // Also, Vref+ = 5v and Vref- = GND
//  ADCON1  = 0x80;  // volt            
    TRISA   = 0xff;      // Make RA5, RA3, RA2, RA1, RA0 input
    TRISE   = 0x0B;      // Make RE0, RE1 and RE2 input
    //ADCON0  = 0x81;        // Turn on the A/D Converter
}
 
 
 
 
 
int GetVolt(unsigned char C )
{
ADC_value1=0;
ADC_value2=0;
ADC_value=0;
 
ADCON0  = 0x81; 
        
 
                ADCON0 &= 0xc7;         // Clear Channel selection bits
                ADCON0 |= (C<<2); // Select channel pin as ADC input
                __delay_us(50);         // Time for Acqusition capacitor 
                                        // to charge up and show correct value
                GODONE  = 1;            // Enable Go/Done
            
                while(GODONE);        // Wait for conversion completion
 
                ADC_value= ((ADRESH<<8)+ADRESL);   // Return 10 bit ADC value
                
return  ADC_value;
}
 
 
void GetVolt3()
{
 
max_point0 = 0;
      for(i=0;i<1000;i++)
      {
          //ADCON0 = 0b00000001;
          if(temp0 = GetVolt(0),temp0>max_point0)  //find the peak point
          {
             max_point0 = temp0;
          }
        Volt_R=max_point0*1.16;
    
      }
max_point0 = 0;
      for(i=0;i<1000;i++)
      {
          //ADCON0 = 0b00000001;
          if(temp0 = GetVolt(1),temp0>max_point0)  //find the peak point
          {
             max_point0 = temp0;
          }
        Volt_Y=max_point0*1.145;
    
      }
 
max_point0 = 0;
      for(i=0;i<1000;i++)
      {
          //ADCON0 = 0b00000001;
          if(temp0 = GetVolt(4),temp0>max_point0)  //find the peak point
          {
             max_point0 = temp0;
          }
        Volt_B=max_point0*1.089;
    
      }
}

 

I don't see a specific reason in the code for getting outliers in the first channel.

Determining the absolute maximum of instantaneous voltage is however a poor method to measure AC voltage. A simple reason might be that the input voltage is actually distorted, or there can be crosstalk on the PCB.

I would try with a low pass filter, e.g. 100 nF in parallel to 3.3k voltage divider resistor.
 

hi FvM
thanks for your reply...

the problem not comes all the times but some time only in first channel rest of the channel are ok...
i ill add a low pass filter and check it again....
 

Hi,

I guess the problem is in the schematic.Maybe floating inputs (digital or analog), noisy supply voltage, noisy reference voltage, unsuitable anti aliasing filters, pushing negative voltages into analog pins...all this is explained in datasheets and application notes)

But all in all, the code is a very dirty solution...and I guess schematic and PCB layout, too.
* Either learn to design mire clean solutions (there are more than enough tutorials, code examples, descriptions, forum threads, videos...available)
* or accept dirty results

Klaus
 

like KlausST said your code is undocumented
(except in a few places, where is is redundant)

you need to document your code because:
it makes it a lot easier to help

a few weeks after the project is done, you won't remember
what you did, so you'll have to re-invent the whole thing
so a change can be made

you can pass it on to a newbie for maintenance

you're stuck with this project forever and can't move on to
something new and better

there is no such thing as Dilberts holy Grail of programming -
10,000 lines of spaghetti logic -it won't take long for management
to get frustrated and fire you
 

hi wwfeldman
thanks for your wordings ! i will improve myself quickly....
 

This is wrong.

Code:
ADC_value= ((ADRESH<<8)+ADRESL);   // Return 10 bit ADC value

casting to 16-bit variable needed.

ADRESH is a 8-bit register.

It is better if you use INT0 to detect ZC of Phase R and then after ZC is detected you start reading the phase voltages.

Also, you cannot and should not feed AC voltage with negative part to PIC ADC input pins. Level shift the AC signal to so that the scaled AC signal doesn't have any negative part and it should vary between 0 to 5V DC. If nominal voltage is 440V then make scaled 2.5V = 440V AC voltage.

- - - Updated - - -

My method of Phase voltage reading for your PIC is not so good because there is only one INT0 pin and you can only detect ZC of any one phase with it without using any external logic gates. The problem is then you have to use a timer interrupt to detect the ZC of other 2 Phases but the ZC will vary based on mains frequency and when that happens you will not get precise voltage readings.

I have done a 3-Phase voltage measurement using PIC18F46K22 which has 3 INTx pins and I have used them with 3 ZCD circuits and I start measuring the voltages on ZCs based upon mains frequency. I, however, assume that at all times the frequency of all the phases will be the same.

- - - Updated - - -

Your circuit modified to handle 500Vrms max for the Phase voltages. +5V DC Offset obtained from PIC's 5V Power Supply.

Initially, I designed the 3x ZCD circuits for PIC18F46K22 for my Pump Starter Cum Automatic Water Level Controller but later modified it for you. You can either use the 3x ZCD circuits and XOR gates to get the ZC signal or just one ZCD say ZC_R circuit to get the ZC signal without XOR gates.

In the XOR circuit, the high-to-low of ZC signal gives the zero crossings of the ZC_R signal.

- - - Updated - - -

My previous circuit (PDF file) had issues related to ADC input voltage.

I have fixed it. Here is the new circuit. You can use it. It handles max 500Vrms.
 

Attachments

  • 3PPSCAWLC.PDF
    94.7 KB · Views: 122
  • 3PPSCAWLC.PDF
    94.4 KB · Views: 107

hi baileychic
First of all i would like to say Thanks for your wonderful effort for me... i really appreciate your works..
ya there is some problem in my code and my hardware too... but unfortunately the pcb design over and i got 110 nos of pcb, i could not able to modify the PCB right now, but i will made some changes in my code and i use it for rightnow ! later i ill consider your suggestion and i ill work in bread board and i ill update here..
 

Your

Code:
void GetVolt3()

code is not good. It tries to find the peak value of voltages but that is only good for sinusoidal voltage. If your voltage is distorted due to load then you will not get the correct voltage readings.
 
hi to all
thanks for your support
now the problem is solved previously i used 5% resistor and now i changed to 1% resistor now am getting the correct voltage on lcd..
am going to test the unit with load connected... i ill update the result once testing completed...
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top