To build a reliable vibration sensor Arduino project, pair the SW-420 digital tilt and vibration module with an Arduino Nano v3 (ATmega328P). Wire the module's DO (Digital Out) pin to a hardware interrupt pin (D2), use the internal pull-up resistor, and implement an interrupt-driven debounce routine in C++ to prevent false triggers from ambient micro-resonances. The total component cost is under $8, and the build takes about 20 minutes on a breadboard.

Unlike simple polling loops that miss fast, transient knocks, hardware interrupts capture the exact moment the sensor's internal spring-mass mechanism closes the circuit. This guide covers the exact wiring, a production-ready code block, and the specific debugging steps required when cheap sensor modules misbehave on the bench.

Sensor Module Comparison: SW-420 vs Alternatives

Before soldering, it is critical to select the right transducer for your specific mechanical environment. The SW-420 is excellent for gross knock detection, but it cannot measure vibration frequency or amplitude. Here is how it compares to other common modules available in 2026.

Module / Sensor Output Type Internal Mechanism Sensitivity Adjustment Typical Price Best Use Case
SW-420 Digital (LOW on trigger) Spring-mass contact Yes (Onboard LM393 trimpot) $1.20 Knock detection, tamper alarms, drop alerts
SW-180 Digital (LOW on trigger) Omnidirectional bead No (Fixed threshold) $1.50 Tilt sensing, continuous motion detection
Piezo Disk (27mm) Analog (Voltage spike) Piezoelectric ceramic N/A (Hardware gain required) $0.80 Frequency analysis, acoustic knock patterns
MPU-6050 (IMU) Digital (I2C Bus) MEMS Accelerometer/Gyro Software (FSR configuration) $3.50 Orientation tracking, complex gesture recognition

Parts List and Pin Mapping

This build targets the Arduino Nano v3 (ATmega328P, 16MHz crystal, 5V logic). If you are using a 3.3V board like the ESP32 DevKit v1, you must use a logic level shifter on the DO pin or power the SW-420 with 3.3V (which reduces its analog comparator range and may require tweaking the trimpot).

Required Materials

  • Microcontroller: Arduino Nano v3 (ATmega328P variant, not the newer Every or RP2040 for this specific interrupt code)
  • Sensor: SW-420 Vibration Sensor Module (with LM393 comparator board)
  • Wiring: 22 AWG solid-core breadboard jumper wires
  • Mounting: Hot glue gun or M3 nylon standoffs (double-sided foam tape will dampen high-frequency vibrations and cause missed reads)
  • Tools: Small flathead or ceramic screwdriver (for the blue trimpot), digital multimeter

Pin Mapping Table

SW-420 Module Pin Arduino Nano v3 Pin Wire Color (Recommended) Notes / Configuration
VCC 5V Red Requires clean 5V. Do not use the VIN pin unless USB is unplugged.
GND GND Black Ensure common ground with the microcontroller.
DO (Digital Out) D2 Yellow D2 is INT0 on the ATmega328P. Required for hardware interrupts.
AO (Analog Out) Not Connected - AO outputs raw comparator voltage; useless for digital knock detection.
Bench Tip: The SW-420 module features a blue 10kΩ trimpot. Turning it clockwise increases the threshold (requires a harder knock), while counter-clockwise makes it hyper-sensitive. We will tune this during the testing phase.

Step-by-Step Wiring and Assembly

  1. De-energize the board: Unplug the Arduino Nano from the USB cable before making connections to prevent accidental shorting of the 5V rail.
  2. Connect Power: Route the red wire from the SW-420 VCC pin to the Nano's 5V pin. Route the black wire from GND to GND.
  3. Connect the Signal: Connect the yellow wire from the SW-420 DO pin to the Nano's D2 pin. Do not use D4 or D5; they do not support external hardware interrupts on the ATmega328P.
  4. Mount the Sensor: Apply a small dab of hot glue to the bottom of the SW-420 PCB and press it firmly against the surface you want to monitor (e.g., a door frame or a motor housing). Avoid foam tape, as the elastomer absorbs the kinetic energy before it reaches the internal spring.
  5. Verify Voltages: Plug in the USB. Use your multimeter to measure across the VCC and GND pins on the sensor module. You should read between 4.8V and 5.1V. If it reads lower, your USB cable has excessive voltage drop; swap to a shorter, thicker cable.

Interrupt-Driven C++ Code with Debounce

Polling a vibration sensor using digitalRead() inside the loop() is a rookie mistake. A sharp knock lasts only a few milliseconds, and if your loop is busy updating an LCD or sending WiFi data, you will miss the event entirely. Instead, we use a hardware interrupt. For more on how the microcontroller handles this at the register level, refer to the Arduino attachInterrupt() reference.

The code below targets the Arduino Nano v3. It uses a 50ms software debounce window to filter out the mechanical 'bounce' of the internal spring, which often registers as 4 or 5 rapid triggers from a single physical knock.

// Target Board: Arduino Nano v3 (ATmega328P, 16MHz, 5V Logic)
// Sensor: SW-420 Digital Vibration Module
// IDE: Arduino IDE 2.x or PlatformIO

#include <Arduino.h> // Required for PlatformIO; harmless in Arduino IDE

// --- Pin Definitions ---
#define SENSOR_PIN 2       // Must be D2 (INT0) or D3 (INT1) on Nano
#define LED_PIN 13         // Onboard Nano LED for visual feedback

// --- Debounce Configuration ---
const unsigned long DEBOUNCE_MS = 50; 
volatile unsigned long lastTriggerTime = 0;
volatile bool vibrationFlag = false;

// --- Interrupt Service Routine (ISR) ---
// Keep ISRs as short as possible. No Serial.print() or delay() here.
void handleVibrationISR() {
  unsigned long currentTime = millis();
  if (currentTime - lastTriggerTime > DEBOUNCE_MS) {
    lastTriggerTime = currentTime;
    vibrationFlag = true;
  }
}

void setup() {
  Serial.begin(115200);
  while (!Serial) {
    ; // Wait for serial port to connect (needed for native USB boards)
  }
  
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);
  
  // Configure sensor pin with internal pull-up resistor.
  // The SW-420 DO pin pulls LOW when vibration is detected.
  pinMode(SENSOR_PIN, INPUT_PULLUP);
  
  // Attach interrupt to trigger on FALLING edge (transition from HIGH to LOW)
  attachInterrupt(digitalPinToInterrupt(SENSOR_PIN), handleVibrationISR, FALLING);
  
  Serial.println("System Ready. Waiting for vibration events...");
}

void loop() {
  // Check if the ISR flagged a valid, debounced vibration event
  if (vibrationFlag) {
    vibrationFlag = false; // Reset flag immediately
    
    // Visual feedback
    digitalWrite(LED_PIN, HIGH);
    
    // Serial telemetry with timestamp
    Serial.print("[EVENT] Vibration detected at ");
    Serial.print(millis());
    Serial.println(" ms");
    
    // Hold LED on briefly for human visibility
    delay(100); 
    digitalWrite(LED_PIN, LOW);
  }
  
  // The main loop is free to handle other tasks (e.g., MQTT, LCD updates)
  // without missing transient vibration events.
}

Debugging: First Three Things to Check When It Fails

Cheap sensor modules from bulk marketplaces often arrive with poorly calibrated comparators or cold solder joints. If your build isn't working, follow this ranked diagnostic path before assuming the module is dead.

1. Compilation Error: 'attachInterrupt' was not declared in this scope

The Exact Error String: error: 'attachInterrupt' was not declared in this scope or error: 'digitalPinToInterrupt' was not declared in this scope.

The Cause: You are compiling in PlatformIO, VS Code, or a non-standard board manager core that does not automatically map the Arduino API macros. Alternatively, you selected a bare ATmega328P chip in the board manager instead of the 'Arduino Nano' board definition.

The Fix: Ensure #include <Arduino.h> is at the very top of your sketch. In the IDE, verify your board selection is set to 'Arduino Nano' and the processor is set to 'ATmega328P (Old Bootloader)' if you are using a cheap clone board that fails to upload.

2. Symptom: Serial Monitor Spams 'VIBRATION' Continuously

The Cause: The LM393 comparator threshold is tuned too low. The sensor is picking up ambient 50/60Hz electromagnetic hum from nearby mains wiring, or the physical mounting surface is resonating with room vibrations (like an HVAC system).

The Fix: Take a small ceramic or plastic screwdriver (metal can short the pads) and turn the blue trimpot on the module clockwise. Watch the onboard red LED. Turn it until the LED turns completely off, then back it off counter-clockwise by exactly 1/8th of a turn. Tap the surface with your knuckle; the LED should flash once per knock.

3. Symptom: Sensor Never Triggers, Even When Smacked

The Cause: Power rail failure or incorrect edge triggering. The SW-420 DO pin requires a solid 5V reference to pull high, and the internal spring requires physical momentum to break the contact.

The Fix: First, put your multimeter in continuity mode. Probe the GND pin on the sensor and the GND pin on the Nano; it should read < 1 ohm. Second, check your physical mounting. If the sensor is hanging by its jumper wires, the kinetic energy will swing the wires instead of compressing the internal spring. The PCB must be rigidly coupled to the test surface.

Safety Note: Never mount the SW-420 directly inside a mains-voltage electrical panel or on high-voltage busbars. The module lacks galvanic isolation and dielectric withstand ratings. For mains-adjacent vibration monitoring (like detecting a failing contactor), use a piezo disk coupled through an optoisolator circuit.

Extending and Simplifying the Build

Once you have the baseline knock-detection working, you can scale the project up for home automation or scale it down for low-power battery applications.

How to Simplify (Low Power / Wearables)

If you are building a battery-powered tamper alarm, drop the Serial communication entirely. Serial.begin() and the USB-to-serial converter chip on the Nano draw an additional 15-20mA of quiescent current. Switch to an ATtiny85, run the sensor directly off a 3V CR2032 coin cell (the SW-420 will operate down to 2.8V, though the LM393 comparator output swing will be reduced), and use the AVR's sleep_mode() library to wake only on the INT0 pin. This reduces standby current to microamps, yielding years of battery life.

How to Extend (IoT and Frequency Analysis)

If you need to know how hard the knock was, or its acoustic signature, the SW-420 is the wrong tool. Swap the digital module for a raw 27mm Piezo disk. As detailed in the SparkFun Piezo Vibration Sensor Hookup Guide, a piezo generates an analog voltage spike proportional to the mechanical force. To extend the build for IoT:

  1. Replace the Nano with an ESP32 DevKit v1.
  2. Wire the piezo disk to an ADC pin (e.g., GPIO34) with a 1MΩ parallel bleed resistor to prevent static charge buildup.
  3. Use the arduinoFFT library to perform a Fast Fourier Transform on the analog samples.
  4. Transmit the dominant frequency peak via MQTT to a Home Assistant dashboard, allowing you to distinguish between a 'door knock' (low frequency thud) and a 'glass break' (high frequency shatter).

By understanding the physical limitations of the spring-mass mechanism inside the SW-420 and leveraging hardware interrupts instead of software polling, you eliminate the most common failure modes in embedded vibration detection. Tune the trimpot, verify your ground continuity, and let the microcontroller's interrupt controller handle the microsecond timing.