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.

voltmeter using pic 16f877a problem

Status
Not open for further replies.
hello,

If you want to do progress
split the problems.

Is your Mikroc an official versus (not cra..ed) or limited versus 2Kmax ?

is it ADC problems or display problems.
Try to put a constant into your code
v=512; // middle scale of voltage
i=256; // a quota of the scale for Amps
and see what result you get on LCD.

if OK , check ADC part
use a potentiometer connected betwwen +5V and 0V , cursor on ADC input
reactivate ADC reading ( instead of constant)
and check if you get 0 to Max scale...

if OK probleme is on divider voltage circuit..
You measure AMPS , is this circuit isolated from de other part PIC16F877
show us your exact drawing
 

Untitled.jpg


this one is for measure from 0 to 30 volt and from 0 to 10A i did it in test board i have a driving kit for the pic. i want to measure any value of volt ant current in the past ranges

- - - Updated - - -

when i measure the volt across the 20K it give me the value of volt that i connected to test the project but it displays a wrong value
 

hello,

some remarks on hardware:
for voltage divider
the source voltage for ADC must be as low as possible of impedance
so reduce resistor divider value for voltage measurement
R1=10K R2=1,5K
idem for Amps measurement
R3=100k is to much , use 1K up to 4,7 maxi

Add 470µF in parralele with 100nF accross the battery 5V
Add a RC reset circuit on MCLR , not direct to 5V
 

2013-09-17 16.29.57.jpg



this is the power for pic

- - - Updated - - -

2013-09-17 16.29.57.jpg



this is the power for pic

- - - Updated - - -

2013-09-17 16.29.57.jpg



this is the power for pic

- - - Updated - - -

2013-09-17 16.29.57.jpg



this is the power for pic
 

no Chang the same as wrong values i connect 9v as input the result is 30.88v and 5.6 A

- - - Updated - - -

check the code
Code:
                              // LCD module connections
sbit LCD_RS at RB5_bit;
sbit LCD_EN at RB7_bit;
sbit LCD_D4 at RC4_bit;
sbit LCD_D5 at RC5_bit;
sbit LCD_D6 at RC6_bit;
sbit LCD_D7 at RC7_bit;

sbit LCD_RS_Direction at TRISB5_bit;
sbit LCD_EN_Direction at TRISB7_bit;
sbit LCD_D4_Direction at TRISC4_bit;
sbit LCD_D5_Direction at TRISC5_bit;
sbit LCD_D6_Direction at TRISC6_bit;
sbit LCD_D7_Direction at TRISC7_bit;
// End LCD module connections



char look(int a)
{
   switch(a)
   {
       case 0:
              return '0';
       case 1:
              return '1';
       case 2:
              return '2';
       case 3:
              return '3';
       case 4:
              return '4';
       case 5:
              return '5';
       case 6:
              return '6';
       case 7:
              return '7';
       case 8:
              return '8';
       case 9:
              return '9';
       default:
              return '.';
   }
}



void main()
{

  unsigned int v,vp,ip,i;
  char *volt = "00.0";
  char *current = "0.00";
  TRISA  = 0xFF;
  Lcd_Init();
  Lcd_Cmd(_LCD_CLEAR);
  Lcd_Cmd(_LCD_CURSOR_OFF);

  do
  {

       ADCON1 = 0x00;
       v = ADC_Read(2);
       i = ADC_Read(3);
       i = (i*4.8828)/0.47;
       v = ((v*4.8828)/2)*12;
       if(v!=vp || i!=ip )
          Lcd_Cmd(_LCD_CLEAR);
       vp = v;
       ip = i;
       volt[0] = look(v/10000);
       volt[1] = look((v/1000)%10);
       volt[3] = look((v/100)%10);
       Lcd_Out(1,1,"Voltage = ");
       Lcd_Out(1,11,volt);
       Lcd_Out(1,16,"V");

       current[0] = look(i/1000);
       current[2] = look((i/100)%10);
       current[3] = look((i/10)%10);
       Lcd_Out(2,1,"Current = ");
       Lcd_Out(2,11,current);
       Lcd_Out(2,16,"A");
       Delay_ms(250);
  } while(1);
}
 

What PIC are you using? 877A or 877? Why don't you use the code I posted? What does your switch case statement do? It doesn't have break;.

Add


Code C - [expand]
1
2
3
4
TRISB = 0x00;
TRISC = 0x00;
PORTB = 0x00;
PORTC = 0x00;

 
Last edited:

finally i fix the problem thank you

the code is
Code:
                              // LCD module connections
sbit LCD_RS at RB5_bit;
sbit LCD_EN at RB7_bit;
sbit LCD_D4 at RC4_bit;
sbit LCD_D5 at RC5_bit;
sbit LCD_D6 at RC6_bit;
sbit LCD_D7 at RC7_bit;

sbit LCD_RS_Direction at TRISB5_bit;
sbit LCD_EN_Direction at TRISB7_bit;
sbit LCD_D4_Direction at TRISC4_bit;
sbit LCD_D5_Direction at TRISC5_bit;
sbit LCD_D6_Direction at TRISC6_bit;
sbit LCD_D7_Direction at TRISC7_bit;
// End LCD module connections



char look(int a)
{
   switch(a)
   {
       case 0:
              return '0';
       case 1:
              return '1';
       case 2:
              return '2';
       case 3:
              return '3';
       case 4:
              return '4';
       case 5:
              return '5';
       case 6:
              return '6';
       case 7:
              return '7';
       case 8:
              return '8';
       case 9:
              return '9';
       default:
              return '.';
   }
}



void main()
{

  unsigned int v,vp,ip,i;
  char *volt = "00.0";
  char *current = "0.00";
  TRISA  = 0xFF;
  Lcd_Init();
  Lcd_Cmd(_LCD_CLEAR);
  Lcd_Cmd(_LCD_CURSOR_OFF);

  do
  {

       ADCON1 = 0x00;
       v = ADC_Read(2);
       i = ADC_Read(3);
       i = (i*4.89)/0.47;
       v = ((v*4.89)/1)*4.5;
       if(v!=vp || i!=ip )
          Lcd_Cmd(_LCD_CLEAR);
       vp = v;
       ip = i;
       volt[0] = look(v/10000);
       volt[1] = look((v/1000)%10);
       volt[3] = look((v/100)%10);
       Lcd_Out(1,1,"Voltage = ");
       Lcd_Out(1,11,volt);
       Lcd_Out(1,16,"V");

       current[0] = look(i/1000);
       current[2] = look((i/100)%10);
       current[3] = look((i/10)%10);
       Lcd_Out(2,1,"Current = ");
       Lcd_Out(2,11,current);
       Lcd_Out(2,16,"A");
       Delay_ms(250);
  } while(1);
}

the correct voltage divider VoltageScaler.png
 

Don't waste others time. You said you needed a range of 0 - 30V and you will measure 12V and now you are using another circuit whose range is 0 to 20V.

Try these changes.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
char *volt = "00.0";
char *current = "00.0";
 
//v and i should be float type
 
v = v * 30.0 / 1023.0;
i = v * 10.0 / 1023.0;
 
volt[0] = (v / 10) + 48;
volt[1] = (v % 10) + 48;
volt[3] = ((v * 10) % 10) + 48;
 
 
current[0] = (i / 10) + 48;
current[1] = (i % 10) + 48;
current[3] = ((i * 10) % 10) + 48;

 
  • Like
Reactions: tpetar

    tpetar

    Points: 2
    Helpful Answer Positive Rating
thank you jayanth.devarayanadurga , paulfjujo for your help i did it by your way now it is working thank you . if i want to use this project to control a relay connected with charger when the volt is less than 12 volt the relay switch the charger on other wise switch it off ???
 
Last edited:

thanks i do this can u correct it
Code:
                              // LCD module connections
sbit LCD_RS at RB5_bit;
sbit LCD_EN at RB7_bit;
sbit LCD_D4 at RC4_bit;
sbit LCD_D5 at RC5_bit;
sbit LCD_D6 at RC6_bit;
sbit LCD_D7 at RC7_bit;

sbit LCD_RS_Direction at TRISB5_bit;
sbit LCD_EN_Direction at TRISB7_bit;
sbit LCD_D4_Direction at TRISC4_bit;
sbit LCD_D5_Direction at TRISC5_bit;
sbit LCD_D6_Direction at TRISC6_bit;
sbit LCD_D7_Direction at TRISC7_bit;
// End LCD module connections
sbit rel at trisb.b1;

char look(int a)
{
   switch(a)
   {
       case 0:
              return '0';
       case 1:
              return '1';
       case 2:
              return '2';
       case 3:
              return '3';
       case 4:
              return '4';
       case 5:
              return '5';
       case 6:
              return '6';
       case 7:
              return '7';
       case 8:
              return '8';
       case 9:
              return '9';
       default:
              return '.';
   }
}



void main()
{

  unsigned int v,vp,ip,i;
  char *volt = "00.0";
  char *current = "0.00";
  TRISA  = 0xFF;
  TRISB = 0x00;
  Lcd_Init();
  Lcd_Cmd(_LCD_CLEAR);
  Lcd_Cmd(_LCD_CURSOR_OFF);

  do
  {

       ADCON1 = 0x00;
       v = ADC_Read(2);
       i = ADC_Read(3);
       i = (i*4.89)/0.47;
       v = ((v*4.89)/1)*4.5;
       if(v!=vp || i!=ip )
          Lcd_Cmd(_LCD_CLEAR);
       vp = v;
       ip = i;
       volt[0] = look(v/10000);
       volt[1] = look((v/1000)%10);
       volt[3] = look((v/100)%10);
       Lcd_Out(1,1,"Voltage = ");
       Lcd_Out(1,11,volt);
       Lcd_Out(1,16,"V");

       current[0] = look(i/1000);
       current[2] = look((i/100)%10);
       current[3] = look((i/10)%10);
       Lcd_Out(2,1,"Current = ");
       Lcd_Out(2,11,current);
       Lcd_Out(2,16,"A");

       Delay_ms(250);
         if(v=13.7,i=6.51)
       rel=0;
       else if(v<13.7,i<6.51)
       rel=1;
  } while(1);
}

- - - Updated - - -

thanks i do this can u correct it iam using mickro c pro
Code:
                              // LCD module connections
sbit LCD_RS at RB5_bit;
sbit LCD_EN at RB7_bit;
sbit LCD_D4 at RC4_bit;
sbit LCD_D5 at RC5_bit;
sbit LCD_D6 at RC6_bit;
sbit LCD_D7 at RC7_bit;

sbit LCD_RS_Direction at TRISB5_bit;
sbit LCD_EN_Direction at TRISB7_bit;
sbit LCD_D4_Direction at TRISC4_bit;
sbit LCD_D5_Direction at TRISC5_bit;
sbit LCD_D6_Direction at TRISC6_bit;
sbit LCD_D7_Direction at TRISC7_bit;
// End LCD module connections
sbit rel at trisb.b1;

char look(int a)
{
   switch(a)
   {
       case 0:
              return '0';
       case 1:
              return '1';
       case 2:
              return '2';
       case 3:
              return '3';
       case 4:
              return '4';
       case 5:
              return '5';
       case 6:
              return '6';
       case 7:
              return '7';
       case 8:
              return '8';
       case 9:
              return '9';
       default:
              return '.';
   }
}



void main()
{

  unsigned int v,vp,ip,i;
  char *volt = "00.0";
  char *current = "0.00";
  TRISA  = 0xFF;
  TRISB = 0x00;
  Lcd_Init();
  Lcd_Cmd(_LCD_CLEAR);
  Lcd_Cmd(_LCD_CURSOR_OFF);

  do
  {

       ADCON1 = 0x00;
       v = ADC_Read(2);
       i = ADC_Read(3);
       i = (i*4.89)/0.47;
       v = ((v*4.89)/1)*4.5;
       if(v!=vp || i!=ip )
          Lcd_Cmd(_LCD_CLEAR);
       vp = v;
       ip = i;
       volt[0] = look(v/10000);
       volt[1] = look((v/1000)%10);
       volt[3] = look((v/100)%10);
       Lcd_Out(1,1,"Voltage = ");
       Lcd_Out(1,11,volt);
       Lcd_Out(1,16,"V");

       current[0] = look(i/1000);
       current[2] = look((i/100)%10);
       current[3] = look((i/10)%10);
       Lcd_Out(2,1,"Current = ");
       Lcd_Out(2,11,current);
       Lcd_Out(2,16,"A");

       Delay_ms(250);
         if(v=13.7,i=6.51)
       rel=0;
       else if(v<13.7,i<6.51)
       rel=1;
  } while(1);
}

- - - Updated - - -

thanks can u correct this code
Code:
                              // LCD module connections
sbit LCD_RS at RB5_bit;
sbit LCD_EN at RB7_bit;
sbit LCD_D4 at RC4_bit;
sbit LCD_D5 at RC5_bit;
sbit LCD_D6 at RC6_bit;
sbit LCD_D7 at RC7_bit;

sbit LCD_RS_Direction at TRISB5_bit;
sbit LCD_EN_Direction at TRISB7_bit;
sbit LCD_D4_Direction at TRISC4_bit;
sbit LCD_D5_Direction at TRISC5_bit;
sbit LCD_D6_Direction at TRISC6_bit;
sbit LCD_D7_Direction at TRISC7_bit;
// End LCD module connections
sbit rel at trisb.b1;

char look(int a)
{
   switch(a)
   {
       case 0:
              return '0';
       case 1:
              return '1';
       case 2:
              return '2';
       case 3:
              return '3';
       case 4:
              return '4';
       case 5:
              return '5';
       case 6:
              return '6';
       case 7:
              return '7';
       case 8:
              return '8';
       case 9:
              return '9';
       default:
              return '.';
   }
}



void main()
{

  unsigned int v,vp,ip,i;
  char *volt = "00.0";
  char *current = "0.00";
  TRISA  = 0xFF;
  TRISB = 0x00;
  Lcd_Init();
  Lcd_Cmd(_LCD_CLEAR);
  Lcd_Cmd(_LCD_CURSOR_OFF);

  do
  {

       ADCON1 = 0x00;
       v = ADC_Read(2);
       i = ADC_Read(3);
       i = (i*4.89)/0.47;
       v = ((v*4.89)/1)*4.5;
       if(v!=vp || i!=ip )
          Lcd_Cmd(_LCD_CLEAR);
       vp = v;
       ip = i;
       volt[0] = look(v/10000);
       volt[1] = look((v/1000)%10);
       volt[3] = look((v/100)%10);
       Lcd_Out(1,1,"Voltage = ");
       Lcd_Out(1,11,volt);
       Lcd_Out(1,16,"V");

       current[0] = look(i/1000);
       current[2] = look((i/100)%10);
       current[3] = look((i/10)%10);
       Lcd_Out(2,1,"Current = ");
       Lcd_Out(2,11,current);
       Lcd_Out(2,16,"A");

       Delay_ms(250);
         if(v=13.7,i=6.51)
       rel=0;
       else if(v<13.7,i<6.51)
       rel=1;
  } while(1);
}
 

I think you will have to add some hysteris value (example +-0.1) to avoid vibrate relais... or sharp situation
because of bit varation in ADC measure..
and also some spike due to the (solenoide) relais itself or in the contact if a big current pass trough.

Antiwheel diode accross relais solenoide + capacitor accross the contact

if((v >= 13.8) && (i >=6.6))
rel=0;
else if((v < 13.6) && (i < 6.4))
rel=1;

Are you sure to act on relay with the 2 conditions together ?
or if only one is over ... test with && or || function.
 

thanks for this useful things i will try it all and thank you all for help and iam sorry for your wasting time
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top