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

Temperature A/D conversion - LM35DT to PIC18F2580
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Gaara



Joined: 10 Feb 2014
Posts: 11

View user's profile Send private message

PostPosted: Wed Feb 12, 2014 7:39 am     Reply with quote

Hi temtronic,

thanks for the reply.


Depending on the application,you have to decide if accuracy of a wide range is critical( say +-.25*C) or not(+-1*C) is OK.Also how 'fine' a reading has to be(say +_.01*C or +-.1*C).I used the LM34 before PICs were around to control remote energy systems,with PICs I used them then switched to the DS digital sensors.It's one of the few 'upgrades' I've been more than happy with.


I intend on measuring the ambient temperature really to an accuracy level of only one decimal place hence the reason why I looked at the LM35 but having carefully read through ttelmah's suggestions I'm looking at making my code work with the LM335 especially as it does not involve extra circuity to generate negative voltage values.


re: DS18B20PAR. -ve temps set a bit in the 'temp registers' and there's a couple 'drivers' in the code library here that show how to extract and display the temperature correctly.As for calibration, you could run simple test of 'ice water','boiling water' using a goodm known thermometer as a reference


Is there a link to the code library you mentioned?


You also need to know that VDD is NOT a good voltage reference.
1) depending on the regulator used it could easily be 4.95-5.05 volts.
2) current drawn will change the VDD value.

re 2) Anytime the PIC does more work, or an LED turns on,relay, etc. more current is drawn and a 'dip' in VDD will occour.While the PIC still runs fine, the ADC ref will drop from what you think it always is.This will give you a 'bad' reading as the alculations will be in error as Vref is not 5.000.


Thanks as I didn't think of this hence this means I need to use the internal Vref which is set to 5.0V (I think), how do I go about declaring I assume in the function setup_adc_ports() the use of the VREF in the code ?

Thanks.
Ttelmah



Joined: 11 Mar 2010
Posts: 19544

View user's profile Send private message

PostPosted: Wed Feb 12, 2014 10:03 am     Reply with quote

There is not an internal voltage reference in your chip...
There is a _comparator_ reference, which is just a voltage divider off the power supply.
A voltage reference always gives a voltage below the supply. So you could add (say) an external bandgap 4.096v reference, the sensor chips will give an accurate 2.5 counts per degree then.
On the chip types there are about five different accuracy variants, including ones with certified zero calibration available. (LM335AZ).
It is all down to what accuracy you actually want/need. With your original supply giving Vref, there is no point in trying to be super accurate on the conversion, since you are starting with a low accuracy reference. Improve the reference, and it becomes worth improving the rest of the circuit.
Gaara



Joined: 10 Feb 2014
Posts: 11

View user's profile Send private message

PostPosted: Fri Feb 14, 2014 5:50 am     Reply with quote

Hi all,

I've purchased the LM335 and hooked it up as per figure 15 in the datasheet - http://www.ti.com/lit/ds/symlink/lm335.pdf. The voltage on the output is 2.98v which is in and round the expected voltage for room temperature (kindly correct me if I'm wrong in saying this). I'm using a 2k2 resistor as proposed by Ttlemah as seen in the very last reply on this post - http://www.ccsinfo.com/forum/viewtopic.php?t=26366.

I've adjusted my code as seen below:

Code:

#include<18F2580.h>

#device adc=10

#fuses XT,PUT,NOBROWNOUT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=14400, parity=N, xmit=PIN_C6, rcv=PIN_C7, STREAM=HWAREUART, ERRORS)

int16 temp_value, adc_value;

void temp_sensor();

void temp_sensor() {

   setup_adc_ports(AN0);   
   setup_adc(ADC_CLOCK_DIV_4);
   set_adc_channel(0);   

   adc_value = read_adc();

   if(adc_done()) {
      temp_value = (adc_value - 559L)/2;

      fprintf(HWAREUART, "Temp is %u\r\n", temp_value);
   }
}

void main() {
   do {
      temp_sensor();
   } while (TRUE);
}


Can anyone identify any loopholes in both my hardware and software setup?

Thanks
temtronic



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

View user's profile Send private message

PostPosted: Fri Feb 14, 2014 6:27 am     Reply with quote

hardware...
pay attention to wiring, filtering,lead length, etc. when using analog sensors.If long length, use shielded cables.

software...
not really 'loopholes' but 'programming styles'...
1)..setup_adc_ports(AN0);
I do this outside of the 'readADC-displayADC' loop.
There's no point in executing it every time.

2) after the printing, I'd add a delay( say 500ms),so you can see the results.

3) 4MHZ is pretty slow, I'd crank up to at least 16megs.

4) I tend to put comments on most lines of code( old assembler habit).A month ,even a day from now ,you'll wonder WHAT does 559L mean?

5) I never use adc_done(); instead just add a small delay...
..
set_adc_channel(0); //select input to adc
delay_us(20); //wait to settle adc
adc_value=read_adc(); //get adc result
..

6) I try to avoid using 'temp' in variables for 'temperature'.I get confused if it's the real data or a 'temporary' data.

7) similar, I use HWUART for hardware UARTs, a bit less typing, hopefully less errors!

heck, if it works GREAT ! Just be sure to copy the source,saving this version as a 'working' example, to build upon.

hth
jay
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Feb 14, 2014 7:21 am     Reply with quote

Code:
   adc_value = read_adc();

   if(adc_done()) {
      temp_value = (adc_value - 559L)/2;
This will work correct but the call to adc_done makes no sense!
When you call read_adc without parameters it will block until the ADC is ready with the conversion and then returns the value. So, the call to adc_done will always yield true.
The code is identical to the simplified:
Code:
   adc_value = read_adc();

   temp_value = (adc_value - 559L)/2;


The only time when adc_done() is needed is when you call read_adc() in combination with the parameter ADC_START_ONLY. This has the advantage that your code can do other things while in the background the ADC is doing the relative slow conversion, or when you want the data to be handled in an interrupt handler. For example:
Code:
set_adc_channel(0);
read_adc(ADC_START_ONLY);
while(! adc_done()) {
  // do other stuff
}
value = read_adc();
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Feb 14, 2014 7:25 am     Reply with quote

temtronic wrote:
5) I never use adc_done(); instead just add a small delay...
..
set_adc_channel(0); //select input to adc
delay_us(20); //wait to settle adc
adc_value=read_adc(); //get adc result
..
I agree about never using adc_done, but I don't see how this relates to your using of the delay? It is good to have a small delay _before_ the start of the ADC sampling, but the adc_done() call is executed _after_ the read_adc() call.
asmboy



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

View user's profile Send private message AIM Address

PostPosted: Fri Feb 14, 2014 9:54 pm     Reply with quote

if you are not going to use analog processing, and are using the LM335,
then the best resolution will be derived from using an ADC reference voltage as close to your maximum expected LM335 voltage reading as possible. this is true no matter how many bits you will be converting to.

i leave it to you to suss out WHY this is the case Very Happy Very Happy

you never did mention what resolution was required in your application.
is this a school project OR for a real,honest to goodness l product ??
gpsmikey



Joined: 16 Nov 2010
Posts: 588
Location: Kirkland, WA

View user's profile Send private message

PostPosted: Sat Feb 15, 2014 6:40 am     Reply with quote

You also need to be very careful when you start talking about measuring in fractions of a degree - how close is your sensor to your regulator (or anything else on the board that generates heat). How long are the leads on the sensor since they can conduct heat? I don't remember right off hand, what is the level of "self heating" for that sensor? Is there airflow past it or is it in a dead pocket which would keep it from measuring the environment correctly? Just because you can measure 34.72 degrees with the A/D does not mean it is that temp ... Twisted Evil

mikey
_________________
mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3
Ttelmah



Joined: 11 Mar 2010
Posts: 19544

View user's profile Send private message

PostPosted: Sat Feb 15, 2014 10:52 am     Reply with quote

Very true.

In fact it gets worse. Problem is that the sensor chip itself will 'self heat'. Now the more current you put through it the worse this is, but if the current is too low, then the input requirements of the ADC can't be met....
Hence buffering becomes necessary as increased accuracy is required.

The sensors here are fine, if you want to measure a temperature like 36C, 37C etc.. However if you want 36.1, with the extra decimal really having meaning, more work is needed.
asmboy



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

View user's profile Send private message AIM Address

PostPosted: Sat Feb 15, 2014 2:09 pm     Reply with quote

another trick which can improve resolution:

i have a design for a biologic research microscope stage heater,
which is required to hold a setpoint of better than+/- .35 % deg-C over the narrow range of 30 to 44 deg centigrade, with 37 degees being nominal.

i ultimately used the Fahrenheit LM34 sensors , analog processing and 3 sensors in total for the design, and had to do quite a bit of coding to get useable calibration for each sensor. The user only sees Cent readings, but internally all calcs are done "F-space", with an 18F 12bit ADC PIC.

the point being that using a Farenheit scaled sensor provides more raw temperature resolution than the internally scaled Cent of Celsius absolute parts do.

this previous post might be of use to you too.
http://www.ccsinfo.com/forum/viewtopic.php?t=50354&highlight=
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
Page 2 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