Hi fella's, thanks for reading my post and hopefully one of you knowledgeable dudes can help me out!
I'm running an LM34 (datasheet: http://www.robotshop.com/content/PDF/lm34-datasheet-604-00011.pdf) and I would like to obtain the most stable temperature readings possible. The sensor is secured between 2 fins on a heat sink. I know that for this sensor to be accurate and stable it needs a stable voltage in. What is the best way of going about this? It's operating temps will only be between say, 50F and 100F, so I don't need anything crazy. It's currently bouncing around between 77F and 79F... I have readings set for every 2s and it just keeps bouncing back and forth.
Any advice on the best way to set this thing up would be most appreciated.
As the Arduino analogRead() can be a bit noisy in the last bits it is often advised to read at least twice and throw the first away (so the ADC can adapt). The other advise is to average multiple readings.
Average
void loop()
{
for (int i=0; i<4; i++) voltage += analogRead(0);
voltage = voltage * 5.0 /1024 /4; // voltage *= 0.001220703; // optimize the math.
...
}
Running Average (will take previos measurement into account, so it slowly (depending on weight) follows the changes preventing spikes)
float voltage;
setup()
{
..
voltage = AnalogRead(0) * 5.0;
}
void loop()
{
voltage = (analogRead(0) * 5.0 + voltage) /2; // one can add other weigths to both parts voltage = (analogRead(0) * 5.0 * 0.3 + voltage *0.7;
...
}
As the Arduino analogRead() can be a bit noisy in the last bits it is often advised to read at least twice and throw the first away (so the ADC can adapt). The other advise is to average multiple readings.
There are two separate things here. Firstly there is noise in the signal (and on the chip) leading to reading variation. This shouldn't be more than one LSB if the signal is low impedance and low noise. Secondly there is the issue of switching the analog multiplexer with a high-impedance signal source.
What analogRead() does is first set the analog multiplexer to connect the relevant analog pin to the ADC circuit, then it starts an analog conversion going. If the signal is high impedance (more than a few k ohms) then stray capacitances lead to error and you should call analogRead() twice, the first time ignoring the value - this is just to switch the multiplexer.
If you only ever read from one analog pin, this isn't required as the multiplexer never switches between pins. If the signal source is low impedance like the LM34 then again this isn't needed.
If the source has noise, especially if its high-frequency noise, then you can use averaging to get more precision, something like:
int value = 0 ;
for (byte i = 0 ; i < 16 ; i++)
{
value += analogRead (pin) ;
}
value = (value + 8) / 16 ;
(Although you get more accuracy by omitting the division at the end)
One problem you may have is ground loops - you don't say how the LM34 is wired up, and the best way to do it is as in figure 10 in that application note, so that you measure a differential signal. That way ground currents don't influence the result.
FlyingSteve:
I'm running an LM34 (datasheet: http://www.robotshop.com/content/PDF/lm34-datasheet-604-00011.pdf) and I would like to obtain the most stable temperature readings possible. The sensor is secured between 2 fins on a heat sink. I know that for this sensor to be accurate and stable it needs a stable voltage in.
Not so, the line regulation of that device is 0.1mV/V maximum, so it is higly insensitive to supply voltage. However, the reading you get will be sensitive to variations in the analog reference voltage, which by default is the 5v supply. My recommendations are:
Separate the LM34 ground wire from other ground paths. Use one Arduino ground pin to connect the ground terminal of the LM34, and the other ground pins to connect everything else. Even better (but perhaps overkill) is to connect the ground terminal of the LM34 direct to the Agnd pin of the mcu.
Use the 3.3v pin to provide the analog reference. Lookup analogReference() in the Reference section of the main site for the precautions to follow.
Thanks guys! For a little more clarity on my project... I am running this sensor, along with several other components, off of an 850W PC PSU. I have the LM34 Vin connected to a 5v wire from the PSU, it stays steady at 5.08V. The ground is connected to a ground wire on the PSU as well. The max voltage I seem to get from the Arduino Uno on the 5V pin is 4.81V... As of right now, this is the only analogRead function I have going on... But I will be adding more of these LM34's.
That 850W supply will be pretty noisy - definitely not suitable for Arduino analog reference, if you can use the 3V3 as a reference that ought to be a lot better.
If you follow the advice in my reply #3 then the noise should be much less of a problem. To use the 3.3v reference:
Connect the AREF pin to the 3.3v pin on the Arduino
In your sketch, in setup() call analogReference() to say you are using the external reference. You MUST do this before you make any analogRead() calls, otherwise you risk damaging the mcu or the 3.3v regulator. Look up analogReference() in the reference section of the main site for more information.