|
|
View previous topic :: View next topic |
Author |
Message |
Gaara
Joined: 10 Feb 2014 Posts: 11
|
|
Posted: Wed Feb 12, 2014 7:39 am |
|
|
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
|
|
Posted: Wed Feb 12, 2014 10:03 am |
|
|
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
|
|
Posted: Fri Feb 14, 2014 5:50 am |
|
|
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
|
|
Posted: Fri Feb 14, 2014 6:27 am |
|
|
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
|
|
Posted: Fri Feb 14, 2014 7:21 am |
|
|
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
|
|
Posted: Fri Feb 14, 2014 7:25 am |
|
|
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
|
|
Posted: Fri Feb 14, 2014 9:54 pm |
|
|
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
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
|
|
Posted: Sat Feb 15, 2014 6:40 am |
|
|
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 ...
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
|
|
Posted: Sat Feb 15, 2014 10:52 am |
|
|
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
|
|
Posted: Sat Feb 15, 2014 2:09 pm |
|
|
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= |
|
|
|
|
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
|