# Arduino TMP36 not enough resolution -- how to improve

I have connected a TMP36 to an Arduino Uno, and eventually figured that the 10-bit resolution allows for the smallest step to be 4.8mV. Using the proper conversion results in half degree temperature steps. Since the TMP36 changes 10mV per degree this makes sense. However, this is simply not good enough for a smooth transition in the first decimal digit. What do I need to do to:

1. spread -- say -- -10 to 40 deg C over the 1024 steps, or
2. increase the bits in the A/D converter, or
3. use an extra/external A/d with higher resolution,

... to achieve a higher resolution?

What I figured is that in other posts, resolution is mistaken for accuracy. I am after a higher resolution; e.g. 4096 steps would be close to 1mV steps. I reckon even more is required for smooth transitions.

Any help appreciated... as I am sort of to new to this.

• What is the temperature range you need, having 0.1 degree resolution, for example? Negative values? Commented Jul 13, 2014 at 17:25
• @DirceuRodriguesJr: -10 to 40 deg C
– MaxG
Commented Jul 13, 2014 at 21:40

You can increase resolution by using the internal 1.1V analog voltage reference instead of the default 5V one. You can do that with the following code:

analogReference(INTERNAL);


That will let you spread the temperature reading over a smaller range and will yield approximately 1.075mV resolution per unit from your analogRead() calls.

Here's more information about the analogReference() function call: AnalogReference.

• @MaxG: And if you need the range, you can detect when you are reaching the upper limit while using the internal reference and then switch to the external reference.
– Evan
Commented Jul 13, 2014 at 14:26
• @EvangelosEm: it looks like I have lots to learn :) I have to try this again (changing the Aref voltage), and more so understand why this actually works. I read about it, but thought 1024 steps are 1024 steps -- just with a different voltage. But dividing 1.1V by 1024 results in steps of 1.07mV -- close to what I would require.
– MaxG
Commented Jul 13, 2014 at 21:44
• And now I remember my reasoning why changing the voltage makes no sense (to me). It is still 1024 steps. The sensor requires 2.7 to 5.5V. So I ca't feed it 1.1V. The range is from -40 to +125 degC, which spans over 165 degrees. At .1 Deg resolution, I would need 1,650 distinct values, but have only 1024. Hence, why I think I need to increase the A/Ds bit = more bits for a higher resolution. (But then I am a layman, and may not be on the right track.)
– MaxG
Commented Jul 13, 2014 at 22:37
• Also, it looks like you're confusing the input supply voltage that the sensor needs (2.7 to 5.5V) with the voltage that it will output to indicate its temperature reading. You should feed its Vin pin with 5V (voltage supply), for example, and then wire its output to an Arduino analog input. Then, if you change the analog reference like I suggested, you'll get a reading from 0 to 1023 for a sensor output of 0 to 1.1V. Everything above 1.1V will read as 1023 to the Ardunino (with 1.1V reference). Commented Jul 13, 2014 at 22:52
• Almost. It's actually easier than what you described. The ATmega328P has an internal 1.1V AREF that you can use for free. You don't have to wire anything to AREF. Just call analogReference(INTERNAL) and you're good to go. The rest of your comment is correct. Good luck! If you have more questions, we're here to answer them. Commented Jul 13, 2014 at 23:58

One technique to achieve higher resolution is over sampling. Here is an application note from Atmel with more details for this technique

• This makes sense (to my present logic and understanding). I will have a read. I also thought of using a 16-bit A/D to get my decimal resolution. -- Thanks for the responses.
– MaxG
Commented Jul 13, 2014 at 22:40
• Interesting technique. +1 Commented Jul 14, 2014 at 0:16

My solution: Reach a resolution truly equal or better than $0.1^{\circ}C/LSB$, by using an amplifier in between the TMP36 and microcontroller ADC (also with $V_{REF}=1.1V$). The idea is to change the sensor transfer function, but sacrificing the original temperature range, from$-40^{\circ}C/+125^{\circ}C$ to $-10^{\circ}C/+40^{\circ}C$ (according you said). Let:

$V_A$: Analog voltage from TMP36, with $V_A=0.01T + 0.5$ (where $T$ is the temperature)

$V_A'$: amplified $V_A$

$V_D$: Digital value converted by ADC, $V_D=INT(\frac{1024}{1.1}V_A')$

Doing the math, the required equation for that tranformation is: $$V_A'=2V_A-0.7$$ Notice that $0.4V\leq V_A< 0.9V$

A possible circuit (w/ rail-to-rail input op. amp):

So, the expression for the temperature (to be implemented on microcontroller code) is: $$T=0.05371V_D-15$$

Using differences: $$\Delta T=0.05371\Delta V_D$$ or $$\Delta T< 0.1\Delta V_D$$ The smaller change in $V_D$ is 1 bit on ADC ($\Delta V_D \Leftrightarrow 1 LSB$). In other words, a resolution better than $0.1^{\circ}C/LSB$. Not accounting for the implementation issues (rounding, fixed point, ...).