If you need to measure ambient temperature on a budget, the most reliable analog temp sensor circuit for 3.3V microcontrollers uses the Microchip MCP9700A. Unlike digital sensors that require I2C or 1-Wire libraries, this analog IC outputs a direct voltage proportional to temperature. To get accurate readings on an ESP32 or Arduino, you must wire it with a 0.1µF bypass capacitor, account for the microcontroller's ADC reference voltage, and apply the correct linear scaling math. Below is the exact bench-tested procedure to build, wire, and calibrate this circuit.

The Silicon Bandgap Sensing Principle

Silicon bandgap temperature sensors like the MCP9700A and TMP36 rely on the predictable temperature coefficient of a bipolar transistor's base-emitter voltage ($V_{BE}$). By running two identical on-chip transistors at different current densities, the sensor generates a delta voltage that is strictly Proportional To Absolute Temperature (PTAT). This physical property of silicon is highly repeatable and forms the foundation of the measurement.

The IC's internal op-amps amplify this PTAT voltage and add a precise DC offset, resulting in a linear, factory-calibrated voltage output. For the MCP9700A, the output scales at exactly 10mV per degree Celsius with a 500mV offset at 0°C. Because the sensing element and the signal conditioning are integrated into a single TO-92 or SOT-23 package, you avoid the complex linearization math required when building a temp sensor circuit with discrete NTC thermistors.

Wiring the Analog Temp Sensor Circuit

The physical wiring is straightforward, but omitting the bypass capacitor is the number one cause of jittery readings on the workbench. The ESP32's ADC is notoriously sensitive to power rail noise, and the sensor's output impedance can couple with stray capacitance to create oscillations.

Bench Tip: Always place the 0.1µF (100nF) ceramic capacitor as physically close to the sensor's VCC and GND pins as possible. If you are using a breadboard, straddle the capacitor directly across the sensor legs.
MCP9700A Analog Temp Sensor Pinout and Specifications
Pin Name Function ESP32 / 3.3V Connection Arduino Uno / 5V Connection
1 (VDD) Power Supply 3.3V Pin 5V Pin
2 (VOUT) Analog Output GPIO 34 (ADC1_CH6) A0
3 (GND) Ground GND GND

Supply Range: The MCP9700A operates from 2.3V to 5.5V. The TMP36 requires 2.7V to 5.5V. Never power these directly from an ESP32 GPIO pin; the sensor draws up to 6µA in active mode, which is fine for GPIO, but GPIO voltage sag under varying loads will ruin your ADC reference baseline. Always tie VDD to the dedicated 3.3V regulator output.

Output Signal Math and ESP32 Calibration

The output of this temp sensor circuit is an analog voltage, not a digital data stream. To convert the microcontroller's raw ADC reading into physical units (Celsius), you must reverse-engineer the ADC's quantization process.

The Raw-to-Unit Math:
1. The MCP9700A outputs $V_{out} = 0.5V + (10mV \times T_{celsius})$.
2. Rearranging for temperature: $T_{celsius} = \frac{V_{out} - 0.5}{0.01}$.
3. If your ADC reference ($V_{ref}$) is 3.3V and it is 12-bit (4096 steps), each step is $\frac{3.3}{4095} \approx 0.805mV$.
4. Therefore, $V_{out} = \frac{ADC_{raw} \times 3.3}{4095}$.

However, the ESP32's internal ADC is highly non-linear and its actual $V_{ref}$ varies per chip due to manufacturing tolerances. Espressif solved this by burning a calibration value into the chip's eFuse during production. Instead of doing manual floating-point math with a hardcoded 3.3V assumption, use the analogReadMilliVolts() function in the Arduino core (v2.0.0+), which automatically applies the eFuse calibration and returns a highly accurate millivolt reading.

// ESP32 Arduino Core Code for MCP9700A
const int TEMP_PIN = 34; // ADC1 pin, safe to use alongside WiFi

void setup() {
  Serial.begin(115200);
  analogReadResolution(12); // Ensure 12-bit resolution (0-4095)
}

void loop() {
  // Read calibrated millivolts directly from ESP32 eFuse data
  uint32_t vOut_mV = analogReadMilliVolts(TEMP_PIN);
  
  // Apply MCP9700A transfer function: T = (Vout - 500mV) / 10mV
  float tempC = (vOut_mV - 500.0) / 10.0;
  float tempF = (tempC * 9.0 / 5.0) + 32.0;
  
  Serial.print('Temp: ');
  Serial.print(tempC);
  Serial.print(' C  |  ');
  Serial.print(tempF);
  Serial.println(' F');
  
  delay(1000);
}

For the standard 5V Arduino Uno, analogReadMilliVolts() is not natively calibrated. You must use the standard analogRead() and multiply by 5000.0 / 1023.0 to get millivolts, assuming your USB supply is exactly 5.000V (which it rarely is; measure your 5V pin with a multimeter and update the constant accordingly).

Analog vs Digital: Managing Interference

A common mistake in embedded design is conflating analog voltage outputs with digital protocols like I2C or 1-Wire. They suffer from entirely different interference modes. Because the MCP9700A outputs a continuous voltage, it is highly susceptible to Electromagnetic Interference (EMI) and ground loops.

Common Interference Sources:

  • Long Wire Capacitance: If the wires between the sensor and the microcontroller exceed 1 meter, the cable capacitance forms a low-pass filter with the sensor's output impedance, and acts as an antenna for 50/60Hz mains hum.
  • WiFi/Bluetooth RF Noise: On the ESP32, transmitting WiFi bursts causes momentary voltage sag on the 3.3V rail. Without the 0.1µF bypass cap, this sag is read by the ADC as a sudden temperature drop.
  • High-Impedance ADC Sampling: The ESP32 ADC has an internal sampling capacitor. If the source impedance is too high, the capacitor won't fully charge during the sampling window, resulting in consistently low readings.

The 1-Meter Rule: If your temp sensor circuit requires wires longer than 1 meter (3 feet), abandon the analog sensor. Switch to a digital DS18B20 1-Wire sensor. Digital signals are immune to the voltage drops and EMI noise that will completely destroy the accuracy of an analog voltage reading over long distances.

Temp Sensor Circuit FAQ

Why is my analog temp sensor circuit reading fluctuating randomly?

Fluctuations are almost always caused by noise on the power rail coupling into the ADC. First, verify you have a 0.1µF ceramic capacitor placed directly across the VCC and GND pins of the sensor. Second, if you are using an ESP32, ensure you are using an ADC1 pin (GPIO 32-39). ADC2 pins share hardware with the WiFi radio and will return garbage data or dropouts when WiFi is active. Finally, average 16 to 32 samples in software to smooth out high-frequency thermal and electrical noise.

Can I power a 3-pin temp sensor circuit directly from an ESP32 GPIO?

Technically yes, as the MCP9700A draws only 6µA, which is well within the 40mA limit of an ESP32 GPIO. However, you should not do this for precision measurements. Driving the sensor from a GPIO means the sensor's VCC reference is tied to the GPIO's internal resistance and the microcontroller's dynamic load. When the ESP32 transmits data, the internal voltage drops slightly, shifting your sensor's baseline. Always power the sensor from the dedicated 3.3V or 5V regulator pins.

Do I need a pull-up resistor for an analog temp sensor circuit?

No. Pull-up resistors are required for open-drain digital protocols like I2C (used by the BME280) or 1-Wire (used by the DS18B20). The MCP9700A and TMP36 use a push-pull analog output stage that actively drives the voltage high and low. Adding a pull-up or pull-down resistor to the VOUT pin will create a voltage divider with the sensor's internal output impedance, skewing your temperature reading by several degrees. Leave the VOUT pin connected directly to the microcontroller's ADC input.