Temperature variance using TMP36

Hi. First post and first Arduino project...

I'm working on a thermostat project to control the pellet burner I have in my house. The project will also include a weekly timer to start and stop the burner depending on day, time-of-day and temperature. I will integrate a real-time clock like BOB-00099 from Sparkfun later, right now I do all the timing in software. I use an Arduino Uno and a DF-Robot LCD Keypad shield together with a TMP36 temp sensor. http://www.dfrobot.com/wiki/index.php?title=Arduino_LCD%26KeyPad_Shield_(SKU:_DFR0009)#Document http://ardx.org/datasheet/IC-TMP36.pdf

I'm not so concerned about accuracy, but rather the variance in my temperature readings. Now I read the temp every 200ms, and I'm currently calculating the average of 80 readings. That means a new average calculated every 16 sec, and the result is displayed on the LCD and is also used to decide if the burner needs to start or stop . Still, the temperature displayed varies with as much as 0.5 degrees centigrade. I have a small digital thermometer next to my project to control the readings. I have increased from average of ten to average of 80 without achieving any more stability in the readings. The small digital thermometer is much more stable, and probably apply some sort of algorithm to stabilize the readings

What would be a good way software wise to get stable readings? Se my last readings below (I only use one decimal digit, although its printed with two here). Btw, for the switching of the pellet burner, I use a hysterisis of +- 0.5 degrees, and apply more dampening like only allowing change of state 30 minutes after last change of state.

24.05 23.87 24.02 23.83 24.00 23.82 24.01 23.79 23.99 24.04 23.78 24.06 23.77 23.97 24.07 23.69 23.95 24.02 23.81 24.04 23.82 24.04 23.80 23.85 24.04 23.76 23.94 24.08 23.71 24.02 23.74 23.95 23.92 24.00 23.83 23.98 24.01

Thanks. Arnljot

Look at the specifications of the TMP36:

  • 10mV/degree Celsius
  • +/-2 degree TYPICAL accuracy (+/-4 degree worst-case for G-grade parts)

If you are getting 0.5 degree variation that means you are getting 5mV variation in your A/D, which is pretty good for a "noisy" environment (unshielded, no special considerations for "quiet" A/D measurements, etc.) The Arduino is just not designed for super-high-precision A/D measurements. Consider that 10-bit resolution on the A/D and 5V reference means each A/D code represents 4.88mV, or 0.5 degrees Celsius. So if your A/D reads 123 and then next time reads 124, that's your 0.5 degree variation right there. And the ATmega328P A/D will definitely vary by +/-1 from reading to reading just due to internal imprecision.

If you want better precision in your readings, you will need an external A/D converter with careful attention to the whole signal path from sensor to A/D.

-- The Aussie Shield: breakout all 28 pins to quick-connect terminals

Mmm, I see. When you put it like that, it sounds logical...

Maybe I should just slow down on the reading of temps and updating of the display then. I could even increase the number of readings in my average calculations..

Thanks for your valuable input.

Below you can see why this variance is a problem in my application. The switching state (of the burner) here is initially off, an is then turned on by a freaky low reading. Remember that each reading in the list below is an average of 80 sensor readings over a period of 16 seconds. The hysteresis is 0.5 degrees, so a temperature setting of 24 degrees will cause switching when the measured temperature drops to 23.5. After switching the burner on, the measured temperature (average) increase to a higher "steady" level.

23.73 23.64 23.71 23.72 23.70 23.49 on:24.00>23.49 (thermostat setting > than average sensor reading) 23.93 24.10 23.82 24.12 24.14 24.12 24.10

Will a sensor with more accuracy have less variance? Are these parameters really the same thing? Maybe this will do: http://www.sparkfun.com/datasheets/Sensors/Temperature/tmp102.pdf

How can I solve the variance problem with software, using the current sensor? I was thinking in the terms of requiring three (or more) consecutive readings at triggering temperature before switching. In this context, a reading is an average of 80 actual sensor readings. Any other suggestions.

Also, later I plan to add an outdoor temp sensor to better regulate indoor temperature. How to I best connect an external sensor to the Arduino? I thought maybe an I2C sensor like the one linked, but then I discovered that the range of I2C is a few meters at best. Electronics and dealing with analog sensors is not my field, so any help and suggestions is greatly appreciated,

Btw. My pellet burner came with a thermostat and weekly program, but since I'm not entirely happy with the user interface and also since I've just discovered Arduino, making my own is just so much more fun. I really like the Arduino stuff and the great Arduino community, and I have a feeling that my house will be full of these little buggers soon. LOL

I use a tmp36 in a couple of locations for temperature control. I had the same problem you're having but much worse. I would see rises and falls of 2 C which caused me many problems. I solved it by reading the sensor MANY times a second, currently around 1000 doing a simple average on that, then keeping a moving average over 10 seconds to stabilize it even further. Yes, I know this is way overkill for the problem, but I'm using it to heat and cool my house so I didn't want my heat pump compressor working unnecessarily.

I used interrupts to drive the arduino and sample in the interrupt routine to get the rapid reads adding each one and keeping count. Then every second I divide the total by the number of reads and hold that in an array. The array is summed and averaged on the fly so I get a nice smooth temperature transition with enough accuracy for controlling the house temperature.

In your case a rolling average of several seconds, maybe 15 or so, should solve your problem. There is sample code for this if you search for 'moving average arduino' and look around a bit. Another trick is to toss out the occasional jump in reading that could be caused by static or something. I didn't do that, the moving average worked fine.

Great input draythomp

I tried 500 samples average, and have a much more stable temperature reading now. The idea with the rolling/moving average is good, and should smooth things out further. Thanks for the input. For my outdoor temp readings, I have found this digital sensor, with a 20 meter range and with humidity sensor included. accuracy is +-0.5 degrees wich is plenty for my application. all I need is a steady signal....

http://www.sparkfun.com/products/10167

cheers

One other thing I had a problem with that may not apply to your situation is the power. I was using the +5 as a voltage reference and when I closed a relay it dropped a tiny bit. That translated to almost 2 degrees from time to time on the temp sensor. I move the sensor to the 3V supply and the problem went away.

Have fun.

Thats useful info. I need to switch a relay as well, but it will be located some distance away from the Arduino controller, so I plan to open and close this relay with the help of an Xbee. Got the idea from here: http://www.adafruit.com/blog/2009/04/21/using-xbees-to-control-relays/

In line with what others have told you:

Work out a stable reference voltage. Arduino, really Atmel, gives you several choices.

Just as important, and often overlooked, is the return path for the ground or common of the chip. Make certain that no other currents travel on any part of the path between the ground pin of the tmp and the ground pin of the microcontroller. If the tmp is mounted somewhere remote, as on the end of a wire or cable, twist the wires and keep the bundle away from power carrying leads and away from motors. The output from the tmp will be referenced to the ground pin. If the ground pin is bouncing around relative to the ground pin on the microcontroller chip due to extraneous current in the wire or trace, it will be reflected in the output.

Accumulate 64 ad conversions into a unint16_t and shift right 6 to get a good number.

After there is a temperature value that you use, do not even check it again for a couple of minutes. Same for deciding when to turn it off. If a system like this goes into oscillation, sample less frequently.

Just a follow up on this problem. As jcarr and draythomp have pointed out, grounding and voltage variance is probably causing much of the trouble I have experienced here. Since I have other current consumers connected, I can never be sure I have a correct voltage reference. Although, I managed to average out the variance by methods described above, I decided to ditch the Tmp36 in favor of Dallas/Maxim DS18B20. This is a digital temp sensor, with on board conversion, and digital transmission. These line of products are really fun little things. They have implemented what is called a 1-wire bus, which only requires a ground line and a signal line. Voltage is supplied on the signal line, or on a separate Vcc line. This sensor is much more accurate , but I still use a ten-number rolling average to smooth things even more.

Thanks for all the input.

The 1-Wire stuff is neat but the commitment of Dallas/Maxim to the platform is questionable. For example, they took out an existing product line (the very popular counter chip) and have yet to replace it with anything. That counter chip was extremely useful for hobbyists like myself (2 channels and counting bandwidth that could be measured in kHz) and was used in every 1-wire weather station to count the precipitation. To the best of my knowledge, they have yet to bring out a replacement counter.

As for the tmp36, as suggested above, your answer may be a better power supply (i.e. 0.1uF cap across GND and 5V) as well as decimation (Google the Atmel paper on that) to boost your sensor resolution from its quasi-10 bit beginnings to something approaching 16 bits. Decimation (or oversampling) is not the same thing as averaging, and for slow moving signals it's a perfect way to make inexpensive hardware perform much better.

All that said, the 1-wire digital temperature sensors from D/M are great units because they are accurate, can operate more easily in noisy environments, and are offered in all sorts of configurations that the TMP36 is not - like in a waterproof sheath, for example.

I bought a few of these LM36/TMP36 sthese and wish I never bothered. I never got the same reading and taking an average is a pain. I then tried the Dallas DS18B20 digital temperature sensor and recommend you seriously lose the TMP36 and go for this temperature sensor and it has 9 - 12 bit accuracy so no need to calibrate for different voltages, etc. Plug it in and away you go!

when I closed a relay it dropped a tiny bit.

advice -> use separate powersupply for relay's if possible.

about moving average - http://arduino.cc/playground/Main/RunningAverage -

jcarrr: Just as important, and often overlooked, is the return path for the ground or common of the chip. Make certain that no other currents travel on any part of the path between the ground pin of the tmp and the ground pin of the microcontroller.

For me, connecting the GND of the TM36 directly to a GND pin on the arduino (instead of hopping through the breadboard) made the output of analogRead() MUCH more stable.

Thanks!

Hey there,

I know this has not been posted on for a long time but since I came here looking for an answer to the temperature variance question, I thought I would post what I found. Aseem - also first post and first project :slight_smile:

I found a simple solution to the problem somewhere online - I connected the sensor to a different ground than the other parts of the circuit were connected to. This made a huge difference in the reliability, especially when I was doing things like pushing buttons.

It makes sense when you think about it since doing things like pushing buttons must adjust the voltage on the ground for an instant.

I’ll likely investigate other smoothing techniques like http://arduino.cc/en/Tutorial/Smoothing and adding a capacitor but since this made such a difference, I thought it was worth mentioning (and I wanted to stick up for the tmp36 :slight_smile: )

The TMP36 needs a load resistor. 47k from Vout to GND and it will be transformed into a reliable and (fairly) accurate sensor. http://www.doctormonk.com/2015/02/accurate-and-reliable-readings-from.html