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.

If you are wanting to differentiate single bumps from vibrations you may also be interested in this blog I did on an Arduino sketch that can be used to avoid false positives. You may also want to look at my subsequent blog on how to use these in an open door or tailgate down sensor which also uses a Reed switch.

If you are interested in how this type of sensor can be integrated into a broader solution that includes notification of detected vibration on a users Android phone see Detect Intrusion with Passive Infrared, Sound, or Vibration


  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!

  3. Found the updated schematic. Thanks. I see you left off the 100k pot voltage divider on the "-" input of the second op-amp. Was that deliberate, or a mistake? Shouldn't it at least be tied to ground?

    BTW, I am having a hard time getting stable results from this circuit. I get lots of spurious readings, plus the trigger is sometimes late. It seems like the results are much worse if I use long (~3 M) leads between the circuit and the piezo element. Is the amplifier strong enough to pick up electromagnetic interference from the leads, or sensitive to the extra impedance from the longer leads? Would I have better luck using twisted pair or shielded wire? I don't have an easy source of earth ground, so shielded wire would probably be less than ideal. I'd have to ground the shielding to the power supply ground, or cobble together an earth ground from a mains plug.

  4. Good catch. Updated. Definitely need the pot on the comparator negative input as this is how to adjust the sensitivity. Regarding the stability, your amplifier may well be picking up noise. Try adjusting the pot on the comparator under normal conditions (no vibration) from the one extreme where you have a consistent high output to just after you see a low output from the comparator. This will effectively raise the pot voltage level (negative input) of the comparator threshold just above the noise level. Then try vibrating the sensor to ensure it triggers reliably. Let us know how it goes.

  5. Also noticed there was an error in the original schematic. The piezo shouldn't be connected to the 5V power. I have updated in both schematics above.

  6. I just figured that out. The piezo being wired to 5V prevented the circuit from working properly. I was digging around on the circuit, trying to figure out why it didn't work when I noticed that the input to the first op-amp was always 5V. When I disconnected the piezo from the 5V rail, it suddenly started working.

    BTW, the zeners I bought are 5.2V, not 5.1V. Will that extra 0.1 V present any problems to the op amp? I'm guessing not, but wanted to be sure...

    1. This comment has been removed by the author.

    2. This comment has been removed by the author.

    3. I checked the datasheet for the LM358 and it will take an input voltage of up to 32V so 5.2V zener should be fine.

    4. Good day sir, can I asked what is the name of that blue thing that was on your prototyping picture.?

    5. Hi Charlot, I think you are referring to the 100k potentiometer. On the photo of the prototype it has a gold screw that is used to adjust the comparator threshold voltage that is in turn used with the comparator to trigger a vibration detection. This effectively gives you control of the sensitivity of the vibration detector.

  7. Hi was trying the last two days to get that System working. But no luck!
    I have a few questions:
    - Im using the LDT0_028K Piezo from Sparkfuns. A knock causes a Peak of about 50mV. Amplifing this Signal with 221 means you get 11V on the Output?
    -When I measure my running circuit with the oscillator it Show mit on the Output of the amplifier always about 4.5V. I did simulate it with LTSpice and its the same.
    -My OPamps have 5V on Vcc and Ground on the other side?
    Pls help this is part of my bachelorthesis: Im planning to send that Signal with an Xbee wirelessly to my Computer. Is it possible that the Piezo Peak could be to short for Xbee modules?

    1. Output voltage on opamp will not go higher than its supply voltage, and usually a bit less so 4.5V makes sense. Make sure your piezo is not connected to the 5V supply rail (see above correction to schematic). I also recommend reduce your opamp feedabck resistor to 160k and add the DC decoupler as shown at the end of my blog and in updated schematic. Let us know how it goes.

  8. David,

    I'm triggering my flash directly from the circuit (well, through an opto-isolator) in order to avoid the latency from the Arduino. However, that means that if the circuit generates multiple pulses, and the flash is triggered on low power, the flash fires more than once. I am seeing multiple flash exposures on many of my balloon popping pics. There is a circuit in the CMOS cookbook section on op-ams that uses an op-amp and a capacitor to create a longer on pulse (Basically turning the op-amp into a monostable. Would that be possible as a mod to your circuit, while still giving fast response time?

    1. I'd try putting a regular diode on output of first opamp and then connect the output of this diode to a small capacitor in parallel with a large resistor eg 1M which both go to ground. You will have to experiment with capacitor value eg 0.1uF or less. The output of the first opamp will charge through the diode the capacitor which will then slowly discharge through the 1M resistor. This will hold the input to the comparator high longer to avoid multiple rapid pulses on the output from your comparator.

    2. David,

      Would that modification increase the latency of the circuit significantly? I want a circuit that responds as fast as possible, and ideally within a microsecond.

    3. The capacitor will have some charge time. Reducing the capacitor will lower the response time. In this case you'd also need to increase the resistor in parallel with it to ensure the capacitor doesn't discharge too quickly. It will require some experimentation. If this approach doesn't work for your application I suggest have a look at logic approaches to debouncing such as the SR latch at Let us know how it goes.

  9. Hi David. I saw this project of yours and this will really help me alot in my next project. Would you mind talking in private or via email? I want to ask questions for the ideas that I want to add in this device. This is my email address . Hoping for your response. Thanks!!!!!

  10. David,

    any chance you have some logged continuous data for a few seconds, or an oscilloscope trace of the signal?

  11. I don't. However, the output from the comparator is a square pulse. I also don't see a lot of bouncing. Have a look at the more recent blog I did on how to avoid false positives. It essentially counts the square pulses. On a typical bump it will count only one pulse. Have fun

  12. David, Thanks for this. I made it and it works but I have one thing that doesn't seem right. When I adjust the pot only the middle half of the pot is a valid adjustment. The last quarter is always sensing (constant beep or led on constant) and the first quarter is no sensing even if I thump the piezo directly. Is this normal?

  13. Hi, can this be used to build a 3- axis vibration sensor?

  14. hello sir,

    how to make a piezo element with the fishing weight glued on with epoxy for added sensitivity?

  15. This looks great! I wonder whether you could adapt this just to light an LED instead of a buzzer? (I'm new to arduino and not great at it.) The code would be really helpful if you have time spare.

  16. Thank you for sharing this! I was successful in making this circuit to improve my own but working on a more refined range and sequence of vibrations frequencies.

  17. Hi,
    Can you please help me out , i am planning to buy this kit from amazon ,I wanted to know that this kit can also detect or grasp the ground vibrations else it would only work for sound vibrations.

    Ground vibrations means I stay in condominium at 3 floor, if some one runs / any car moves i need to get a alert .Does this kit supports .

    Thanks in advance.

  18. Hi. I have built both circuits and uploaded your sketch, but the LED I used to replace buzzer comes on without any stimuli to piezo. Even more intersting, if I completely disconnect circuit from the Arduino and place my finger near to the digital pin 8, the LED will illuminate. Seems the sketch makes the pin super sensitive to the smallest voltage. Any ideas.