Emerging Interfaces

Force Sensing From Zero: FSRs, Load Cells, and Which One You Actually Want

An FSR costs a few dollars and is not a scale. A load cell costs a bit more and is. Picking wrong is the most common mistake in interactive pressure sensing.

Pressure is an underused input. A button is binary, a knob needs a hand already free, and a camera needs light and a clear view — but how hard someone is pressing, leaning, gripping or standing is continuous, physical, and almost nobody uses it.

The sensors cost a few dollars. The difficulty is that there are two very different kinds and the names do not make the difference obvious.

Science Buddies’ walkthrough of the basic FSR circuit.

The two options, and the decision

FSR (force-sensitive resistor)Load cell
MeasuresForce, approximatelyForce, accurately
Cost$5–15$5–20, plus an amplifier
OutputResistance, 1MΩ → ~1kΩTiny differential voltage (mV)
Extra hardwareOne resistorHX711 amplifier board
RepeatabilityPoor — 10–25% error, driftsGood — a few grams
LinearityVery non-linearLinear
Thin and flexibleYesNo — rigid metal
Right forIs someone pressing, and roughly how hardHow much does this weigh

The decision is one question: do you need a number, or do you need a gesture?

If the answer is I want the sound to get louder as they press harder — use an FSR. It is thin, cheap, and bends around things.

If the answer is I want to know when someone is standing on the plate or how much water is in this vessel — use a load cell. An FSR will give you a figure that drifts over an afternoon and changes if the sensor is mounted slightly differently.

FSR: the circuit

An FSR is a variable resistor. You cannot read resistance with an ADC, so you make a voltage divider:

3.3V ──[ FSR ]──┬──[ 10kΩ ]── GND
                │
             to ADC pin
int raw = analogRead(A0);          // 0–1023 (or 0–4095 on ESP32)
float v  = raw * 3.3 / 1023.0;
float r  = 10000.0 * (3.3 - v) / v;   // FSR resistance in ohms

Choosing the fixed resistor sets your sensitive range. The divider is most sensitive where the two resistances are comparable, so a 10kΩ resistor gives good resolution around 10kΩ of FSR resistance — roughly a firm press. For light touch use 100kΩ; for heavy force use 1kΩ. This is the single most effective adjustment and most people never change it from whatever the tutorial said.

Do not try to convert to newtons. FSR datasheets give force-resistance curves, they are log-log, and unit-to-unit variation is large. Map raw readings to your output range empirically and move on.

Load cell: the circuit

A load cell is a metal beam with strain gauges in a Wheatstone bridge. Bending changes the gauges’ resistance and unbalances the bridge, producing a differential voltage of a few millivolts at full scale — far too small for a microcontroller ADC.

So you need an HX711 — a 24-bit ADC with a built-in instrumentation amplifier, about $2, and the standard answer:

#include "HX711.h"
HX711 scale;

void setup() {
  scale.begin(DOUT_PIN, SCK_PIN);
  scale.set_scale(CALIBRATION_FACTOR);   // from calibration, below
  scale.tare();                          // zero with nothing on it
}

void loop() {
  float grams = scale.get_units(5);      // average of 5 readings
}

Calibration is two steps and takes two minutes: tare() with nothing on the cell, then put a known mass on it, read the raw value, and CALIBRATION_FACTOR = raw / known_grams. A bag of sugar is a perfectly good reference.

Wire colours are usually red/black for excitation and white/green for signal, but check your cell — they vary, and swapping signal wires inverts your readings.

The four things that will catch you out

1. Hysteresis. Press an FSR to 50% and release to 50% and you get two different readings. This is physical, not noise, and no filtering fixes it. Design around it: never use absolute FSR values as a position, only as a direction of change or a thresholded state.

2. Drift and creep. Hold a constant force on an FSR and the reading slowly changes. Load cells creep too, less. For anything that sits loaded for hours — a plinth, a seat, a floor plate — re-zero periodically when you believe the load is removed, or accept slow baseline wander.

3. Temperature. Load cells are noticeably temperature-sensitive. An installation near a window or a projector will show a daily drift that looks like someone leaning on it. Good load cells are temperature-compensated; cheap ones are not.

4. Mounting is most of the result. This is the big one. A load cell must be mounted so the force goes through it in the direction it expects — typically one end bolted down, the other end loaded, with nothing else carrying the load. If your plate also rests on its frame, the frame takes the weight and the cell reads nothing. Four cells under a platform, summed, is the standard way to make a reliable floor plate.

For an FSR, put something compliant over it — a few millimetres of silicone or foam — to spread point loads across the sensing area. Pressing a hard object directly onto an FSR gives you wildly inconsistent readings depending on exactly where it lands.

What to build

  • Pressure-sensitive pads and plinths. An FSR under a surface, or four load cells under a platform, gives you presence and intensity. Far better than a PIR, which only tells you something moved.
  • Grip and squeeze interfaces. An FSR wrapped in a soft object is one of the most intuitive expressive controls there is — and it maps beautifully to amplitude or filter cutoff.
  • Weight as a slow input. A load cell measuring a vessel’s contents over hours drives work on a completely different timescale from motion sensing.
  • Centre of pressure. Four load cells under a board give you where the weight is, not just how much — a balance board, from first principles.

For the complementary sensor, see our IMU primer: accelerometers tell you how something is moving, force sensors tell you how hard it is being pushed, and a lot of good interfaces use both.