When You Squeeze, It Vibrates — Build a Haptic Feedback Device with Arduino
You squeeze the trigger. The controller hits back.
That vibration? It was engineered — probably by a team with a massive budget. And for years, that little pulse felt like magic.
But here's the truth: it's not magic. It's physics. And you can build it yourself.
Not in a lab. Not with industrial equipment. Just an Arduino, a force sensor, and a vibration motor — wired together in an afternoon, running code you wrote yourself.
This is what it feels like to make feedback, instead of just receiving it.
What Would You Actually Use This For?
Before we touch a wire, here's the more important question:
What would you build this for?
The applications are bigger than you might think:
VR and gaming — Put an FSR on your glove. Grip harder, and the controller pushes back harder. The virtual sword feels heavy when you swing it. The physics you feel is exactly the physics you designed.
Rehabilitation coaching — A physical therapist attaches an FSR+Arduino module to a grip strengthener. The device vibrates the moment a patient hits their target pressure zone — a real-time, physical cue that says "you're doing it right." No camera. No screen. Just feel.
Wearable nudges — Someone with nerve damage needs to know when they're putting too much pressure on a healing injury. A small FSR patch triggers a gentle pulse at the wrist before pain even starts. The body learns what numbers on a screen never taught it.
Musical expression — A drummer places FSR pads under drumsticks. Hit harder, and the haptic response through the stick intensifies. Every strike becomes a two-way conversation — you hit, it answers, you adjust.
Smart assistive devices — An elderly user's door handle has an embedded FSR. As grip weakens with age, the Arduino subtly resists or assists the turn. Independent entry without assistance — a dignity issue most smart home tech ignores entirely.
All of these are built on the same core principle: force becomes feedback. And that's a loop you can design yourself.
How an FSR Reads Your Force
The heart of this system is a component called an FSR — Force Sensing Resistor.
Its resistance changes with pressure. That's it. That's the whole device.
But the "how" is where it gets interesting:
Think of it like a crowded subway platform at rush hour.
When nobody's pushing, people stand spaced apart — hard to make contact. But the moment the crowd gets compressed, bodies pack tight and people bump into each other constantly. More pressure. More connection. More everything.
An FSR works the same way. Press on it, and microscopic conductive particles inside get squeezed together, creating pathways for electrons to flow. The harder you press, the lower the resistance. Arduino reads that resistance as a voltage, and that voltage becomes a number you can use.
No moving parts. No calibration. Just a thin sheet that feels the world through touch.
What You'll Need
| Component | Recommended Spec | Purpose |
|---|---|---|
| FSR Force Sensor | Interlink 402 or 406 series, 5–10mm | Reads your press, translates it to resistance |
| Arduino Nano | ATmega328P | The brain — reads signal, drives output |
| LRA Vibration Motor | 3V / 5V, flat coin style (6mm or 10mm) | Fast response, precise haptic control |
| OR ERM Motor | 3V–5V, cylindrical | Stronger buzz, slightly slower |
| NPN Transistor | 2N2222 or S8050 | Switches the motor on/off from Arduino's signal |
| Diode | 1N4001 or 1N4148 | Flyback protection — shields your circuit from voltage spikes |
| 10kΩ Resistor | 1/4W | Forms a voltage divider with the FSR |
| 1kΩ Resistor | 1/4W | Protects Arduino's output pin |
| Breadboard + Wires | Various | Quick prototyping |
⚠️ Safety first — two rules that will save your Arduino:
Rule 1: Arduino is the brain, not the battery.
Arduino's digital pins output signals — they don't supply power to motors. A vibration motor can draw 100–500mA when spinning up. That's far more than Arduino's 40mA per pin limit. Always use a transistor or motor driver to switch an external power supply.
Rule 2: Motors are lazy — they don't want to stop.
When you cut power, a motor's collapsing magnetic field spits a voltage spike back at your circuit. This back-EMF can destroy your transistor or Arduino's GPIO pin instantly. A flyback diode gives that energy a safe exit route instead.
Wiring — Step by Step
Step 1 — The FSR Voltage Divider
- Connect one leg of the 10kΩ resistor to Arduino's 5V pin.
- Connect the other leg of the resistor to Arduino's A0 pin.
- Connect one leg of the FSR to Arduino's A0 pin — the same junction point as the resistor.
- Connect the other leg of the FSR to GND.
This creates a voltage divider: when you press the FSR and its resistance drops, the voltage at A0 rises. Arduino reads that as a number between 0 and 1023.
Step 2 — The Transistor Switch
- Connect the transistor's base (B) through the 1kΩ resistor to Arduino's Pin 9 (PWM output).
- Connect the transistor's collector (C) to the motor's positive lead.
- Connect the transistor's emitter (E) to GND.
This arrangement lets Arduino's small signal switch a much larger current through the motor.
Step 3 — Flyback Protection
Connect the 1N4001 diode in parallel with the motor terminals — band (cathode) toward the positive side, anode toward ground.
This is not optional. The moment you cut power to a motor, this diode saves your circuit.
Step 4 — Connect the Motor
- Connect the motor's positive lead to an external 5V supply (or Arduino's 5V pin for small motors under 200mA only).
- Connect the motor's negative lead to the transistor's collector (C).
Step 5 — Verify
Double-check all grounds are shared. Confirm diode orientation. Use a multimeter to check for shorts before powering on.
The Code
// FSR + Arduino Haptic Feedback System
// Reads force, maps it to vibration motor intensity
const int fsrPin = A0; // FSR on analog pin 0
const int motorPin = 9; // Motor driver transistor on PWM pin 9
void setup() {
Serial.begin(9600);
pinMode(motorPin, OUTPUT);
}
void loop() {
int fsrValue = analogRead(fsrPin); // Read FSR value (0–1023)
int vibration = 0;
if (fsrValue > 50) {
// Map force to motor speed (30–255, LRA minimum threshold)
vibration = map(fsrValue, 50, 1023, 30, 255);
vibration = constrain(vibration, 0, 255);
}
analogWrite(motorPin, vibration); // Drive motor
// Optional: monitor in Serial Monitor at 9600 baud
Serial.print("FSR: ");
Serial.print(fsrValue);
Serial.print(" -> Motor: ");
Serial.println(vibration);
delay(50);
}
How it works:
-
analogRead(fsrPin)samples the voltage at A0, giving you a number from 0 (no press) to 1023 (full scale). - The
if (fsrValue > 50)threshold filters idle noise — without it, the motor would jitter constantly even when no one is touching it. -
map(fsrValue, 50, 1023, 30, 255)scales your press to the motor's usable range. We start at 30 because most LRAs need a minimum voltage just to overcome inertia. -
analogWrite()sends a PWM signal to the transistor, controlling how fast the motor spins.
To test: Open the Serial Monitor at 9600 baud. Press the FSR lightly — you should see values in the 200–400 range. Press hard — values approach 1023. Watch the motor respond in real time.
That Pulse Was Yours
Here's what you just built:
A loop that starts with your body, travels through a piece of polymer that changes resistance when you press it, gets read by a microcontroller that translates pressure into a number, gets processed through code you wrote, and ends with a motor that vibrates back against your skin.
You designed that whole chain. Wire by wire. Line by line.
The next time you feel that little pulse in a game controller — know that it came from your own hands. FSR + Arduino: where your touch becomes the feedback.
Ready to Build This?
I independently research and test every part in my guides. If you find this useful, grabbing components through my verified links is the best way to say thanks — and it helps me keep publishing.
Start here:
I may earn a small commission on qualifying purchases — at no extra cost to you.
Part 2 is coming: We're adding Bluetooth so you can control haptic intensity from your phone. Same principle — more possibilities.
📎 Friends Link
Follow my latest interactive system builds and breakdowns:

Top comments (0)