A flex sensor, also known as a bend sensor, is a low-cost, simple-to-use sensor used to measure the amount of deflection or bending.
It gained popularity in the 1990s due to its inclusion in the Nintendo Power Glove. People have been using it ever since as a goniometer to measure joint movement, a door sensor, a bumper switch to detect walls, and a pressure sensor on robotic grippers.
Flex Sensor Overview
A flex sensor is basically a variable resistor, whose resistance varies when bent. Because the resistance is directly proportional to the amount of bending, it is often referred to as a Flexible Potentiometer.
Flex sensors are typically available in two sizes: 2.2′′ (5.588cm) long and 4.5′′ (11.43cm) long.
Construction
A conductive ink based flex sensor is made of a phenolic resin substrate onto which conductive ink is applied. A segmented conductor is then placed on top to create a flexible potentiometer.
Directions to Use
The flex sensor is only designed to be flexed in one direction, away from the ink, as shown in the image below. If you bend the sensor in the opposite direction, you will not receive accurate data and you may even damage it.
Also, avoid bending the sensor too close to the base (where the pins are crimped), as this can cause it to kink and fail.
How Do Flex Sensors Work?
The conductive ink on the sensor serves as a resistor. When the sensor is straight, this resistance is around 25k.
When the sensor is bent, the conductive layer is stretched, resulting in a reduced cross section (imagine stretching a rubber band) and increased resistance. At a 90° angle, this resistance is approximately 100K.
When the sensor is straightened out again, the resistance returns to its original value. By measuring the resistance, you can determine how much the sensor is bent.
Reading a Flex Sensor
The simplest way to read the flex sensor is to combine it with a static resistor to form a voltage divider, which produces a variable voltage that can be read by the analog-to-digital converter of a microcontroller.
It is important to note that the output voltage you measure is the voltage drop across the pull-down resistor, not the voltage drop across the flex sensor.
We can use this equation to calculate the output voltage (Vo).
In this configuration, the output voltage decreases as the bend radius increases.
For example, with a 5V supply and a 47K pull-down resistor, when the sensor is flat (0°), the resistance is relatively low (around 25k). This produces the following output voltage:
When bent to its full extent (90°), the resistance increases to approximately 100K. As a result, the output voltage becomes:
Wiring a Flex Sensor to an Arduino
Connecting a flex sensor to an Arduino is very simple.
You need to connect a 47kΩ pull-down resistor in series with the flex sensor to create a voltage divider circuit. The A0 ADC input of an Arduino is then wired to the junction of the pull-down resistor and the flex sensor.
Keep in mind that flex sensors are really just resistors, which means you can connect them either way and they will still work.
Arduino Example Code
Here’s a simple sketch that reads sensor data from the Arduino’s ADC pin and displays it on the serial monitor. For most projects, this is pretty much all that is needed.
const int flexPin = A0; // Pin connected to voltage divider output
// Change these constants according to your project's design
const float VCC = 5; // voltage at Ardunio 5V line
const float R_DIV = 47000.0; // resistor used to create a voltage divider
const float flatResistance = 25000.0; // resistance when flat
const float bendResistance = 100000.0; // resistance at 90 deg
void setup() {
Serial.begin(9600);
pinMode(flexPin, INPUT);
}
void loop() {
// Read the ADC, and calculate voltage and resistance from it
int ADCflex = analogRead(flexPin);
float Vflex = ADCflex * VCC / 1023.0;
float Rflex = R_DIV * (VCC / Vflex - 1.0);
Serial.println("Resistance: " + String(Rflex) + " ohms");
// Use the calculated resistance to estimate the sensor's bend angle:
float angle = map(Rflex, flatResistance, bendResistance, 0, 90.0);
Serial.println("Bend: " + String(angle) + " degrees");
Serial.println();
delay(500);
}
If everything is fine, you should see the following output on the serial monitor.
Code Explanation:
The sketch begins with the declaration of the Arduino pin to which the flex sensor is connected.
const int flexPin = A0;
Then, a few constants are defined, including the system voltage (VCC
), the resistor used to make a voltage divider (R_DIV
), and the resistance offered by the flex sensor in its flat and bent configurations (flatResistance
and bendResistance
, respectively). Make sure these constants are set correctly.
const float VCC = 5;
const float R_DIV = 47000.0;
const float flatResistance = 25000.0;
const float bendResistance = 100000.0;
In the setup, we establish serial communication and configure the flexPin
as an INPUT.
void setup() {
Serial.begin(9600);
pinMode(flexPin, INPUT);
}
In the loop, we start by reading the ADC.
int ADCflex = analogRead(flexPin);
When the Arduino converts the analog output voltage of the sensor to a digital value, it converts it to a 10-bit number between 0 and 1023. Therefore, to calculate the actual output voltage, we use the following formula:
float Vflex = ADCflex * VCC / 1023.0;
The resistance of the flex sensor is then calculated using the formula derived from the voltage divider formula and displayed on the serial monitor.
float Rflex = R_DIV * (VCC / Vflex - 1.0);
Serial.println("Resistance: " + String(Rflex) + " ohms");
We then use the calculated resistance to estimate the bend angle of the sensor. For this, we use the IDE’s built-in map()
function.
The map()
function maps and converts the sensor’s resistance to its bend angle. When we call map(Rflex, flatResistance, bendResistance, 0, 90.0)
, the value of flatResistance
is mapped to 0°, the value of bendResistance
is mapped to 90°, and the values in-between are mapped to values in-between.
float angle = map(Rflex, flatResistance, bendResistance, 0, 90.0);
Serial.println("Bend: " + String(angle) + " degrees");
Serial.println();