DEV Community

張旭豐
張旭豐

Posted on

From Feeling to Firmware: Build Your First Haptic Feedback Device in 10 Minutes

From Feeling to Firmware: Build Your First Haptic Feedback Device in 10 Minutes

How do you feel that subtle tap on your wrist? Let's break down the technology — and build it yourself.


The Moment You Felt It

When your Apple Watch taps your wrist to notify you, you feel it. When your PS5 controller rumbles during a race, you feel it. When your phone vibrates in your pocket, you feel it.

But have you ever wondered what's actually happening inside those devices — and how you could build the same feeling into your own projects?

That's what we're going to do today.

By the end of this article, you'll have built a working haptic feedback circuit and written the Arduino code to control it. No theory, no deep physics — just a working prototype you can hold in your hand.


What Makes Things Feel Like They're Touching You?

There are three main technologies that create tactile sensations:

ERM (Eccentric Rotating Mass) LRA (Linear Resonant Actuator) Piezo
Feel Strong buzz, broad vibration Crisp, fast taps Sharp, precise clicks
Power Low (2.5V–5V) Medium (3V–5V) High (up to 100V)
Control Analog (voltage varies speed) Digital (on/off at resonance) Digital (precise pulses)
Size Small Very small Tiny
Cost $0.50–$3 $2–$8 $5–$20
Common in Game controllers, phones Smartwatches, gamepads Premium haptics

ERM motors are the easiest to get started with. They're cheap, widely available, and work with simple Arduino signals. That's what we'll use today.


What You'll Need

Here's your shopping list with affiliate links:


Why Each Component Exists

Before we wire anything, let's understand the circuit:

Why transistor, flyback diode, and external 5V?

The circuit does three things: switches the motor on/off, protects your Arduino from voltage spikes, and keeps motor noise separate from logic circuits.

Why a transistor? Arduino pins deliver 40mA max — your motor needs 75mA. The transistor acts as a switch controlled by your Arduino's signal.

Why a flyback diode? When a motor stops, it generates a voltage spike that can fry your Arduino. The diode shorts that spike safely back to the power rail.

Why external 5V? Motors are electrically noisy. Using a separate power rail keeps your Arduino's logic circuits clean.


Step 1: Identify Your Components

Fig 3: ERM Vibration Motor

ERM Vibration Motor

ERM motors look like small rectangular motors with a small weight (the eccentric mass) attached to the shaft. The weight is what creates the off-center rotation that produces vibration.

Fig 3b: ERM vs LRA vs Piezo Motor Comparison

ERM vs LRA vs Piezo motor comparison

This comparison shows the three main haptic actuator types side by side. Notice the size difference and the different mechanical designs.

Fig 3c: PN2222 NPN Transistor

PN2222 NPN Transistor (TO-92 package)

The PN2222 is a small transistor in a TO-92 package — the same shape as a small beetle with three legs. When you hold it with the flat face toward you, the legs go left-to-right: Collector — Base — Emitter.

Fig 3d: 1N4148 Switching Diode

1N4148 Switching Diode (DO-35 glass package)

The 1N4148 is a small glass-bodied diode with a black band on one end. This band marks the cathode (negative side). The band MUST face toward +5V in your circuit.

Most common mistake: Installing the diode backwards. If your motor buzzes instead of tapping crisply, check the diode direction first.

Fig 3e: 330 Ohm Resistor

330 Ohm Resistor (Orange-Orange-Brown color bands)

This resistor limits the current flowing into the PN2222's base, protecting your Arduino pin. Identify it by its color bands: Orange — Orange — Brown (3, 3, times 10 = 330 Ohm).


Step 2: Assemble the Circuit

Fig 10: Half-Size Breadboard with Arduino Nano

Half-size breadboard with Arduino Nano mounted

Place your Arduino Nano so it straddles the center channel of the breadboard. The USB connector faces up.

Fig 6: Complete Breadboard Wiring

Breadboard wiring diagram

Here's the complete wiring. Follow each wire from the list below:

Power rails (top and bottom rows):

  • Breadboard + rail (red) to Arduino 5V
  • Breadboard - rail (blue) to Arduino GND

Motor control circuit:

  • Arduino Pin D9 to 330 Ohm resistor to PN2222 Base (middle leg)
  • Arduino GND to PN2222 Emitter (right leg, with flat face toward you)
  • PN2222 Collector (left leg) to ERM motor lead
  • ERM motor other lead to External +5V
  • 1N4148 Cathode (band end) to External +5V
  • 1N4148 Anode to PN2222 Collector

Fig 8: Complete Circuit Schematic

Complete circuit diagram

For a cleaner view of the circuit, here's the schematic:


Step 3: Write the Code

Connect your Arduino Nano to your computer via USB. Open Arduino IDE and upload this sketch:

const int HAPTIC_PIN = 9;
const int PUSH_BUTTON = 2;

void setup() {
  pinMode(HAPTIC_PIN, OUTPUT);
  pinMode(PUSH_BUTTON, INPUT_PULLUP);
  Serial.begin(9600);
  Serial.println("Haptic Feedback Ready");
}

void loop() {
  // Read button (pressed = LOW because INPUT_PULLUP)
  if (digitalRead(PUSH_BUTTON) == LOW) {
    tap(HAPTIC_PIN, 100);        // 100ms burst
    delay(200);
    tap(HAPTIC_PIN, 50);         // first tap
    delay(100);
    tap(HAPTIC_PIN, 50);         // second tap
    delay(500);
  }
  heartbeat(HAPTIC_PIN, 2.0);   // 2-second cycle
}

void tap(int pin, int duration) {
  digitalWrite(pin, HIGH);
  delay(duration);
  digitalWrite(pin, LOW);
}

void heartbeat(int pin, float seconds) {
  for (int i = 0; i <= 255; i += 15) {
    analogWrite(pin, i);
    delay(seconds * 1000 / 34);
  }
  analogWrite(pin, 0);
  delay(seconds * 1000);
}
Enter fullscreen mode Exit fullscreen mode

Predicted Q&A

Q: My motor is buzzing instead of vibrating smoothly. What's wrong?
A: Check your flyback diode direction. The black band must face +5V. Also try a different 5V power source — USB power can be under-voltage if your laptop is charging.

Q: Can I use a different transistor?
A: Yes — any NPN transistor that handles 100mA+ will work. The 2N2222 is a direct substitute. Avoid PNP transistors for this circuit.

Q: The motor runs even when I don't want it to.
A: Your Arduino pin might be floating during startup. Add this to your setup:
pinMode(HAPTIC_PIN, OUTPUT);
digitalWrite(HAPTIC_PIN, LOW);

Q: Can I control multiple motors with one Arduino?
A: Yes — each motor needs its own transistor and flyback diode on a separate pin. The Arduino Nano has 19 pins capable of PWM, so you can control up to 19 motors independently.

Q: How do I make the vibration stronger?
A: ERM motors run at higher voltage produce stronger vibration. You can use 5V logic from Arduino but power the motor from a separate 5V supply up to its rated voltage.


What You Just Built

You now have a working haptic feedback circuit. You understand:

  • Why an ERM motor vibrates (eccentric rotating mass)
  • Why you need a transistor (Arduino can't source enough current)
  • Why you need a flyback diode (protection against voltage spikes)
  • How to control vibration patterns programmatically

This is the foundation of every game controller, smartwatch notification, and tactile interface you have ever felt.


What's Next?

Now that you have the ability to make things feel, the real question is: what should they feel like, and when?

That's the question the full course answers — going deeper into haptic design patterns, motor selection logic, and integrating haptics into complete interactive systems.

Get the full course on Whop: https://whop.com/checkout/plan_ltsCZE0HeWEUl

The first 50 students get 40 percent off. See you on the other side.


All components linked are the same ones used in this tutorial. Affiliate links help support more projects like this.

Top comments (0)