The Physics of Resistive Sensoren
When sourcing variable resistive components—often listed in international catalogs and datasheets as resistive sensoren—you are dealing with devices that change their internal electrical resistance in response to a physical stimulus. Depending on the specific module, this stimulus could be mechanical force (Force Sensitive Resistors), physical deformation (Flex sensors), incident light (Photoresistors/LDRs), or soil moisture. Because microcontrollers cannot measure resistance directly, we must pass a known current through the component to generate a measurable voltage drop.
This is universally achieved using a voltage divider circuit. By placing a fixed reference resistor in series with the variable sensor, the changing resistance alters the ratio of the voltage drop across the two components. The microcontroller's Analog-to-Digital Converter (ADC) reads this midpoint voltage, allowing us to reverse-engineer the physical stimulus using basic Ohm's Law and the known characteristics of the fixed resistor.
ESP32 Wiring and Supply Specifications
The ESP32 features two ADC units, but ADC2 shares hardware with the WiFi radio. If your project uses WiFi (which most do), you must use ADC1. Furthermore, the ESP32 operates at 3.3V logic; feeding a 5V voltage divider directly into a GPIO pin will permanently damage the silicon. Below is the exact wiring specification for a standard 3.3V setup using an analog input pin.
| Component / Pin | ESP32 Connection | Supply Range | Engineering Notes |
|---|---|---|---|
| Sensor Terminal 1 | 3V3 Pin (or external 3.3V LDO) | 3.2V - 3.4V DC | Use a dedicated LDO if the ESP32 3V3 rail is noisy from WiFi spikes. |
| Sensor Terminal 2 | ADC Midpoint (Junction) | 0V - 3.3V | This is the analog signal wire. Keep it under 5cm to avoid EMI. |
| Fixed Resistor (e.g., 10kΩ) | Midpoint to GND | N/A | Use a 1% metal film resistor. 5% carbon resistors introduce thermal drift. |
| ESP32 ADC Pin | GPIO 34 (ADC1_CH6) | 0V - 3.3V Max | GPIO 34, 35, 36, 39 are input-only and lack internal pull-ups, making them ideal for external dividers. |
| Filter Capacitor | Midpoint to GND | N/A | 100nF X7R Ceramic. Forms a low-pass filter to kill high-frequency RF noise. |
The Math: Raw ADC to Physical Units
The output of a resistive sensor circuit is an analog voltage between 0V and 3.3V. The ESP32's 12-bit ADC maps this to a raw digital integer between 0 and 4095. However, the ESP32's raw ADC readings are notoriously non-linear, particularly above 2.8V. To get accurate physical units, you must bypass analogRead() and use the factory-calibrated analogReadMilliVolts() function available in modern ESP32 Arduino cores.
Here is the mathematical progression from raw voltage to sensor resistance, using a Force Sensitive Resistor (FSR) as our working example. In this topology, the FSR is connected to VCC, and the fixed 10kΩ resistor is connected to GND.
Step 1: Calculate Sensor Resistance
Using the voltage divider formula inverted for the top-resistor:
R_sensor = R_fixed * ((V_cc / V_out) - 1)
Step 2: Convert Resistance to Physical Unit (Force)
For an Interlink FSR402, the conductance (1/R) is roughly linear with force. A practical bench approximation for force in Newtons is:
Force (N) ≈ (1 / R_sensor) * 100 (Note: This is a simplified linear fit; high-precision applications require the specific polynomial curve from the SparkFun FSR Integration Guide).
// ESP32 Arduino Core v2.x+ required for analogReadMilliVolts
const int SENSOR_PIN = 34;
const float V_CC = 3300.0; // 3.3V in millivolts
const float R_FIXED = 10000.0; // 10k ohm fixed resistor
void setup() {
Serial.begin(115200);
analogReadResolution(12); // Explicitly set 12-bit resolution
}
void loop() {
// Read factory-calibrated millivolts (bypasses raw ADC non-linearity)
int v_out_mv = analogReadMilliVolts(SENSOR_PIN);
if (v_out_mv <= 10) {
// Prevent division by zero when sensor is completely unloaded (infinite resistance)
Serial.println("Force: 0.00 N (Unloaded)");
} else {
float r_sensor = R_FIXED * ((V_CC / v_out_mv) - 1.0);
float force_newtons = (1.0 / r_sensor) * 100.0; // Simplified FSR402 fit
Serial.print("Resistance: "); Serial.print(r_sensor); Serial.println(" ohms");
Serial.print("Estimated Force: "); Serial.print(force_newtons); Serial.println(" N");
}
delay(100);
}
Signal Integrity, Calibration, and Interference
Resistive sensor circuits are high-impedance by nature, making them prime targets for environmental interference. If your serial monitor shows jittery readings, you are likely falling victim to one of three common issues:
- Electromagnetic Interference (EMI): Long jumper wires act as antennas, picking up 50/60Hz mains hum and switching noise from nearby DC-DC converters. Fix: Keep the wire from the voltage divider midpoint to the ESP32 GPIO under 5cm. Solder a 100nF ceramic capacitor directly across the ADC pin and GND to create a hardware low-pass filter.
- ADC Saturation and Non-Linearity: The ESP32 ADC physically saturates around 3.1V (depending on the chip batch and 11dB attenuation setting). If your sensor's maximum resistance pushes the midpoint voltage above 2.8V, your readings will compress and lose resolution. Fix: Lower the value of your fixed pull-down resistor to shift the operating curve downward, keeping the maximum expected voltage under 2.5V.
- Thermal Drift of the Fixed Resistor: If you use a standard 5% carbon composition resistor, its value will drift as the ambient temperature changes, introducing false readings. Fix: Always use 1% or 0.1% metal film resistors for the reference leg of the divider.
For software calibration, rely on the Espressif ADC Calibration API. The analogReadMilliVolts() function reads the eFuse calibration data burned into the silicon at the factory, automatically correcting the raw ADC curve into true millivolts. For applications demanding laboratory-grade accuracy, implement a two-point software calibration using known physical weights or light sources to map the specific polynomial curve of your exact sensor batch.
Decision Matrix: Selecting Your Sensor and Pull-Resistor
Choosing the right fixed resistor value is just as critical as choosing the sensor itself. The fixed resistor should ideally match the sensor's resistance at the midpoint of your target measurement range to maximize ADC resolution. Use the decision table below to finalize your bill of materials.
| Application Scenario | Sensor Type | Target Range | Optimal Fixed Resistor |
|---|---|---|---|
| Bumper / Collision Detection | Force Sensitive Resistor (FSR) | 100g - 10kg | 10kΩ (Midpoint of FSR curve) |
| Daylight / Night Tracking | CdS Photoresistor (LDR) | 10 Lux - 1000 Lux | 5kΩ to 10kΩ (Depends on LDR dark/light specs) |
| Wearable Joint Articulation | 2.2" Flex Sensor | 0° to 90° Bend | 22kΩ to 47kΩ (Flex sensors have high base resistance) |
| Potted Plant Soil Moisture | Resistive Soil Probe | Dry to Saturated | 10kΩ (Must use AC excitation to prevent galvanic corrosion) |
If you are building a general-purpose force or pressure interface and need a definitive starting point, purchase the Interlink Electronics FSR402. Pair it with a 10kΩ 1% metal film resistor and a 100nF X7R MLCC capacitor wired directly at ESP32 GPIO 34. This combination provides the widest usable voltage swing within the ESP32's linear ADC range (0.1V to 2.5V) without requiring complex operational amplifier buffering circuits.






