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

adc_read()
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
cerr



Joined: 10 Feb 2011
Posts: 241
Location: Vancouver, BC

View user's profile Send private message

adc_read()
PostPosted: Wed Sep 14, 2011 12:26 pm     Reply with quote

Hi There,

I got some funny results from the temperature chamber today:
I read the voltage over a 10k ntc connected to GND and the PIC's (18F86K22) adc with a 10k pullup to +5V.
I got following results:
read_adc() read 4086 (12bit adc) at -10.3C (it's 4095 when I go slightly lower) & the voltmeter showed 4.25V across the NTC. A little calculation tells me that the ntc was at 56.6k and the datasheet tells me it oughta be at 46k at -10C but that's not the problem, the problem is that assuming the adc reads 4095 at 5V, it should read 3480 at 4.25V, right? My reference voltage is det to default which should be the +5V of the MCU, right?
Any clue what might be going on here?
Thank you!

Ron
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Wed Sep 14, 2011 12:40 pm     Reply with quote

post your CODE and compiler version !
12 bits is only 4095 so you are close to top scale
be sure you are formatted properly

to read 12 bits make sure you have:
#device adc=16

and stuff the results into an unsigned INT16
for starters

you could just as easily be having a circuitry problem here too

what value do you see if you read teh NTC part with an ohm meter
and do the scalar ration bit ??

if you really have a solid 5.0v and 1% 10 k pullup
your adc reading near full scale
says its WAY more than 50K ohms --
as in 500K ohms more like it

are you SURE your therm connection is SOLID ?

and that your CLOCKING of the ADC is within spec??


Last edited by asmboy on Wed Sep 14, 2011 1:01 pm; edited 1 time in total
temtronic



Joined: 01 Jul 2010
Posts: 9174
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Sep 14, 2011 12:58 pm     Reply with quote

All sorts of 'well it could be'......

Non regulated, non precise 5 volt supply....

Wiring not shielded...long lines,etc.

Someone's cellphone or wireless router reset during a reading..

'Glitches' on the power supply feed,EMI,RFI,etc....

NTCs are very nonlinear,prone to selfheating effects...

Make/model of the NTC , any buffer between it and the PIC ?

Adequate bypass caps ???

that outght to be a start ???!!!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Sep 14, 2011 1:09 pm     Reply with quote

You're doing a new thread for every aspect of the same NTC problem
so the previous info isn't readily available. But I recall that you don't have
any sort of opamp buffer or instrumentation amplifier circuit on your NTC.

The 18F86K22 data sheet says this, regarding the maximum source
impedance of the external circuit that's feeding the A/D:
Code:

Param
No.   Symbol  Characteristic         Min   Typ   Max

A30   ZAIN    Recommended             -     -    2.5 Kohm
              Impedance of Analog
              Voltage Source

This info is from a table on page 523 in the Acrobat reader in the data sheet:
http://ww1.microchip.com/downloads/en/DeviceDoc/39960d.pdf

It says it can't have a source resistance any higher than 2.5K. But your
NTC and the other resistor in the divider are much higher than that. So
the A/D is not getting the amount of current that it needs to operate within
parameters. This is most likely the main reason why you have accuracy
problems.

I think you need to need to add a suitable Op-Amp circuit to buffer the NTC.
cerr



Joined: 10 Feb 2011
Posts: 241
Location: Vancouver, BC

View user's profile Send private message

PostPosted: Wed Sep 14, 2011 3:00 pm     Reply with quote

asmboy wrote:
post your CODE and compiler version !
be sure you are formatted properly

4.119
right aligned format (ADCON2|=0x80;)
I have
#device adc=12 - had adc=16 before, no change, played around with that aleady, see other thread: #device adc=10 instead of =12

The result isn't even buffered as of right now, I got following:
Code:

fprintf(PC, "LPR temperature %Ld\r\n",read_adc());


I haven't measured the resistance yet...

the clocking of the adc is set to setup_adc (ADC_CLOCK_INTERNAL); just changed this now to ADC_CLOCK_DIV_32 as I recall that ADC_CLOCK_INTERNAL is really bad, isn't it?

Looking at the circuitry now as I have an impedance that's way higher than 2.5K in my circuitry. There actually also is a low pass filter with a 10k resistor in series and a 0.1uF cap towards ground. I'll measure if there's any voltage over the resistor (current flowing) and will see if bypassing it will change/improve results.

Thank you very much to everyone for the help.
cerr



Joined: 10 Feb 2011
Posts: 241
Location: Vancouver, BC

View user's profile Send private message

PostPosted: Wed Sep 14, 2011 3:21 pm     Reply with quote

Reading 10 - 13mV RMS across that serial filter resistor with the PIC side being at the higher end.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Sep 14, 2011 3:36 pm     Reply with quote

This is what is important, and you are grossly violating it:
Quote:

23.3 A/D Acquisition Requirements

For the A/D Converter to meet its specified accuracy,
the Charge Holding (CHOLD) capacitor must be allowed
to fully charge
to the input channel voltage level. The
analog input model is shown in Figure 23-5. The
source impedance (RS) and the internal sampling
switch (RSS) impedance directly affect the time
required to charge the capacitor
CHOLD. The sampling
switch (RSS) impedance varies over the device voltage
(VDD).
The source impedance affects the offset voltage at the
analog input (due to pin leakage current). The maximum
recommended impedance for analog sources is 2.5K.
cerr



Joined: 10 Feb 2011
Posts: 241
Location: Vancouver, BC

View user's profile Send private message

PostPosted: Wed Sep 14, 2011 4:11 pm     Reply with quote

right, I saw this! So we better be looking at re scaling these resistors? We wanna avoid adding another OPamp into our design if possible...

Thanks for the suggestions!
Ron
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Wed Sep 14, 2011 6:29 pm     Reply with quote

if you have a nominal 10k thermistor
i would be very interested to see how you can rescale anything
to get out of the hole you are in.

an opamp buffer is really the correct solution.
B U T ......
there is a cheaters way out with caveats

if you did not expect to take reading more than once half
minute or so
there is a little known but actually effective way to cheat this, especially at only 10 or 12 bits.

add a low leak film capacitor.

U C, with your choice of scaling Resistance - you have to take RC / integrating time of the A/D storage cap into account.

but for an infrequent measurement of a slow changing value like temperature -put a .22uf low leakage FILM capacitor from the PIC A/D
input pin to ground.

the "effective impedance" of this - over the sample time of the A/D conversion cycle will be low enough to get a good reading - so long as you do not read too often. with 10k and .22uf TC1 =2.2ms
using 100xTC1 - ( 220 ms between readings)
you can get a pretty good reading - in spite of the
apparent violation of the DC input impedance spec.
the reality of the PIC input spec is about IMPEDANCE / abilty to transfer charge - not a simple input resistance value.


been there done that have a nice t-shirt too.
cerr



Joined: 10 Feb 2011
Posts: 241
Location: Vancouver, BC

View user's profile Send private message

PostPosted: Thu Sep 15, 2011 10:41 am     Reply with quote

asmboy,

Thanks for this! Great suggestion, we will look at this a little closer later today. But why do you think I can't "Just" switch to a 1K NTC and a 1K pull up resistor? Shouldn't that help? (assuming the serial 10K filter resistor gets removed alltogether)...
cerr



Joined: 10 Feb 2011
Posts: 241
Location: Vancouver, BC

View user's profile Send private message

PostPosted: Thu Sep 15, 2011 11:18 am     Reply with quote

I got some more very interesting findings: I took a second isolated power supply and turned it up to +5V, I conntected it over the NTC and read the adc value, it reads 3519. I measured the voltage difference between the adc input on the pic and the Vdd of the pic which is 0.08V - why would the adc not read 4095 now? I'm confused. The serial filter resistor of 10k got bypassed. So i put +5V directly into the adc....I'm confused...

Thanks for assistance!
cerr



Joined: 10 Feb 2011
Posts: 241
Location: Vancouver, BC

View user's profile Send private message

PostPosted: Thu Sep 15, 2011 11:44 am     Reply with quote

Okay,

I now made a little test program to display my issue:
Code:

#include <18F86K22.h>
#device HIGH_INTS=TRUE, adc=16, ICD=TRUE

#FUSES NOWDT                      //No Watch Dog Timer
#FUSES WDT128                     //Watch Dog Timer uses 1:128 Postscale
#FUSES HSM                        //Hi-Speed crystal oscillator
#FUSES NOBROWNOUT                 //No brownout reset
#FUSES NOPLLEN                    //No PLL enabled
#FUSES BBSIZ1K                    //1K words Boot Block size
#FUSES NOXINST                    //Extended set extension and Indexed Addressing mode disabled (Legacy mode)

#use delay(clock=20000000)
#use rs232(baud=19200,parity=N,xmit=PIN_G2,rcv=PIN_G1,UART2,bits=8,stream=PC, ERRORS)
//#bit ADFM = ADCON2.7
#byte ADCON2 = getenv("sfr:ADCON2")
#define FILTER 10
void main (void)
{
  //test=1;
  SIGNED int16 adcval=0,value=0;
  float flt=0;
  SIGNED int8 i=0;
  setup_adc(ADC_CLOCK_DIV_32);
  ADCON2|= 0x80; 
  while (true) {
   set_adc_channel(14);
    delay_us(10);
    adcval=read_adc();
    value = (value * FILTER + adcval) / (FILTER + 1);
    flt = (flt *FILTER + adcval) / (FILTER + 1);
    fprintf(PC,"%f - ",flt);
    for (i=15;i>=0;i--) {
     if (i==7)
       fprintf(PC," ");    
     if (((value>>i)&0x01)==1)
    
       fprintf(PC,"1");
     else
       fprintf(PC,"0");
      
   }
   fprintf(PC," - 0x%Lx %Ld\r\n", adcval, adcval);
   delay_ms(100);
  }
}   

The maximum value it ever reads is adcval = 3327 even when i got over 5V with my isolated power source...
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Thu Sep 15, 2011 11:49 am     Reply with quote

1- 3327 is a very interesting number when expressed in binary.
it makes me think of formatting issues

2- i note you are using a SIGNED int16 to get adc_read()

why not UNSIGNED int 16 ?
( as the output IS unsigned )
3- and this ?? ADCON2|= 0x80;
hmmmmm?
cerr



Joined: 10 Feb 2011
Posts: 241
Location: Vancouver, BC

View user's profile Send private message

PostPosted: Thu Sep 15, 2011 12:06 pm     Reply with quote

asmboy wrote:
1- 3327 is a very interesting number when expressed in binary.
it makes me think of formatting issues

2- i note you are using a SIGNED int16 to get adc_read()

why not UNSIGNED int 16 ?
( as the output IS unsigned )
3- and this ?? ADCON2|= 0x80;
hmmmmm?

3327 = 1100 1111 1111 - formating issues, how?
turned SIGNED into UNSIGNED and there's no difference...adcval still stays at 3327....But interesting is, the first read ever after reprogramming the PIC returns 4095
ADCON2|= 0x80; just right aligns the values read.
hmmmmmmmm... what am i doing wrong i'm wondering, any hints?
Thanks,
Ron
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Thu Sep 15, 2011 12:08 pm     Reply with quote

AND IF YOU COMMENT THAT ADCON MANIPULATION OUT ???

I ALSO CANT FIND THIS RATHER IMPORTANT LINE

setup_adc_ports( AN0_AN1_AN3 );

of course CONFIGURED FOR YOUR pic PART to make sure 'chan 14' is properly
initialized for analog input in the first place

lastly - lose the data manipulation and cut to the chase

just show yourself the RAW adc count ADCVAL
a number from 0 -4095 ( %Lu )
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  Next
Page 1 of 3

 
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