A flex sensor is fundamentally a variable resistor (potentiometer) whose resistance increases as it is bent. Because microcontrollers cannot read resistance directly, you must use a voltage divider circuit to convert the changing resistance into an analog voltage (typically 0V to 3.3V), which the MCU’s Analog-to-Digital Converter (ADC) then translates into a raw digital number. For standard carbon-polymer flex sensors, flat resistance sits around 10kΩ, rising to roughly 35kΩ–40kΩ at a 90° bend.
The Sensing Principle: How Carbon-Polymer Flex Sensors Work
Standard unidirectional flex sensors consist of a carbon-impregnated polymer layer sandwiched between flexible substrate sheets (usually Kapton or PET). When the sensor is flat, the carbon particles are densely packed, providing a low-resistance conductive path. As the sensor bends, the outer radius of the polymer matrix stretches, forcing the carbon particles further apart. This physical separation restricts electron flow, resulting in a predictable, roughly linear increase in electrical resistance proportional to the bend angle.
It is critical to note that these sensors are strictly unidirectional. Bending them along their primary axis increases resistance, but bending them backward (against the substrate grain) yields erratic, non-linear readings and can permanently crack the carbon matrix. If your mechanical design requires measuring deflection in both directions (e.g., a bidirectional hinge), you must use a specialized bidirectional flex sensor or mount two standard sensors back-to-back.
Wiring and Signal Conditioning: Turning Resistance into Voltage
Flex sensors do not have a "supply voltage" in the way an active IC does; they are passive resistive elements. However, the voltage divider circuit you build around them requires a stable reference voltage. The output signal is an analog DC voltage that scales inversely with the bend angle (more bend = higher resistance = lower output voltage, assuming a pull-down configuration).
Standard Wiring Pinout (ESP32 / Arduino)
| Component Node | ESP32 DevKit Pin | Arduino Uno Pin | Notes & Supply Range |
|---|---|---|---|
| VCC (Voltage Divider Top) | 3V3 | 5V | Supply range: 3.3V to 5.0V DC. Keep it clean; use a decoupling capacitor if on a noisy rail. |
| VOUT (Divider Midpoint) | GPIO 34 (ADC1_CH6) | A0 | Analog output. Do not use ADC2 pins on ESP32 if WiFi is active. |
| GND (Pull-down Bottom) | GND | GND | Common ground reference for the MCU and sensor. |
The Raw-to-Unit Math: Calculating Bend Angle from ADC Reads
The most common mistake makers make with flex sensors is using a 10kΩ pull-down resistor. While this works for 5V Arduinos, it pushes the ESP32’s 3.3V ADC into its non-linear saturation zones. The ESP32 ADC is notoriously inaccurate below 0.2V and above 3.1V. To maximize resolution, we use a 47kΩ pull-down resistor. This shifts our voltage swing into the ESP32's linear sweet spot.
The Voltage Divider Equation
With the flex sensor ($R_{flex}$) on top and the fixed resistor ($R_{fixed}$) on the bottom to ground, the output voltage ($V_{out}$) is calculated as:
V_out = V_cc × [ R_fixed / (R_flex + R_fixed) ]
- Flat (0°): $R_{flex}$ ≈ 10,000Ω. $V_{out} = 3.3 × [47,000 / (10,000 + 47,000)] = 2.71V
- Bent (90°): $R_{flex}$ ≈ 35,000Ω. $V_{out} = 3.3 × [47,000 / (35,000 + 47,000)] = 1.89V
This gives us a clean 0.82V swing (approx. 25% of the ADC range) sitting perfectly in the middle of the ESP32’s linear response curve. For a deeper look at the underlying circuit theory, reference the SparkFun Flex Sensor Hookup Guide.
ESP32 Arduino Calibration Code
Because carbon-polymer sensors vary by ±20% from the factory, you must perform a two-point calibration. The code below maps the raw 12-bit ADC reading (0-4095) to a physical angle (0-90°) using calibrated thresholds.
// Flex Sensor Calibration for ESP32 (12-bit ADC)
// Hardware: 2.2" Flex Sensor + 47kΩ pull-down resistor
const int FLEX_PIN = 34;
// Calibrated ADC values for YOUR specific sensor (measure these first!)
const int ADC_FLAT = 3360; // ADC reading at 0 degrees (approx 2.71V)
const int ADC_BENT = 2345; // ADC reading at 90 degrees (approx 1.89V)
void setup() {
Serial.begin(115200);
analogReadResolution(12); // Ensure 12-bit resolution (0-4095)
}
void loop() {
// Read raw ADC and apply a simple software low-pass filter
int rawADC = analogRead(FLEX_PIN);
// Map raw ADC to degrees. Note: ADC_FLAT > ADC_BENT, so map handles inversion
float angle = map(rawADC, ADC_FLAT, ADC_BENT, 0, 90);
// Constrain to physical limits to prevent negative angles or >90 errors
angle = constrain(angle, 0.0, 90.0);
Serial.print("Raw ADC: ");
Serial.print(rawADC);
Serial.print(" | Angle: ");
Serial.println(angle);
delay(50);
}
Interference, Hysteresis, and Signal Noise
Flex sensors are highly susceptible to environmental and mechanical interference. Understanding these failure modes is required to write robust firmware.
- Mechanical Creep (Hysteresis): If you hold a flex sensor at 90° for 60 seconds, the resistance will slowly drift upward. When you release it, it will not immediately return to the baseline 10kΩ; it requires a few seconds to "relax." Fix: Implement a dynamic baseline calibration in software that resets the 0° point when the system is idle.
- Temperature Drift: The carbon-polymer matrix has a negative temperature coefficient (NTC). As ambient or skin temperature rises, baseline resistance drops. If your wearable glove heats up during use, your 0° calibration point will shift.
- Electromagnetic Interference (EMI): Flex sensors output high-impedance analog signals. Running unshielded wires longer than 6 inches near stepper motors or WiFi antennas will inject severe high-frequency noise. Fix: Keep wire runs under 4 inches, use twisted-pair wire, or place a 0.1µF ceramic capacitor in parallel with the $R_{fixed}$ pull-down resistor to create a hardware low-pass filter.
Decision Tree: Choosing the Right Flex Sensor for Your Build
Do not waste time guessing which form factor to buy. Use this decision matrix to select the exact part number based on your mechanical constraints.
| Application Scenario | Joint Radius / Bend Area | Required Sensor Type | Concrete Part Recommendation |
|---|---|---|---|
| Finger tracking (Glove) | < 1.5 inches | Standard Unidirectional | Spectra Symbol 2.2" (FS-A) |
| Wrist / Elbow / Knee tracking | > 2.5 inches | Long Unidirectional | Spectra Symbol 4.5" (FS-L) |
| Biomechanical hinge (both ways) | Any | Bidirectional | Flexpoint Bidirectional (54-764) |
| High-cycle industrial testing | Any | Capacitive (Not Carbon) | Advanced Capacitive Flex (Custom) |






