CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

problem with A/D
Goto page 1, 2, 3, 4  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Sep 24, 2007 12:15 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Aug 27, 2009 9:41 am     Reply with quote

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







PostPosted: Thu Aug 27, 2009 9:52 am     Reply with quote

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

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Aug 27, 2009 9:56 am     Reply with quote

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

View user's profile Send private message

i got it
PostPosted: Thu Aug 27, 2009 10:11 pm     Reply with quote

you are right ........ thanks bro
djole_nisam_ja



Joined: 10 Dec 2009
Posts: 18

View user's profile Send private message

PostPosted: Wed Dec 23, 2009 7:33 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Dec 23, 2009 7:57 am     Reply with quote

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







PostPosted: Wed Dec 23, 2009 8:50 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Dec 23, 2009 9:26 am     Reply with quote

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







PostPosted: Wed Dec 23, 2009 10:48 am     Reply with quote

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

View user's profile Send private message Send e-mail

PostPosted: Wed Dec 23, 2009 11:25 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Dec 23, 2009 12:15 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Dec 23, 2009 12:24 pm     Reply with quote

[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

View user's profile Send private message

PostPosted: Wed Dec 23, 2009 12:52 pm     Reply with quote

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

View user's profile Send private message Send e-mail

PostPosted: Wed Dec 23, 2009 1:27 pm     Reply with quote

[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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2, 3, 4  Next
Page 1 of 4

 
Jump to:  
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