xbee voltmeter using pic16f887

Status
Not open for further replies.

flamesier

Newbie level 6
Joined
Oct 2, 2010
Messages
13
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Visit site
Activity points
1,453
hi,
im new to programming..
but managed to do this...below..
i want to measure the actual voltage that is being measured..but everytime i tried its not displaying anything...
after some editing i managed to display the adc value that is being read by the pic16f887...
can anyone help me on how to display the 0-5vdc that is measured?? in the virtual terminal in proteus?i dont know how else to do it..
thanks in advance..
here is my code..


void main() {
int adc_rd;
char text[12];

ANSEL = 0b00000100; // Configure AN2 pin as analog
ANSELH=0; //other are digital
INTCON=0; //disable interrupts
ADCON0=1; //ADC enable(bit1)
CM1CON0=0; //disable comparators
CM2CON0=0;
//ADCON1 = 0x80; //Setting result format, conversion clock and activating ADC function.
//TRISA = 0x2F; //Setting Port A as input.
//TRISE = 0x07; //Setting Port E as input.
//TRISC = 0x80; //Setting Port C as input and output
TRISA=0xFF; // PORTA is input
PORTA=0;

ADC_init();
UART1_Init(9600); // Initialize UART module at 9600 bps
Delay_ms(100); // Wait for UART module to stabilize

UART1_Write_Text("Start");
UART1_Write(10);
UART1_Write(13);

while(1) {
delay_ms(250);
adc_rd = ADC_read(2); // get ADC value from 2nd channel
//adc_rd = adc_rd*5;
//adc_rd = adc_rd/10;

inttostr(adc_rd,text);
UART1_write_text(text);
UART1_write_text("\n");
UART1_write_text("\r");
}




 

Code:
// Define LCD
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB3_bit;
sbit LCD_D5 at RB2_bit;
sbit LCD_D6 at RB1_bit;
sbit LCD_D7 at RB0_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB3_bit;
sbit LCD_D5_Direction at TRISB2_bit;
sbit LCD_D6_Direction at TRISB1_bit;
sbit LCD_D7_Direction at TRISB0_bit;
unsigned int adcvalue,value;
unsigned char car,x,y;
char *voltage = "00.00";
long temp;
void ShowADC(int x, int y, unsigned int adcvalue)      // Routine to show the value of the ADC_read
{
car = adcvalue / 1000;
LCD_Chr(x,y,48+car);
adcvalue=adcvalue-1000*car;
car = (adcvalue / 100);
LCD_Chr_CP(48+car);
adcvalue=adcvalue-100*car;
car = (adcvalue / 10);
LCD_Chr_CP(48+car);
adcvalue=adcvalue-10*car;
car = adcvalue;
LCD_Chr_CP(48+car);
delay_ms(30);
}
void ShowVoltage (int x,int y, unsigned int value)     // Routine to show the ADC_read conversion in Volt
{
temp = (long)value* 5000;                      
temp = temp / 1023;
voltage[0] = temp/10000 + 48;
voltage[1] = (temp/1000)%10 + 48;
voltage[3] = (temp/100)%10 + 48;
voltage[4] = (temp/10)%10 + 48;
Lcd_Out (x,y,voltage);
delay_ms(30);
}
void main() {
ADCON1 = 0x80;                          // All analogs - right justify
TRISA = 0xFF;                               // PORTA Input
TRISB = 0;                                    // PORTB Output
TRISD = 0;
Lcd_Init();
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_Out(1, 1, " ADC Voltage");
do {
value = ADC_Read(1);                    // channel 1 (RA1)
adcvalue=value;
Lcd_Out(3,1,"Ch1:");
ShowADC (3,5,adcvalue);
ShowVoltage(3,11,value);
value = ADC_Read(2);                    // channel 2 (RA2)
adcvalue=value;
Lcd_Out(4,1,"Ch2:");
ShowADC (4,5,adcvalue);
ShowVoltage(4,11,value);
} while(1);
}

Check the adc value, you must convert it:

Code:
temp = (long)value* 5000;                      
temp = temp / 1023;
 

hi xbased,
im sorry for the confusion i created.
what i meant was i know how to convert the adc value to volt... i already can display it in lcd...

but every time i convert it and sent it via uart, the terminal is not displaying anything...
the best i can go is only displaying the adc value in the terminal...
please..help needed...
 

Please zip and post your mikroC files and Proteus file. I will check it. I don't see any problem in the code. Only thing I see is you have disabled interrupts and if Serial interrupt is disabled then UART code will not work as it needs Serial interrupts to be enabled.
 

i want to send this value to an xbee connected to the computer...i have tested the hardware mode itself...the xctu software only displaying the adc value..i cannot make it to display the value in actual voltage value
lets say im measuring 4.99 volts-the display software will display 1023 only...
i want to make it to display 4.99 volts in the software itself..
thats the part i dont know how to write the coding..
..thats my problem here is the code and the proteus file...thanks in advance jayanth.devarayanadurga
 

Attachments

  • New Folder (4).zip
    25.6 KB · Views: 97

If your adc value is 1023 for 4.99V then

1023 * x = 4.99V

x = 4.99V/1023

x = 0.0048778103616813

1/x = 205.0100200400802

adc_val = adc_val * 0.0048778103616813

or

adc_val = adc_val / 205.0100200400802

Another way to calculate x is

adc_val = adc_val * Vref / 1023

x = Vref / 1023

x = 5 / 1023

x = 0.0048875855327468
 



ok...after this is done..how i can possibly send the X value to the pc?i am totally blank on this sending to pc (uart) part only...other calculation all ok for me...
i am totally confused on the sending...
if i do this calculation and insert the uart part as the old code, the value is not being displayed in the pc..
 

Calculate adc_value. If it contains some value like 4.567890 then use FloatToStr() to get the string of adc_val and then send this string as text to UART. If you use UARTx_Write_Text() then you have to add the delimiter to the end of the String else use UARTx_Write()


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void main(){
      unsigned char str_adc_val[17];
      unsigned int i = 0;
 
      while(1)[
             adc_val = adc_val * 5 / 1023;
             FloatToStr(adc_val, str_adc_val);
             
             while(str_adc_val[i]){
                        UART1_Write(str_adc_val[i++]);
             }
 
      }
}



Edit: Delimiter not needed for UARTx_Write_Text() function. Delimiter is needed for UARTx_Read_Text() function.
 
Last edited:
thank you for your fast reply!! really appreciate it....exactly this transmitting area is my weakness...
i done something with my code..
is this ok?

void main() {
int adc_rd;
//char text[12];
unsigned char str_adc_val[17];
unsigned int i = 0;

ANSEL = 0b00000100; // Configure AN2 pin as analog
ANSELH=0; //other are digital
INTCON=0; //disable interrupts
ADCON0=1; //ADC enable(bit1)
CM1CON0=0; //disable comparators
CM2CON0=0;

TRISA=0xFF; // PORTA is input
PORTA=0;

ADC_init();
UART1_Init(9600); // Initialize UART module at 9600 bps
Delay_ms(100); // Wait for UART module to stabilize

UART1_Write_Text("Start");
UART1_Write(10);
UART1_Write(13);

while(1) {
delay_ms(250);
adc_rd = ADC_read(2); // get ADC value from 2nd channel
adc_rd = adc_rd * 5000 / 1023;
FloatToStr(adc_rd, str_adc_val);

while(str_adc_val){
UART1_Write_text(str_adc_val[i++]);
}

UART1_write_text("\n");
UART1_write_text("\r");
}
}
 

Change this int adc_rd; to this float adc_rd; Change this UART1_Write_text(str_adc_val[i++]); to this UART1_Write(str_adc_val[i++]);

Try this


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
//lcd module connections
sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB1_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;
sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
 
void main() {
 
       float adc_val = 0.0, old_val = 0.0;
       unsigned char str_adc_val[17];
       unsigned int i = 0;
       
       TRISA = 0b00000100;
       PORTA = 0x00;
       TRISB = 0x00;
       PORTB = 0x00;
       TRISC = 0x80;
       PORTC = 0x00;
       ANSEL = 0b00000100;
       ANSELH = 0x00;
       ADCON1 = 0x80;
       CM1CON0 = 0x00;
       CM2CON0 = 0x00;
       VRCON.VROE = 0;
       
       LCD_Init();
       LCD_Cmd(_LCD_CLEAR);
       LCD_Cmd(_LCD_CURSOR_OFF);
       LCD_Out(1,1,"ADC XBee Example");
       
       UART1_Init(9600);
       Delay_ms(100);
       
       
       while(1){
       
            adc_val = ADC_Read(2);
            adc_val = adc_val * 5 / 1023;
            if(adc_val != old_val){
                   old_val = adc_val;
                   FloatToStr(adc_val, str_adc_val);
                   LCD_Out(2,1,str_adc_val);
                   i = 0;
                   while(str_adc_val[i]){
                            UART1_Write(str_adc_val[i++]);
                   }
                   UART1_Write(0x0D);
                   UART1_Write(0x0A);
            }
       }
}




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
//lcd module connections
sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB1_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;
sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
 
void main() {
 
       float adc_val = 0.0, old_val = 0.0;
       unsigned char str_adc_val[17];
       unsigned int i = 0;
       
       TRISA = 0b00000100;
       PORTA = 0x00;
       TRISB = 0x00;
       PORTB = 0x00;
       TRISC = 0x80;
       PORTC = 0x00;
       ANSEL = 0b00000100;
       ANSELH = 0x00;
       ADCON1 = 0x80;
       CM1CON0 = 0x00;
       CM2CON0 = 0x00;
       VRCON.VROE = 0;
       
       LCD_Init();
       LCD_Cmd(_LCD_CLEAR);
       LCD_Cmd(_LCD_CURSOR_OFF);
       LCD_Out(1,1,"ADC XBee Example");
       
       UART1_Init(9600);
       Delay_ms(100);
       
       
       while(1){
       
            adc_val = ADC_Read(2);
            adc_val = adc_val * 5 / 1023;
            if(adc_val != old_val){
                   old_val = adc_val;
                   FloatToStr(adc_val, str_adc_val);
                   LCD_Out(2,1,str_adc_val);
                   i = 0;
                   //while(str_adc_val[i]){
                            //UART1_Write(str_adc_val[i++]);
                   //}
                   UART1_Write_Text(str_adc_val);
                   UART1_Write(0x0D);
                   UART1_Write(0x0A);
            }
       }
}



 

Attachments

  • XBee.rar
    275 KB · Views: 116
  • XBee.png
    59.8 KB · Views: 134
  • XBee v2.rar
    262.6 KB · Views: 116
Last edited:





void main() {
float adc_rd;

char volt;
unsigned char str_adc_val[17];
unsigned int i = 0;

ANSEL = 0b00000100; // Configure AN2 pin as analog
ANSELH=0; //other are digital
INTCON=0; //disable interrupts
ADCON0=1; //ADC enable(bit1)
CM1CON0=0; //disable comparators
CM2CON0=0;
//ADCON1 = 0x80; //Setting result format, conversion clock and activating ADC function.
//TRISA = 0x2F; //Setting Port A as input.
//TRISE = 0x07; //Setting Port E as input.
//TRISC = 0x80; //Setting Port C as input and output
TRISA=0xFF; // PORTA is input
PORTA=0;

ADC_init();
UART1_Init(9600); // Initialize UART module at 9600 bps
Delay_ms(100); // Wait for UART module to stabilize

UART1_Write_Text("Start");
UART1_Write(10);
UART1_Write(13);

while(1) {
delay_ms(250);
adc_rd = ADC_read(2); // get ADC value from 2nd channel
adc_rd = adc_rd *0.0048875855327468;
//volt = adc_rd;
FloatToStr(adc_rd, str_adc_val);
//adc_rd = adc_rd*5;
//adc_rd = adc_rd/10;
while(str_adc_val){
UART1_Write(str_adc_val[i++]);
}

UART1_write_text("\n");
UART1_write_text("\r");
}
}


this code works just fine!!! thanks alot!!!! u saved me...
sorry for the trouble i have caused you..
but one more last thing...
this code only takes one value and the stops...
when i reduce and increase the voltage, only the first reading is there..no more reading...
i have to stop and run it back everytime...
how to make it take reading continuously?
the print screen is attached..
 

Please see my previous post.

Put this line


Code C - [expand]
1
adc_val = adc_val * 5 / 1023;



inside the if() condition, so that controller will be freed from executing it all the time.
 
Last edited:

thank you sir!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
it works great!!!!!
u are a genius!!!
 

Read 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
//lcd module connections
sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB1_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;
sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
 
void main() {
 
       float adc_val = 0.0, old_val = 0.0;
       unsigned char str_adc_val[17];
       //unsigned int i = 0;
       
       TRISA = 0b00000100;
       PORTA = 0x00;
       TRISB = 0x00;
       PORTB = 0x00;
       TRISC = 0x80;
       PORTC = 0x00;
       ANSEL = 0b00000100;
       ANSELH = 0x00;
       ADCON1 = 0x80;
       CM1CON0 = 0x00;
       CM2CON0 = 0x00;
       VRCON.VROE = 0;
       
       LCD_Init();
       LCD_Cmd(_LCD_CLEAR);
       LCD_Cmd(_LCD_CURSOR_OFF);
       LCD_Out(1,1,"ADC XBee Example");
       
       UART1_Init(9600);
       Delay_ms(100);
       
       
       while(1){
       
            adc_val = ADC_Read(2);
            
            if(adc_val != old_val){
                   old_val = adc_val;
                   adc_val = adc_val * 5 / 1023;
                   FloatToStr(adc_val, str_adc_val);
                   LCD_Out(2,1,str_adc_val);
                   //i = 0;
                   //while(str_adc_val[i]){
                            //UART1_Write(str_adc_val[i++]);
                   //}
                   UART1_Write_Text(str_adc_val);
                   UART1_Write(0x0D);
                   UART1_Write(0x0A);
            }
       }
}

 
Last edited:



ok...everything is working fine now..
but can i use this to measure rms value of an ac voltage?220vac?
this is the modified circuit...
i am trying to display ac voltage in the display...
 

Last edited:

adc_val = ADC_Read(2);
adc_val = (adc_val * 5 / 1023)*60 ;
if(adc_val != old_val){
old_val = adc_val;
FloatToStr(adc_val, str_adc_val);

yes...is this something that u are saying?
 

Yes. Just measure AC voltage you are giving to primary of trf using a multimeter. If multimeter reads 230V AC and if you get 230 on UART then it is right.

If

3.833333333333333V = 230 Vrms AC
5V = 300 Vrms AC
 
Last edited:
Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…