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 CCS Technical Support

adc_read()
Goto page Previous  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

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

asmboy wrote:
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 )


Alright,

I did so, now looks like:
Code:
void main (void)
{
  //test=1;
  UNSIGNED int16 adcval=0,value=0;
  float flt=0;
  SIGNED int8 i=0;
  setup_adc(ADC_CLOCK_DIV_32);
  setup_adc_ports( sAN14 );
  while (true) {
   set_adc_channel(14);
    delay_us(10);
    adcval=read_adc();
    value = (value * FILTER + adcval) / (FILTER + 1);
    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," - %Ld\r\n", adcval);
   delay_ms(100);
  }
}

and the maximum value read at 5V is 3339 which is slightly closer to 4095 but not quite there yet... started playing around with the ADC_CLOCK divider and actually get to read 4095 when I set the divider to setup_adc(ADC_CLOCK_DIV_4);!
cerr



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

View user's profile Send private message

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

But the problem now is, it already reads 4095 at 4.1V that's not what I want either! Mad
with ADC_CLOCK_DIV_8 the maximum value read at 5V is 3683 - that's as close as I can get with this...
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:39 pm     Reply with quote

I have never used the 18F86K22.
So no first hand idea of what else could be up with that chip
vis-a-vis CCS.

have u thought of testing this code on a more down market part?
temtronic



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

View user's profile Send private message

PostPosted: Thu Sep 15, 2011 1:38 pm     Reply with quote

I think it's time to really simplify...
get rid of the thermistor, and the 'math' in the program.
Just a simple 5K pot( I have a few nicew 10 turn ones here), and a silly program to read the adc and display the raw data,updating say every 1/4 second. Be sure the Vcc is a soild 5.00 volts. Let it run for 10-15 minutes, see how stable it is, can you get full range, numbers as they should be.
Once this is all confirm..then..add on the thermistor, see what happens.
I know you've may have done this, but 'something' is 'not right' and going back to a bare board....10 lines of code may be the only way to figure it out.
It might be something as simple as a power pin not connected, flakey ground,???

What temperature range do you want to read, maybe a thermocouple is better? I run thermistors in 'constant current bridges' for greater stability,btw.
asmboy



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

View user's profile Send private message AIM Address

PostPosted: Thu Sep 15, 2011 1:59 pm     Reply with quote

for degrees C or F and fractions

my choice for temps in the "solid-liquid-low/vapor" range of water is
the natsemi LM34(DZ) and so little math to make it real.

it is also very very amenable to the pullup resistor/port connection you already have too.........

its what i've used in water boiler controls for quite some time
and pretty well self calibrated too.
cerr



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

View user's profile Send private message

PostPosted: Thu Sep 15, 2011 2:14 pm     Reply with quote

temtronic wrote:
I think it's time to really simplify...
get rid of the thermistor, and the 'math' in the program.
Just a simple 5K pot( I have a few nicew 10 turn ones here), and a silly program to read the adc and display the raw data,updating say every 1/4 second. Be sure the Vcc is a soild 5.00 volts. Let it run for 10-15 minutes, see how stable it is, can you get full range, numbers as they should be.
Once this is all confirm..then..add on the thermistor, see what happens.
I know you've may have done this, but 'something' is 'not right' and going back to a bare board....10 lines of code may be the only way to figure it out.
It might be something as simple as a power pin not connected, flakey ground,???

What temperature range do you want to read, maybe a thermocouple is better? I run thermistors in 'constant current bridges' for greater stability,btw.


It's not that easy as you might think as I'm working with a PCBA, fully assembled. There however are a couple of pots on there as well going to another ADC (sAN22) - If i turn that all the way round I get 4.711V on the adc and read 3641 but mathematically, this number would equal out to 4.445V so there is some difference there too. The code now looks like this:
Code:
#include <18F86K22.h>
#device HIGH_INTS=TRUE, adc=12, 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)
#define FILTER 10
void main (void)
{
  UNSIGNED int16 adcval=0,value=0;
  SIGNED int8 i=0;
  setup_adc(ADC_CLOCK_DIV_8);
  setup_adc_ports( sAN22 );
  while (true) {
   set_adc_channel(22);
   fprintf(PC," - %Ld\r\n", read_adc());
   delay_ms(250);
  }
}   


If I look at it with the scope, I can see 200kHz spikes that are about 300uS long and they spike <+/- 1V - this is from the buck converter on the board. We've tried to minimalize them already as well as we could but didn't get rid of them completely... Would they mess up my adc conversions?
temtronic



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

View user's profile Send private message

PostPosted: Thu Sep 15, 2011 6:35 pm     Reply with quote

Oh yeah !!! Any noise is bad news and switchers are FULL of noise!! It's one reason why I use linear supplies for all critical ADC operations. Very easy to filter. Getting a 16 bit, 32 channel ADC to run right inside an Optical emission spectrometer was 'fun' (20KV, hundreds of ma, lethal really).
You might be able to use some 2 or 3 section Pi filters to knock out the noise. Also use wide ground and power traces, cross hatch large area of ground instead of solid area.
temtronic



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

View user's profile Send private message

PostPosted: Thu Sep 15, 2011 6:44 pm     Reply with quote

Nothing is ever easy...sigh.

Ok...try adding solid copper wire on top of the traces (power and ground), then add some decoupling caps (.1mfd, .01mfd, .001mfd), even a couple of 10mfd ...'here and there'...

Eliminating 'noise' is a 'black art', half science - half luck !!
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Thu Sep 15, 2011 7:23 pm     Reply with quote

When hunting down noise near a switcher, beware of your scope ground lead. The scope probe ground lead may create a loop that picks up magnetic (not electrical) noise from inductors. The scope may see electrical noise that is not really electrical.

Another hard learned troubleshooting gem...
_________________
The search for better is endless. Instead simply find very good and get the job done.
cerr



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

View user's profile Send private message

PostPosted: Fri Sep 16, 2011 11:18 am     Reply with quote

SherpaDoug wrote:
When hunting down noise near a switcher, beware of your scope ground lead. The scope probe ground lead may create a loop that picks up magnetic (not electrical) noise from inductors. The scope may see electrical noise that is not really electrical.

Another hard learned troubleshooting gem...

Well if only the scope sees it but the pic doesn't i would be fine with it too but my adc conversion apparently isn't working the way it ought to Sad
cerr



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

View user's profile Send private message

PostPosted: Fri Sep 16, 2011 12:30 pm     Reply with quote

Ok, I figured out a nasty work around:
if I disable to adc after reading like this:
Code:
#include <18F86K22.h>
#device HIGH_INTS=TRUE, adc=12

#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)
#define FILTER 10
void main (void)
{
  UNSIGNED int16 adcval=0,value=0;
  SIGNED int8 i=0;
  while (true) { 
   setup_adc(ADC_CLOCK_DIV_16);
    setup_adc_ports( /*sAN22*/sAN14 );
   set_adc_channel(/*22*/14);
    delay_us(50);
   fprintf(PC," - %Ld\r\n", read_adc());
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   delay_ms(250);
  }
}   

I seem to get somewhat good values but only between 0.8V and 4.2V. Everything below gives me weird values and at 0 V i get constantly 255 but when i'm some where between 0V and 0.8V I get to read smaller values than 255 too... it's weird... at 4.2V I read 4095 and it - of course - doesn't go higher... so that's where I'm at now but it sure isn't the place where i'd like to be! The values are all measured right at the pic and i'm using a isolated power supply to source the voltage on the adc that I measure with my scope (that's isolated to the PIC & the power supply as well)....this just isn't doing what I like it to do... Mad
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Sep 16, 2011 5:11 pm     Reply with quote

Quote:
#FUSES HSM //Hi-Speed crystal oscillator

#use delay(clock=20000000)

setup_adc(ADC_CLOCK_DIV_16);

As a test, change these to INTRC_IO, 4M, and ADC_CLOCK_DIV_4.
See if you then get the 4095 full-scale output.

I don't have your exact PIC, but I'm testing it with a 18F46K80 which
also has a 12-bit A/D, and I'm seeing some weird effects with a 20 MHz
crystal vs. a 4 MHz crystal (Or 4 MHz internal oscillator). At 20 MHz
the max value of the A/D result is limited to about 3900 (with +5v A/D
input). It's as if there is a problem with the TAD value. Maybe there is.

If I manually control the TAD by OR'ing in the ADC_TAD_MUL_20
parameter in setup_adc(), then it gives 4095. I don't have time to
investigate it any further this afternoon. But try the internal oscillator
and see if the problem goes away. You can leave the 20 MHz installed
while you do this test.
cerr



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

View user's profile Send private message

PostPosted: Mon Sep 19, 2011 10:25 am     Reply with quote

Nope,

changed the code to
Code:

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

#FUSES NOWDT                      //No Watch Dog Timer
#FUSES WDT128                     //Watch Dog Timer uses 1:128 Postscale
#FUSES INTRC_IO                       
#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=4000000)
#use rs232(baud=19200,parity=N,xmit=PIN_G2,rcv=PIN_G1,UART2,bits=8,stream=PC)
#define FILTER 10
void main (void)
{
  UNSIGNED int16 adcval=0;
  while (true) { 
   setup_adc(ADC_CLOCK_DIV_4);
    setup_adc_ports(sAN14);
   set_adc_channel(14);
    delay_us(10);
    adcval = read_adc();
   fprintf(PC," - %Ld\r\n", adcval);
   setup_adc(ADC_OFF);
   delay_ms(250);
  }
}   

and nothing has really changed, at 0V i read 159 and I'm maxed out at 4095 at 4.23V already.... I guess i'll go ahead and now and start playing around with TAD and see if i can get somewhere.

As always, Thanks for your help PCM!
cerr



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

View user's profile Send private message

PostPosted: Mon Sep 19, 2011 11:02 am     Reply with quote

So with ADC_CLOCK_DIV_2|ADC_TAD_MUL_2 I get 4095 at 4.78V and -1 at 72mV which is the best range so far but it's kinda weird, from -1 it jumps directly to 32 just a tiny wee bit higher(75mV)...however, this is the best result I got so far...I Might be able to go with that, further testing is required...
temtronic



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

View user's profile Send private message

PostPosted: Mon Sep 19, 2011 1:14 pm     Reply with quote

Ok...another road to try...how about using an external 12bit ADC ? I know going 'backwards' but maybe possible solution ?!?!?

Any help in any of Microchip's forums or someone else's ???
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 Previous  1, 2, 3  Next
Page 2 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