Interfacing Force Sensing Resistor (FSR) with Arduino

Force Sensing Resistors are also known as Force Sensitive Resistors or Force Sensors or just FSRs. They are low-cost and easy-to-use sensors specifically designed to detect physical pressure, squeeze, and weight.

You will find them in electronic drums, mobile phones, handheld gaming devices and many more portable electronics.

While these sensors are great for measuring pressure, they are not great at finding how many pounds of weight they have on them. However, if you just want to find out “whether the sensor has been squeezed or pressed and how much” they are a good option for your next touch-sensing project.

FSR Overview

The technology used in FSRs has been patented by Interlink Electronics which has been in operation since 1985. The most common types of FSR that you will easily find are the Interlink FSR-402 and FSR-406.

Construction

An FSR is nothing but a variable resistor that varies in resistance as pressure is applied to the sensing area.

It is made up of several thin flexible layers. The more it is pressed, the more resistive carbon elements touch the conductive traces and this reduces resistance.

how fsrs made

Shape and Size

There are a variety of FSR options out there, and a few key features such as size, shape, and sensing range that set them apart.

Most FSRs have either a circular or rectangular sensing area. Square FSRs are good for broad-area sensing, while small circular sensors can provide greater accuracy to the sensing field.

types of fsr sensors

Sensing Range

Another key feature of the FSR is its rated sensing range, which defines the minimum and maximum pressures that the sensor can differentiate between.

The lower the force rating, the more sensitive the FSR is. Any pressure beyond the sensor’s maximum range is unmeasurable (which can also damage the sensor). For example, a smaller 1kg rated FSR may provide more sensitive readings from 0 to 1kg, but cannot tell the difference between 2kg and 5kg weight.

How FSR Works?

As we have said, FSR is basically a resistor that changes its resistive value depending on how much it has been pressed.

fsr working animation

When there is no pressure, the sensor looks like an infinite resistor (open circuit). The harder you press on the head of the sensor, the lower the resistance between the two terminals will be, but as you remove the pressure it will return to its original value.

The graph below displays approximately the resistance of the sensor at different force measurements for the FSR 402 sensor. Note that the data is plotted on logarithmic scales.

fsr 402 resistance vs force curve

Notice that the graph is generally linear from 50g and up, but not below 50g. This means that whenever we put pressure on it, its resistance quickly decreases from infinity to 100K, and then becomes more linear.

Reading an FSR

The easiest way to read the FSR is to connect the FSR with a fixed value resistor (usually 10kΩ) to create a voltage divider. To do this you connect one end of the FSR to Power and the other to a pull-down resistor. Then the point between the fixed value pull-down resistor and the variable FSR resistor is connected to the ADC input of an Arduino.

This way you can create a variable voltage output, which can be read by a microcontroller’s ADC input.

fsr voltage divider

Note that the output voltage you measure is the voltage drop across the pull-down resistor, not across the FSR.

The output of the voltage divider configuration is described by the equation:

fsr1

In the shown configuration, the output voltage increases with increasing force.

For example, with 5V supply and 10K pull-down resistor, when there is no pressure, the FSR resistance is very high (around 10MΩ). This results in the following output voltage:

fsr2

If you press really hard on the FSR, the resistance will go down to roughly 250 Ω. This results in the following output voltage:

fsr3

As you can see, the output voltage varies from 0 to 5V depending on the amount of force applied to the sensor.

Below table indicates the approximate analog voltage based on the sensor force/resistance with 5V supply and 10K pulldown resistor.

Force (lb)Force (N)FSR ResistanceVoltage across R
NoneNoneInfinite0V
0.04lb0.2N30KΩ1.3V
0.22lb1N6KΩ3.1V
2.2lb10N1KΩ4.5V
22lb100N250Ω4.9V

Wiring an FSR to Arduino UNO

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. Then the point between the pull-down resistor and the FSR is connected to the A0 ADC input of an Arduino.

wiring fsr to arduino

Note that FSRs are basically resistors. This means that you can connect them either way and they will work fine.

Arduino Code – Simple Analog FSR Measurements

For our first experiment, we will read the sensor data from the ADC pin of the Arduino and display the output on the serial monitor.

The code is pretty straightforward. It just prints out what it interprets as the amount of pressure in a qualitative manner. For most projects, this is pretty much all that’s 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 below output on serial monitor.

fsr analog output

Code Explanation:

The sketch begins with the declaration of the Arduino pin to which FSR and 10K pull-down are connected. We also define the variable fsrReading which holds the raw analog reading from the FSR.

int fsrPin = 0;
int fsrReading;

In setup function of code we initialize the serial communication with the PC.

void setup(void) {
  Serial.begin(9600);   
}

In loop function, we take the analog reading from the FSR resistor divider and display it on serial monitor.

As mentioned earlier, the output voltage of the sensor is between 0V (no pressure applied) and approximately 5V (maximum pressure applied). When the Arduino converts this analog voltage into digital, it actually converts it to a 10-bit number of range 0 to 1023. So you will see a value between 0 and 1023 in a serial monitor, depending 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 Code – Advanced Analog FSR Measurements

Our next arduino sketch is pretty advanced. It measures the approximate Newton force measured by the FSR. This can be pretty useful for calibrating what forces you think 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 how the output looks like in the serial monitor.

fsr analog output2