The Sensing Principle: Variable Resistance via Carbon Ink

A flex sensor is fundamentally a passive, analog variable resistor. The active sensing element consists of a carbon-based polymer ink printed onto a flexible, insulated substrate. When the sensor rests perfectly flat, the carbon particles are tightly packed together, yielding a low baseline resistance—typically between 10kΩ and 25kΩ depending on the specific model and manufacturer.

As you bend the sensor along its active length, the substrate stretches on the convex side. This physical deformation pulls the carbon particles apart, increasing the electrical path length and reducing the cross-sectional area for electron flow. Consequently, the resistance spikes proportionally to the bend angle. At a 90-degree bend, the resistance typically doubles or triples (e.g., reaching 30kΩ to 60kΩ). Because it is strictly a passive resistive component, it outputs no native voltage, current, or digital signal on its own; it requires external signal conditioning to be read by a microcontroller.

Wiring the Voltage Divider and Pin Mapping

To read a variable resistor with a microcontroller's Analog-to-Digital Converter (ADC), you must convert the resistance change into a voltage change. This is done using a voltage divider circuit. You place a fixed pull-down resistor in series with the flex sensor. The microcontroller reads the voltage at the junction between the two resistors.

Callout Tip: Never connect a flex sensor directly between VCC and an ADC pin without a pull-down resistor. Without the fixed resistor to ground, the ADC pin will either float randomly or read a hard maximum VCC, giving you zero usable data.

Standard Pin and Wiring Table

Flex Sensor Pin Destination Notes & Constraints
Pin 1 (Arbitrary) VCC (3.3V or 5V) Supply range is 3.3V to 5V. Use 3.3V for ESP32 to keep the divider output within the linear ADC region.
Pin 2 (Arbitrary) ADC Input Pin & Pull-down Resistor Connects to the ADC pin (e.g., ESP32 GPIO 34) AND one leg of a 10kΩ fixed resistor.
Pull-down Resistor GND The other leg of the 10kΩ resistor connects to system ground.

Supply Range Note: While flex sensors can tolerate up to 5V, running the divider at 3.3V is highly recommended for 3.3V logic microcontrollers like the ESP32 or Raspberry Pi Pico. If you use a 5V supply with an ESP32, the voltage at the ADC junction can exceed 3.3V when the sensor is flat, instantly saturating the ADC and potentially damaging the GPIO pin.

The Math: Raw ADC Reads to Bend Angles

Converting the raw ADC integer into a physical bend angle requires a three-step mathematical pipeline: ADC to Voltage, Voltage to Resistance, and Resistance to Angle. Below is the exact sequence used in production firmware.

Step 1: ADC to Voltage

Assuming a 12-bit ADC (like the ESP32, which reads 0 to 4095) and a 3.3V reference:

V_out = (ADC_Raw / 4095.0) * 3.3

Step 2: Voltage to Flex Resistance

Using the standard voltage divider formula rearranged to solve for the unknown sensor resistance (R_flex), where R_pull is your fixed 10,000Ω resistor:

R_flex = R_pull * (V_out / (3.3 - V_out))

Step 3: Resistance to Angle (Linear Interpolation)

Flex sensors are reasonably linear between 0° and 90°. According to the SparkFun Flex Sensor Hookup Guide, a standard 2.2-inch sensor outputs roughly 10kΩ at 0° and 35kΩ at 90°. You map the calculated resistance to this range:

Angle = ((R_flex - R_flat) / (R_bent90 - R_flat)) * 90.0

Implementation Code (C++ / Arduino Framework)

const float V_CC = 3.3;
const float R_PULL = 10000.0; // 10k ohm pull-down
const int ADC_MAX = 4095;

// Calibration constants (measure these for your specific unit)
const float R_FLAT = 11000.0;  // Resistance at 0 degrees
const float R_BENT_90 = 32000.0; // Resistance at 90 degrees

float getBendAngle(int adc_raw) {
    // Prevent division by zero if ADC reads max value
    if (adc_raw >= ADC_MAX) adc_raw = ADC_MAX - 1;
    
    float v_out = ((float)adc_raw / ADC_MAX) * V_CC;
    float r_flex = R_PULL * (v_out / (V_CC - v_out));
    
    float angle = ((r_flex - R_FLAT) / (R_BENT_90 - R_FLAT)) * 90.0;
    
    // Clamp angle to physical limits
    if (angle < 0.0) return 0.0;
    if (angle > 90.0) return 90.0;
    return angle;
}

Calibration, Hysteresis, and Interference Sources

Off-the-shelf flex sensors are notorious for unit-to-unit variance. You cannot rely on datasheet baseline numbers for precision work; you must perform a 2-point physical calibration. Measure the ADC value when the sensor is clamped perfectly flat (0°), and again when clamped against a machined 90-degree bracket. Plug those derived resistance values into the R_FLAT and R_BENT_90 constants in the code above.

When deploying flex sensors in the field, you must account for four primary interference sources:

  1. Creep and Hysteresis: Carbon polymer ink exhibits viscoelastic properties. If you hold the sensor at 90° for 60 seconds, the resistance will slowly drift upward (creep). When released, it will not immediately snap back to the 0° baseline (hysteresis). Fix: Implement a software deadband and avoid using flex sensors for applications requiring rapid, high-precision return-to-zero measurements.
  2. Temperature Drift: The carbon ink's resistance shifts with ambient temperature. A sensor calibrated at 20°C will read a different baseline at 35°C. Fix: If operating in uncontrolled environments, add a thermistor to your circuit and apply a temperature compensation multiplier in firmware.
  3. ADC Noise and Non-Linearity: The ESP32's internal ADC is notoriously noisy (±50 counts) and highly non-linear near the 3.3V rail. As documented in the Espressif ADC Calibration API, readings above 2.8V are unreliable. Fix: Keep your voltage divider output below 2.5V by using a 3.3V supply and a 10kΩ pull-down, and apply an Exponential Moving Average (EMA) low-pass filter to the raw ADC reads.
  4. Mechanical Fatigue: Bending the sensor past its minimum bend radius (typically 0.25 inches or 6.35mm) will micro-fracture the carbon trace, leading to permanent open-circuit failures or erratic resistance spikes. Fix: Never fold the sensor sharply; always bend it in a smooth arc.

Decision Tree: Selecting Your Sensor and Pull-Down Resistor

Use the following decision matrix to select the correct hardware for your specific embedded application.

If your application requires... Then choose this sensor type... And this pull-down resistor...
Gross gesture tracking (animatronics, smart gloves, robotic grippers) Standard 2.2" Unidirectional Flex Sensor 10kΩ 1% Metal Film
Micro-deflection or structural strain monitoring Piezoresistive Strain Gauge (Not a flex sensor) Wheatstone Bridge + Instrumentation Amp
Measuring bending in both directions (up and down) 2-Way / Bidirectional Flex Sensor 10kΩ (Requires mid-scale bias calibration)
High-precision, zero-hysteresis angle tracking Rotary Encoder or IMU (BNO055) N/A (Digital I2C/SPI interface)

The Concrete Recommendation

For 95% of DIY, wearable, and embedded robotics projects, do not overcomplicate your bill of materials. Buy the Spectra Symbol 2.2" Flex Sensor (Model FS-A) or the identical Adafruit 2.2" Flex Sensor (Product ID 182), which typically retails for $8 to $12.

Pair it exclusively with a 10kΩ 1% tolerance metal film pull-down resistor and power the divider at 3.3V. Do not use 47kΩ or 100kΩ pull-down resistors; while they reduce current draw, they push the voltage divider's output into the non-linear upper saturation zone of the ESP32 ADC, destroying your measurement accuracy. Stick to the 10kΩ/3.3V combination, apply the EMA filter in software, and your angle tracking will be stable and repeatable.