Saturday, February 22, 2014

High Sensitivity Vibration Sensor Using Arduino

In my last post I described how to build a High Sensitivity Arduino Sound Level Detector. Another useful type of sensor to determine if something interesting is going on in the environment is a vibration sensor. In this post I use a piezo element as a raw sensor to detect vibration.

I found the raw piezo generated a very small signal. To greatly improve its sensitivity I used epoxy to glue a fishing weight to the piezo sensor. The piezo drives a load resistor of 1M in parallel with a 5.1v Zener diode just to protect the IC's against any large voltage spikes in the event of a large physical bump. I found the raw output of the piezo unsuitable for direct input to the Arduino as it is typically a very small voltage signal and needs amplification, so I amplify the signal from the piezo with a 221 gain non-inverting op-amp using one side of an LM358. I use the other side of the LM358 for a comparator. The sensitivity of the vibration sensor is controlled using a potentiometer for the threshold (negative) input into the comparator. The other (positive) input to the comparator comes from the amplifier of the piezo signal. The output of the comparator provides a direct input to Arduino Uno digital pin 8. To hear when it senses vibration I use a simple piezo buzzer driven directly from Arduino Uno pin 13. Below is the circuit diagram:

... and the breadboard circuit:

Here is the actual prototype:

... and a close up of the piezo element with the fishing weight glued on with epoxy for added sensitivity:

Here is the sketch I used on the Arduino Uno:

If you want to use this as a starting point you can copy / paste from below:


int buzzerDurationMillis = 1000;

void setup(){

void loop(){
    if(digitalRead(VIBRATION_DIGITAL_IN_PIN) == HIGH){
      digitalWrite(BUZZER_DIGITAL_OUT_PIN, HIGH);
      digitalWrite(BUZZER_DIGITAL_OUT_PIN, LOW);
Enjoy. Let me know if you make any cool improvements on this.

Note: if you notice your output locking in on state try lowering the feedback resistor of the op-amp from 220k to something lower, for example 160k.

Update: I later added a 0.1uF capacitor to connect the output from the piezo element to the input of the op-amp, also grounded on the op-amp side using a 100k resistor. This acted as a DC decoupler and effectively lowered the comparator threshold required to detect vibration.

Below is the updated circuit diagram showing the refinements for reducing the gain to avoid op-amp output lockup, and DC decoupler on the input.


  1. Hmm. My previous comment got lost.

    Thanks for an excellent post, and a handy little circuit. I added an opto-isolator to my version because I wanted to be totally sure not to send stray high voltages from the piezo into the Arduino.

    Would you mind updating your schematic to show the extra capacitor and 100k resistor? I'm a software guy, and it isn't clear to me if the cap should be in series with the piezo or bridging to ground, nor is it clear where the resistor would go.

  2. Hi Duncan, glad you found this post useful.

    The output from the comparator into Arduino can't go higher than the 5V supply voltage to the op-amp, so you may be able to save your opto-isolator. However, the piezo can generate voltages much higher than 5V which is why I use a 5.1V zener diode across it to effectively clamp the piezo high output voltage at safe levels for input to the first op-amp amplifier.

    See above for an updated schematic towards the end of my post which shows the refinements for lowering the amplifier gain and introducing a DC decoupler on its input.

    Have fun!