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

PIC18F87K22 ADC
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
beaker404



Joined: 24 Jul 2012
Posts: 163

View user's profile Send private message

PIC18F87K22 ADC
PostPosted: Tue Apr 23, 2019 4:08 pm     Reply with quote

datasheet says 12ADC. read the device .H file, no config for ADC resolution.

setting up like this:

Code:
setup_adc(ADC_CLOCK_DIV_64 | ADC_TAD_MUL_0);          // set up ADC
setup_adc_ports(sAN0|VSS_VDD);     


and calling like this for AN0:

Code:
set_adc_channel(0);
delay_us(50);
adc_value = read_adc();


adc_value is in INT16

ADC seems to be running at 8 bit resolution. for a 0.775V input to AN0, i get a value of 40 decimal returned.

Not clear on how to set the negative side of AN0 to ground, did not see how to do that in the .H file.
beaker404



Joined: 24 Jul 2012
Posts: 163

View user's profile Send private message

PostPosted: Tue Apr 23, 2019 4:09 pm     Reply with quote

Oh, CCS V5.064
windows 10
pic is running at 40MHz
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Apr 23, 2019 5:59 pm     Reply with quote

Look in the read_adc() section of the CCS manual. You use a #device
statement to set the number of bits.

Vss is ground.
Quote:
setup_adc_ports(sAN0|VSS_VDD);
beaker404



Joined: 24 Jul 2012
Posts: 163

View user's profile Send private message

PostPosted: Thu Apr 25, 2019 7:37 am     Reply with quote

Yep, setting to 12 bit resolved the problem YESTERDAY.
for some reason, I thought 12 Bit was the only option.
today, though, back to getting an 8 bit range number even though adc is set for 12 bit the proper voltage is going to the ADC port too.
beaker404



Joined: 24 Jul 2012
Posts: 163

View user's profile Send private message

PostPosted: Thu Apr 25, 2019 8:14 am     Reply with quote

ADC is returning -24279 when in 12 bit mode. if I comment out the #device adc=12 line it returns a 41

Code:
   setup_adc(ADC_CLOCK_DIV_64 | ADC_TAD_MUL_0);          // set up ADC
   setup_adc_ports(sAN0|VSS_VDD);                        // only AN0 is analog port with range of 0 - 5VDC


Code:
set_adc_channel(0);
delay_us(50);
adc_value = read_adc();

//value = (int)(((adc_value/4096.0)*5.0)/0.01);                // convert ADC to degrees F cast to INT to save space only need INT precision
value = (int)adc_value;



commented out line is so I can see the ADC value as it is read in.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Thu Apr 25, 2019 8:58 am     Reply with quote

-24279. No it isn't....

It is returning an _unsigned_ integer, but you are printing it as signed.

If you use #DEVICE ADC=12
you can't cast this to an 'int'. Casting just forces a byte to be treated 'as if'
it was the target type. It'll truncate the top part and result in numeric errors.

Now you are performing your maths with float. result huge amount of
wasted code size. The maths itself seems 'wrong'. /0.01 is the same as
*100 (which would be faster...), but you have a voltage 0 to 5 feeding
this part of the maths so would get 0 to 500.

The way to do this is work in integer:
Assuming adc_value is declared as an int16 (which it needs to be if
the ADC is set to 12bit output):

value = ((int32)adc_value*500)/4096;

Would give the same result as your current sum, just using int32
arithmetic. You are multiplying by 5, and by 100, and dividing by 4096.

In integer do the multiplications first to avoid working with fractions.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Apr 25, 2019 9:10 am     Reply with quote

beaker404 wrote:
ADC is returning -24279 when in 12 bit mode. if I comment out the #device adc=12 line it returns a 41

What voltage are you applying to the adc input pin, that gives this result ?

beaker404 wrote:
ADC is returning -24279 when in 12 bit mode. if I comment out the #device adc=12 line it returns a 41

What method are you using to display the ADC result ?
I don't see a printf statement in your posted code. If you're using printf,
post that line. Are you using the debugger ? If so, what debugger,
hardware or MPLAB Sim ? Also, what version of MPLAB ?

beaker404 wrote:

//value = (int)(((adc_value/4096.0)*5.0)/0.01); // convert ADC to degrees F cast to INT to save space only need INT precision
value = (int)adc_value;

commented out line is so I can see the ADC value as it is read in.

If you cast to an 'int', you are casting to an 8-bit value (with the PCH
compiler). The compiler throws away all upper bits. For example, if
your adc result is 0x1234, after a cast to 'int', you will get 0x0034.
beaker404



Joined: 24 Jul 2012
Posts: 163

View user's profile Send private message

PostPosted: Thu Apr 25, 2019 9:13 am     Reply with quote

I understand your reasoning for the math.
the 0.01 comes into play to scale the voltage calculation to deg F.

still do not understand why I cannot print the ADC counts today and yesterday I could.
Just not getting the same numbers as yesterday.
beaker404



Joined: 24 Jul 2012
Posts: 163

View user's profile Send private message

PostPosted: Thu Apr 25, 2019 9:36 am     Reply with quote

fprintf(SERIAL,"** DEG F= %Lu#\n\r",adc_value);

prints as 41257

this is the number from the adc_read should be 635
beaker404



Joined: 24 Jul 2012
Posts: 163

View user's profile Send private message

PostPosted: Thu Apr 25, 2019 9:52 am     Reply with quote

no sim or debugger, just running PIC and looking at results on hyperterminal.
MPLAB V 8.91
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Apr 25, 2019 10:06 am     Reply with quote

beaker404 wrote:
fprintf(SERIAL,"** DEG F= %Lu#\n\r",adc_value);

prints as 41257

this is the number from the adc_read should be 635

What is the input voltage (measured on the ADC pin with a scope) that
gives that value ?
beaker404



Joined: 24 Jul 2012
Posts: 163

View user's profile Send private message

PostPosted: Thu Apr 25, 2019 10:08 am     Reply with quote

0.775V on the pin and that is the same as from the temperature sensor.
beaker404



Joined: 24 Jul 2012
Posts: 163

View user's profile Send private message

PostPosted: Thu Apr 25, 2019 10:15 am     Reply with quote

moved voltage to AN1 and get the same result, perhaps the ADC is shot? was working last night when I left, this morning turned it on and this happened.
cleaning people were in the office last night and stuff always gets moved around with them around.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Apr 25, 2019 10:22 am     Reply with quote

I note that 41257 / 64 = 645. Just a preliminary observation.

Can you post the top several lines of your program ? I want to see the
#device adc statement, and the #fuses, and the #use delay().
beaker404



Joined: 24 Jul 2012
Posts: 163

View user's profile Send private message

PostPosted: Thu Apr 25, 2019 10:52 am     Reply with quote

ye did that math too for the magical 64 number.

Code:
/*
*********************************************************************************************
*  INCLUDES and CONTROLLER SETTINGS
*********************************************************************************************
*/
#DEVICE PIC18F87K22
#DEVICE ADC=12

#include <18F87K22.h>
#include <stdlib.h>

#FUSES HSH              // UP TO 25MHZ CRYSTAL.
#FUSES NOEBTRB
#FUSES NOEBTR
#FUSES NOWRTD
#FUSES NOWRTB
#FUSES NOPROTECT
#FUSES NOCPB
#FUSES NOCPD
#FUSES NOWRT
#FUSES NODEBUG
#FUSES NOSTVREN
#FUSES NOMCLR
#FUSES NOWAIT
#FUSES NOWDT
#FUSES NOIESO
#FUSES PUT                          // enable power up timer delay
#FUSES NOBROWNOUT
#FUSES NOFCMEN
#FUSES NOPLLEN

#USE delay(CRYSTAL=10000000, CLOCK=40000000)
#USE rs232(UART1,baud=38400, xmit=PIN_C6,rcv=PIN_C7,STREAM=SERIAL,errors)
#USE SPI(MASTER, MODE=0, SPI1, STREAM=SPI,FORCE_HW)
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  Next
Page 1 of 2

 
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