To wire a TMP36 analog temperature sensor to an ESP32, connect the VCC pin to the 3.3V rail, GND to GND, and the VOUT pin to GPIO 34 (or any ADC1 channel). Do not use ADC2 pins (like GPIO 25 or 26), as they are disabled when the ESP32's WiFi radio is active. To get an accurate reading, use the analogReadMilliVolts() function in the ESP32 Arduino Core to bypass the chip's notorious ADC non-linearity, then apply the TMP36 offset math: Temp_C = (mV - 500) / 10.
The TMP36: How This Simple Sensor Actually Works
The TMP36 is a precision centigrade temperature sensor whose output voltage is linearly proportional to the Celsius temperature. Unlike thermistors that require complex Steinhart-Hart equations and external pull-up resistors, this simple sensor integrates the transducer and signal conditioning on a single silicon die. It outputs an analog voltage that scales at exactly 10 mV per degree Celsius, with a 500 mV DC offset.
Internally, the chip relies on the predictable voltage drop across a forward-biased silicon PN junction. As temperature increases, the bandgap voltage shifts at a highly predictable rate. The onboard circuitry amplifies this shift and offsets it so the output reads 500 mV at 0°C. This 500 mV offset is the critical design choice: it allows the sensor to measure sub-zero temperatures (down to -40°C, outputting 100 mV) without requiring a negative supply rail, making it perfect for single-supply 3.3V microcontrollers.
Hardware Specs and ESP32 Pin Mapping
Before soldering, it is vital to understand how this analog component stacks up against digital alternatives, and exactly which ESP32 pins can safely read its output. The ESP32 has two ADC units, but only ADC1 is guaranteed to work while WiFi or Bluetooth is transmitting.
| Sensor Model | Output Type | Supply Range | Scale Factor | Typical Accuracy | Approx. Cost |
|---|---|---|---|---|---|
| TMP36 | Analog Voltage | 2.7V to 5.5V | 10 mV / °C | ±1°C (at 25°C) | $1.60 |
| LM35 | Analog Voltage | 4.0V to 30V | 10 mV / °C | ±0.5°C (at 25°C) | $2.10 |
| DS18B20 | Digital (1-Wire) | 3.0V to 5.5V | N/A (Digital) | ±0.5°C (-10 to +85°C) | $3.50 |
| DHT22 | Digital (Custom) | 3.3V to 5.5V | N/A (Digital) | ±0.5°C | $4.00 |
ESP32 DevKit V1 Wiring Pinout
The physical output of the TMP36 is an analog voltage. The ESP32 reads this via its internal Successive Approximation Register (SAR) ADC. You must route the signal to an ADC1 pin.
| TMP36 Pin (Flat face up) | Function | ESP32 DevKit Pin | Notes & Constraints |
|---|---|---|---|
| 1 (Left) | VCC (Supply) | 3V3 | Do not use 5V/VIN; it will push VOUT above the ESP32's 3.3V ADC max, risking silicon damage. |
| 2 (Middle) | VOUT (Signal) | GPIO 34 (ADC1_CH6) | GPIO 32, 33, 35, 36, 39 are also valid ADC1 pins. Never use ADC2 pins (e.g., GPIO 25, 26, 27). |
| 3 (Right) | GND | GND | Ensure a solid common ground; ground loops will introduce 50/60Hz hum into the reading. |
Converting Raw ADC Counts to Celsius
The most common mistake hobbyists make with analog sensors on the ESP32 is using the legacy Arduino analogRead() function and multiplying by 3.3/4095. The ESP32's ADC is notoriously non-linear, particularly at the top and bottom of the voltage range. Furthermore, the default attenuation is 0dB, meaning it clips at roughly 1.1V—completely missing the TMP36's output above 60°C.
The Raw-to-Unit Math
Assuming you configure the ADC for 11dB attenuation (which extends the readable range to ~3.1V), the physical math dictated by the Analog Devices TMP36 Datasheet is:
- Voltage (mV): Derived from the calibrated ADC reading.
- Offset Removal: Subtract 500 mV (the 0°C baseline).
- Scaling: Divide by 10 (since the scale factor is 10 mV/°C).
Formula: Temperature (°C) = (Voltage_mV - 500) / 10
Production-Ready ESP32 Code
The code below utilizes analogReadMilliVolts(), a function introduced in ESP32 Arduino Core v2.x. This function reads the raw ADC value and automatically applies the factory-programmed eFuse calibration data stored on your specific ESP32 silicon, drastically reducing non-linearity errors without requiring manual lookup tables.
#include <Arduino.h>
// GPIO 34 is an ADC1 pin, safe to use with WiFi active
const int TMP36_PIN = 34;
// Number of samples to average out ESP32 ADC thermal noise
const int SAMPLE_COUNT = 64;
void setup() {
Serial.begin(115200);
delay(1000);
// Set 11dB attenuation to read voltages up to ~3.1V
// Required for TMP36 to measure temperatures above 60°C
analogSetPinAttenuation(TMP36_PIN, ADC_11db);
Serial.println('TMP36 ESP32 Interfacing Initialized');
}
void loop() {
long sum_mV = 0;
// Oversampling: The ESP32 ADC has inherent noise.
// Taking 64 rapid samples and averaging yields a much cleaner signal.
for (int i = 0; i < SAMPLE_COUNT; i++) {
// analogReadMilliVolts uses eFuse factory calibration
sum_mV += analogReadMilliVolts(TMP36_PIN);
delayMicroseconds(250); // Allow ADC sampling cap to settle
}
float avg_voltage_mV = (float)sum_mV / SAMPLE_COUNT;
// Apply TMP36 transfer function
float tempC = (avg_voltage_mV - 500.0) / 10.0;
float tempF = (tempC * 9.0 / 5.0) + 32.0;
Serial.printf('Avg mV: %.1f | Temp: %.2f C | %.2f F\n',
avg_voltage_mV, tempC, tempF);
delay(1000);
}
Real-World Interference and Calibration Fixes
Even with factory eFuse calibration, a simple sensor like the TMP36 can yield jittery readings on the bench. The output is an analog voltage, which means it is highly susceptible to environmental electrical noise. If your serial monitor shows the temperature bouncing by ±2°C, you are experiencing interference, not a broken sensor.
Common Interference Sources
- WiFi RF Noise: The ESP32 draws spikes of current (up to 500mA) during WiFi transmission. If your 3.3V rail sags even 50mV during a transmit burst, the TMP36's VCC drops, and the VOUT reading follows it down, registering as a sudden temperature drop.
- ADC Sampling Capacitor Droop: The ESP32's internal ADC uses a ~10pF sampling capacitor that connects to the input pin during the read window. If your wire run from the TMP36 to the ESP32 is longer than 6 inches, the wire inductance prevents charge from replenishing fast enough, causing the voltage to droop during the read.
- 60Hz Mains Hum: Long, unshielded analog wires act as antennas, picking up electromagnetic interference from nearby AC mains wiring.
Hardware Fixes for Clean Data
Software oversampling (as shown in the code above) masks noise, but hardware fixes eliminate it at the source. Implement these two physical modifications for production-grade stability:
- The Bypass Capacitor (Mandatory): Solder a 100nF (0.1µF) ceramic capacitor directly across the VCC and GND pins of the TMP36, as close to the sensor body as possible. This provides a local reservoir of charge to handle the ESP32's ADC sampling droop and high-frequency RF noise.
- The RC Low-Pass Filter (For Long Wires): If your sensor is mounted more than 12 inches from the microcontroller, add a simple RC filter at the ESP32 GPIO pin. Place a 10kΩ resistor in series with the VOUT wire, and a 1µF ceramic capacitor from the GPIO pin to GND. This creates a hardware low-pass filter with a cutoff frequency of roughly 15Hz, entirely eliminating 60Hz mains hum and WiFi switching noise before it reaches the ADC.
For deeper exploration of the ESP32's analog subsystem, including how to implement continuous DMA-based ADC reads for high-speed sensor arrays, refer to the official Espressif ADC Oneshot Driver Documentation. By respecting the analog nature of the TMP36 and the specific quirks of the ESP32's ADC1 hardware, you can extract lab-grade temperature data from a $1.60 component.






