|
|
View previous topic :: View next topic |
Author |
Message |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 24, 2007 12:15 pm |
|
|
Here's a demo program that shows how to display the A/D voltage
on the LCD, from 0 volts to 5.00 volts.
Code: |
#include <16F877.H>
#device adc=10
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
//#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#include "flex_lcd.c"
//============================
void main()
{
int16 adc_value;
float volts;
lcd_init();
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_DIV_8);
set_adc_channel(0);
delay_us(20);
while(1)
{
adc_value = read_adc();
volts = (float)(adc_value * 5)/1023.0;
printf(lcd_putc, "\f%3.2f", volts);
delay_ms(500);
}
} |
|
|
|
mutthunaveen
Joined: 08 Apr 2009 Posts: 100 Location: Chennai, India
|
|
Posted: Thu Aug 27, 2009 9:41 am |
|
|
Code: | printf(lcd_putc, "\f%3.2f", volts); |
hi this is really fine but i dont understand one thing in this what is 3.2 in this line |
|
|
Ttelmah Guest
|
|
Posted: Thu Aug 27, 2009 9:52 am |
|
|
Minimum of 3 characters output, with 2 after the decimal place.
Hence the .00, in the final value PCM programmer gives.
Best Wishes |
|
|
SET
Joined: 15 Nov 2005 Posts: 161 Location: Glasgow, UK
|
|
Posted: Thu Aug 27, 2009 9:56 am |
|
|
See:
http://en.wikipedia.org/wiki/Printf
So '3.2' means *at least* 3 digits before the decimal point (adding spaces if reqd) and *at least* 2 digits after the decimal point. |
|
|
mutthunaveen
Joined: 08 Apr 2009 Posts: 100 Location: Chennai, India
|
i got it |
Posted: Thu Aug 27, 2009 10:11 pm |
|
|
you are right ........ thanks bro |
|
|
djole_nisam_ja
Joined: 10 Dec 2009 Posts: 18
|
|
Posted: Wed Dec 23, 2009 7:33 am |
|
|
I have a problem calibrating with this code.
At first I used it in original for couple of measurements.
After some time it started to give me results on LCD shifted for 1 space to the right.
Example: instead of showing 1.43 it showed 0.14
so I had to change this line:
Code: | volts = (float)(adc_value * 5)/1023.0; |
into this line:
Code: | volts = (float)(adc_value * 50)/1023.0; |
What happened and how to solve this? |
|
|
meereck
Joined: 09 Nov 2006 Posts: 173
|
|
Posted: Wed Dec 23, 2009 7:57 am |
|
|
Just one follow-up question
Code: | volts = (float)(adc_value * 50)/1023.0; |
I am always confused whether it should be /1023 or /1024.
Which one is correct?
cheers |
|
|
Ttelmah Guest
|
|
Posted: Wed Dec 23, 2009 8:50 am |
|
|
SET wrote: | See:
So '3.2' means *at least* 3 digits before the decimal point (adding spaces if reqd) and *at least* 2 digits after the decimal point. |
Replying here to this old post first, but it is important to get this right....
No.
Not in C.
The first number is the 'minimum field width', _not_ the digits in front of the decimal place. In Fortran, or some of the standard 'maths' languages (CoBol for example), 3.2, would imply 3digits in front of the DP, but not in C.....
The 'answer' to /1023, or 1024, is actually quite complex!....
It depends on the ADC involved. Normally, with a linear ADC, going from 0, to 1023 output values, Just like the stair, where there would be 1024 levels, but only 1023 'risers', you would need to divide by 1023.
However the PIC ADC, is slightly 'odd' in this regard, which is why it is common to get the division wrong. The first oddity, is that unlike most ADC's, the change from a reading of '0', to '1', occurs at 1/nobits of the full scale, not at a half bit, which would be normal. Similarly, at the full voltage end, the transition occurs one bit 'below' the full voltage, not at half a bit below. Effectively it behaves as if it has one extra 'count', with it's steps spaced as if it had 1025 levels, instead of 1024, but with the two end levels giving the same reading, and shifted half a bit 'up'.
So the 'best fit' transfer function for the PIC, is:
Vout=((counts+0.4999999)/1024)*Vref
This gives the best fit to the actual PIC ADC transfer function, but you need to besure to only digits, or you will not see '0', and overshoot at the top by half a bit....
Best Wishes |
|
|
djole_nisam_ja
Joined: 10 Dec 2009 Posts: 18
|
|
Posted: Wed Dec 23, 2009 9:26 am |
|
|
Ttelmah wrote: | SET wrote: | See:
So '3.2' means *at least* 3 digits before the decimal point (adding spaces if reqd) and *at least* 2 digits after the decimal point. |
Replying here to this old post first, but it is important to get this right....
No.
Not in C.
The first number is the 'minimum field width', _not_ the digits in front of the decimal place. In Fortran, or some of the standard 'maths' languages (CoBol for example), 3.2, would imply 3digits in front of the DP, but not in C.....
The 'answer' to /1023, or 1024, is actually quite complex!....
It depends on the ADC involved. Normally, with a linear ADC, going from 0, to 1023 output values, Just like the stair, where there would be 1024 levels, but only 1023 'risers', you would need to divide by 1023.
However the PIC ADC, is slightly 'odd' in this regard, which is why it is common to get the division wrong. The first oddity, is that unlike most ADC's, the change from a reading of '0', to '1', occurs at 1/nobits of the full scale, not at a half bit, which would be normal. Similarly, at the full voltage end, the transition occurs one bit 'below' the full voltage, not at half a bit below. Effectively it behaves as if it has one extra 'count', with it's steps spaced as if it had 1025 levels, instead of 1024, but with the two end levels giving the same reading, and shifted half a bit 'up'.
So the 'best fit' transfer function for the PIC, is:
Vout=((counts+0.4999999)/1024)*Vref
This gives the best fit to the actual PIC ADC transfer function, but you need to besure to only digits, or you will not see '0', and overshoot at the top by half a bit....
Best Wishes |
Thanks for your quick reply. I tried it on my 18F4520.
Vref=5V
but I still need to multiply with 50 instead with 5.
Code: | Vout=((counts+0.4999999)/1024)*50 |
instead of
Code: | Vout=((counts+0.4999999)/1024)*5 |
and transfer function is not quite accurate, because it is still inaccurate for greater voltage while for lower voltage it is quite accurate
Example:
for Vout=0.63 real voltage is 0.63 but
for Vout=2.58 real voltage is 2.61
for Vout=3.34 real voltage is 3.48 |
|
|
Ttelmah Guest
|
|
Posted: Wed Dec 23, 2009 10:48 am |
|
|
I'd suggest that the problem is elsewhere. The accuracy of your Vref, or the source impedance of the circuit itself, or possibly noise on the circuit (because the PIC ADC, is capacitive, it tends to integrate noise on the incoming voltage, while voltmeters may tend to record 'peak' values).
Using a high accuracy Vref, and oversampling 16*, I have got good correlation between the PIC ADC, out to five digits, with a freshly calibrated Fluke DVM.....
However using the supply for Vref, often gives problems, since the PIC also tends to integrate noise on the supply line. This tends to give a lower than expected reading, and might be what you are seeing.
Best Wishes |
|
|
mkuang
Joined: 14 Dec 2007 Posts: 257
|
|
Posted: Wed Dec 23, 2009 11:25 am |
|
|
SET wrote: | See:
http://en.wikipedia.org/wiki/Printf
So '3.2' means *at least* 3 digits before the decimal point (adding spaces if reqd) and *at least* 2 digits after the decimal point. |
No, it means at least 3 digits before the decimal point, adding leading zeros if required (not spaces) and exactly 2 digits after the decimal point.
In addition, the Thevenin equivalent impedance as seen by the PIC A/D pin should be less than 10k (or is it 5K, you have to check the datasheet) or you may get the accuracy you are looking for. |
|
|
djole_nisam_ja
Joined: 10 Dec 2009 Posts: 18
|
|
Posted: Wed Dec 23, 2009 12:15 pm |
|
|
Ttelmah wrote: | I'd suggest that the problem is elsewhere. The accuracy of your Vref, or the source impedance of the circuit itself, or possibly noise on the circuit (because the PIC ADC, is capacitive, it tends to integrate noise on the incoming voltage, while voltmeters may tend to record 'peak' values).
Using a high accuracy Vref, and oversampling 16*, I have got good correlation between the PIC ADC, out to five digits, with a freshly calibrated Fluke DVM.....
However using the supply for Vref, often gives problems, since the PIC also tends to integrate noise on the supply line. This tends to give a lower than expected reading, and might be what you are seeing.
Best Wishes |
Could you please explain me what did you mean by "it tends to integrate noise on the incoming voltage" and by "oversampling 16*".
I am using Vref from my UNI-DS3 Development Board which I bought from Mikroelektronika, you think that could be a reason for this or something else? |
|
|
djole_nisam_ja
Joined: 10 Dec 2009 Posts: 18
|
|
Posted: Wed Dec 23, 2009 12:24 pm |
|
|
[quote="mkuang"] SET wrote: | See:
In addition, the Thevenin equivalent impedance as seen by the PIC A/D pin should be less than 10k (or is it 5K, you have to check the datasheet) or you may get the accuracy you are looking for. |
Excuse me mkuang, could you give me a help a bit.
Do you say that if I measure voltage on ADC pin (with voltmeter), I am actually not measuring the whole voltage (which measures the PIC) because of the ADC pin´s resistance? |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Wed Dec 23, 2009 12:52 pm |
|
|
Quote: | Do you say that if I measure voltage on ADC pin (with voltmeter), I am actually not measuring the whole voltage (which measures the PIC) because of the ADC pin´s resistance? | Right. You would need an oscilloscope to watch the input voltage at the sampling moment, which
is actually dropping due to the source resistance and the ADC's input impedance. The voltmeter is too
slow to follow it.
Your previous statement about a voltage factor 5 versus 50 is still confusing. You may want to dump the
actual ADC code and check the calculation by pencil and paper method. From the shown code, I can't follow
a factor of 50. |
|
|
mkuang
Joined: 14 Dec 2007 Posts: 257
|
|
Posted: Wed Dec 23, 2009 1:27 pm |
|
|
[quote="djole_nisam_ja"] mkuang wrote: | SET wrote: | See:
In addition, the Thevenin equivalent impedance as seen by the PIC A/D pin should be less than 10k (or is it 5K, you have to check the datasheet) or you may get the accuracy you are looking for. |
Excuse me mkuang, could you give me a help a bit.
Do you say that if I measure voltage on ADC pin (with voltmeter), I am actually not measuring the whole voltage (which measures the PIC) because of the ADC pin´s resistance? |
When was the last time your voltmeter was calibrated? How do you know how accurate it is even if the input signal is a nice dc level. Also be careful when you set your voltmeter on "auto-scale" as is common with some of these newer models your results may not be as accurate with some older models where you can specify the input voltage range you are looking for. In these older models the voltmeter can switch in the optimal value series resistor for measurement.
The differences between what the voltmeter measures and the PIC it looks like its about 1% or so, which could partially be attributed to this effect.
Also, to elaborate a little more (you may know this already) your voltmeter form a voltage divider with your source voltage. Now modern voltmeters typically have input impedances greater than a 10e9 Ohms so this is probably not a big deal unless your source impedance is very very large (like a megaohm or more). The PIC datasheet, however, specifies a maximum input impedance of 5-10K (you can check) or the results may be as accurate as you like it to be. At high source impedance you may also need more time for the A/D capacitors to charge to the final values.
These are just some of the problems you should be aware of. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|