About the TMP36 Sensor
The TMP36 is the reference analogue temperature sensor in the Arduino world. It is affordable, small et power efficient. For sure there are better temperature sensors but this one will do the job for almost nothing :-)
This sensor is very common and easy to use. It is also one of the components of the ARDX development kit.
With the TMP36, it is possible to measure a temperature from -50°C to 125°C, the output voltage is proportional to the temperature.
Don't be fooled, the TMP36 looks like a transistor (eg: P2N2222AG) but it isn't a transistor. It is a complex sensor within a package identical to a transistor.
There are 3 pins on the TMP36.
- the ground (on the left),
- the output signal (center position),
- the +5 volts (on the right)
The sensor output signal does output 10 millivolts per degree (with 500mV offset for temperature under 0°C).
- 25° C --> output = 750 mV
- 0° C --> output = 500mV
- Analog output (see graphics)
- Temperature range: from -50°C to 125°C
- Power supply range: 2.7 to 5.5v
- TMP36 datasheet (analog.com, html)
How to measure the temperature
It will be necessary to convert the analogue voltage intro degree. As the TMP36 can also measure negative temperature, the 0 degree Celcius is placed at 500 mV offset. So, any voltage under 0.5 Volt is a negative temperature.
Here is the formula to use with a TMP36 powered at 3.3v:
Temp in °C = ( output_voltage_in_mV - 500) / 10
So, if we do have an output voltage of exactly 1 Volt (1000 mV) then the temperature would be
temp = (1000 - 500)/10
So 50 Celcius degrees.
To use the TMP36, connect:
- The pin 1 (on the left) to a power source (3.3V),
- The pin 3 (the the right droite) to the ground/GND.
- The pin 2 (middle one) to the ADC0 analog input.
The TMP36 output voltage would range from 0V @ -50°C to 1.75V @ 125°C. So no risk for our 3V based microcontroler.
Testing the sensor
The Raspberry-Pico offers a 12 bits resolution ADC (effective 0.8mV resolution. 3.3V/4095).
| The MicroPython ADC expose an unified reading method named read_u16() returning a 16 bits integer (between 0 and 65535).
So the 12 bits value readed on the ADC hardware is upscaled to 16 bits by read_u16(). However upscaling will do not increase the ADC resolution (which stays anyway to 8mV).
# Read the TMP36 analog temperature sensor # sensor wired to ADC0 (GP26) # from machine import ADC, Pin import time adc = ADC(Pin(26)) while True: value = adc.read_u16() mv = 3300.0 * value / 65535 temp = (mv-500)/10 print( 'Temp: %5.2f °C, Voltage: %4i mV' % (temp,mv) ) time.sleep( 0.100 )
Which produce the following results into the MicroPython REPL/Shell
Temp: 15.19 °C, Voltage: 651 mV Temp: 14.87 °C, Voltage: 648 mV Temp: 14.71 °C, Voltage: 647 mV
Improving the circuit
You may notice some variation in the temperature reading. This is due to the DC/DC regulation using running at lower frequency (to spare power when really few current required by the project). At lower frequency, the voltage regulation is less efficient and 3V3 rail will be more noisy.
As the TMP36 only requires 50µA and RP2040 consume very few current, you may encounter this situation.
The following scope capture show the 3V3 rail at very low current. As shown, je 3V3 contains lot of noise (Saw Waveform).
As the analog sensors are very sensitive to unstable power voltage. Variation and noise on power rail may cause important variation on analog output of an analog sensor.
By adding the 2200µF capacitor, the noisy saw waveform will be changed and adding the 10nF will greatly reduce the noise opn the PowerRail.
Improving the code
A good way to improve stability in the readings is to preform a means calculation over several reading.
# Mean read the TMP36 analog temperature # sensor wired to ADC0 (GP26) # from machine import ADC, Pin import time adc = ADC(Pin(26)) while True: value = 0 for i in range(10): value += adc.read_u16() value /= 10 mv = 3300.0 * value / 65535 temp = (mv-500)/10 print( 'Temp: %5.2f °C, Voltage: %4i mV' % (temp,mv) ) time.sleep(0.100 )
Written by Meurisse D. for MCHobby