A Force Sensing Resistor, also known as a Force Sensor, or simply an FSR, is a simple and inexpensive sensor designed to measure physical pressure, squeeze, and weight.
It can be found in a variety of portable electronics, including electronic drums, handheld gaming devices, and mobile phones.
This sensor is excellent at measuring pressure, but not so accurate at estimating how much weight is on it. So, if you just want to know “whether the sensor has been squeezed or pressed and how hard,” it could be a good choice for your next force-sensing project.
FSR Overview
The patent for the technology used in FSRs is owned by Interlink Electronics, which has been in business since 1985. The most common types of FSR that you will encounter are Interlink FSR-402 and FSR-406.
Construction
An FSR is simply a variable resistor whose resistance varies in response to pressure applied to the sensing area.
It is made up of several thin, flexible layers. When squeezed, more of the carbon elements that normally offer resistance are brought into contact with the conductive traces, thereby lowering the resistance.
Shape and Size
There is a wide selection of FSRs available, each with its own unique size, shape, and sensing range.
The majority of FSRs have circular or rectangular sensing areas. Rectangular FSRs are ideal for wide-area sensing, whereas small circular sensors can provide higher accuracy.
Sensing Range
The sensing range of the FSR is another important aspect because it determines the lowest and highest pressures that it can detect.
The shorter the FSR’s sensing range, the greater its sensitivity. But! any pressure above the maximum range of the sensor is unmeasurable (which can also damage the sensor). For example, a smaller 1kg rated FSR will provide more sensitive readings from 0 to 1kg, but cannot distinguish between 2kg and 5kg.
How Does FSR Work?
As previously stated, an FSR is basically a resistor whose resistive value varies based on the amount of pressure applied to it.
In the absence of pressure, the sensor will read infinite resistance (larger than 1MΩ). Applying more pressure to the sensor’s head reduces the resistance between its terminals, while releasing the pressure restores the resistance to its original value.
The graph below shows the approximate resistance of the FSR-402 sensor at various applied forces. Here, logarithmic scales are used to plot the data.
Observe that the graph is linear above 50g. This is due to the fact that these sensors have a turn-on threshold. It’s a force that must exist before the resistance drops below 100k, after which the relationship becomes more linear.
Reading an FSR
The simplest way to read the FSR 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 FSR.
We can use this equation to calculate the output voltage (Vo).
In this configuration, the output voltage increases as the applied force increases.
For example, with a 5V supply and a 10K pull-down resistor, when there is no pressure, the FSR resistance is extremely high (around 10M). This produces the following output voltage:
If you apply significant force to the FSR, the resistance will drop to approximately 250 Ω. As a result, the output voltage becomes:
As you can see, the output voltage varies from 0 to 5V depending on the amount of force applied to the sensor.
The table below gives a rough idea of the analog voltage you can expect from an FSR at various applied forces.
Force (lb) | Force (N) | FSR Resistance | Voltage across R |
None | None | Infinite | 0V |
0.04lb | 0.2N | 30KΩ | 1.3V |
0.22lb | 1N | 6KΩ | 3.1V |
2.2lb | 10N | 1KΩ | 4.5V |
22lb | 100N | 250Ω | 4.9V |
Wiring an FSR to an Arduino
It is quite easy to connect FSR to an arduino.
You need to connect a 10kΩ pull-down resistor in series with the FSR to create a voltage divider circuit. Next, the A0 ADC input of an Arduino is wired to the junction of the pull-down resistor and the FSR.
Keep in mind that FSRs are really just resistors, which means you can connect them either way and they will still work.
Arduino Example 1 – Simple Analog FSR Measurements
In our first experiment, we will read sensor data from the Arduino’s ADC pin and display it on the serial monitor.
The code is pretty straightforward. It simply prints out what it interprets as the amount of pressure in a qualitative manner. For most projects, this is pretty much all that is needed.
int fsrPin = 0; // the FSR and 10K pulldown are connected to a0
int fsrReading; // the analog reading from the FSR resistor divider
void setup(void) {
Serial.begin(9600);
}
void loop(void) {
fsrReading = analogRead(fsrPin);
Serial.print("Analog reading = ");
Serial.print(fsrReading); // print the raw analog reading
if (fsrReading < 10) {
Serial.println(" - No pressure");
} else if (fsrReading < 200) {
Serial.println(" - Light touch");
} else if (fsrReading < 500) {
Serial.println(" - Light squeeze");
} else if (fsrReading < 800) {
Serial.println(" - Medium squeeze");
} else {
Serial.println(" - Big squeeze");
}
delay(1000);
}
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 FSR is connected. Next, we define the fsrReading
variable to store the FSR’s raw analog reading.
int fsrPin = 0;
int fsrReading;
In the setup function, serial communication is established.
void setup(void) {
Serial.begin(9600);
}
In the loop, we read the FSR’s analog output and show it on the serial monitor.
As mentioned previously, the sensor’s output voltage varies from 0V (no pressure applied) to approximately 5V (maximum pressure applied). When the Arduino converts this analog voltage to a digital value, it converts it to a 10-bit number between 0 and 1023. Therefore, the value displayed on the serial monitor will range from 0 to 1023 based on how hard you squeeze the sensor.
fsrReading = analogRead(fsrPin);
Serial.print("Analog reading = ");
Serial.print(fsrReading);
Finally, we print the amount of pressure measured qualitatively.
if (fsrReading < 10) {
Serial.println(" - No pressure");
} else if (fsrReading < 200) {
Serial.println(" - Light touch");
} else if (fsrReading < 500) {
Serial.println(" - Light squeeze");
} else if (fsrReading < 800) {
Serial.println(" - Medium squeeze");
} else {
Serial.println(" - Big squeeze");
}
Arduino Example 2 – Advanced Analog FSR Measurements
The following Arduino sketch is quite advanced. It measures the approximate Newton force measured by the FSR. This can be quite helpful for calibrating the forces you expect the FSR will experience.
int fsrPin = 0; // the FSR and 10K pulldown are connected to a0
int fsrReading; // the analog reading from the FSR resistor divider
int fsrVoltage; // the analog reading converted to voltage
unsigned long fsrResistance; // The voltage converted to resistance
unsigned long fsrConductance;
long fsrForce; // Finally, the resistance converted to force
void setup(void) {
Serial.begin(9600); // We'll send debugging information via the Serial monitor
}
void loop(void) {
fsrReading = analogRead(fsrPin);
Serial.print("Analog reading = ");
Serial.println(fsrReading);
// analog voltage reading ranges from about 0 to 1023 which maps to 0V to 5V (= 5000mV)
fsrVoltage = map(fsrReading, 0, 1023, 0, 5000);
Serial.print("Voltage reading in mV = ");
Serial.println(fsrVoltage);
if (fsrVoltage == 0) {
Serial.println("No pressure");
} else {
// The voltage = Vcc * R / (R + FSR) where R = 10K and Vcc = 5V
// so FSR = ((Vcc - V) * R) / V yay math!
fsrResistance = 5000 - fsrVoltage; // fsrVoltage is in millivolts so 5V = 5000mV
fsrResistance *= 10000; // 10K resistor
fsrResistance /= fsrVoltage;
Serial.print("FSR resistance in ohms = ");
Serial.println(fsrResistance);
fsrConductance = 1000000; // we measure in micromhos so
fsrConductance /= fsrResistance;
Serial.print("Conductance in microMhos: ");
Serial.println(fsrConductance);
// Use the two FSR guide graphs to approximate the force
if (fsrConductance <= 1000) {
fsrForce = fsrConductance / 80;
Serial.print("Force in Newtons: ");
Serial.println(fsrForce);
} else {
fsrForce = fsrConductance - 1000;
fsrForce /= 30;
Serial.print("Force in Newtons: ");
Serial.println(fsrForce);
}
}
Serial.println("--------------------");
delay(1000);
}
Here’s what the output looks like in the serial monitor.