Bizzare Piezo Behavior

Hi guys,

I'm having a problem with what seems to be a feedback loop(?) in 2 mini (dime-sized) piezo disc transducers (link). Basically, when only 1 is connected, they work fine, but when both are connected, they exhibit weird behavior. They are both connected with the circuit prescribed in the 'knock' tutorial, and the only connection they share is that they both connect to ground. In my experience, piezos connected with that circuit will give sightly noisy readings that flutter around 75 when idle.

Anyway, here is what my piezos are doing. When both are connected, instead of giving the lightly-noisy idle readings I'm used to, they are instead buried at 1. They still respond to strikes, although they seem a bit less sensitive. Now, the REAL problem and what particularly makes me scratch my head, is that if you hit a piezo a couple times, it'll suddenly spaz out and bury itself at around 900. In this state, it still responds to strikes, but is very insensitive. I originally said 'screw it, I'll just set the hit-detection threshold above 900', but then the pads require very firm strikes to activate which isn't going to work for me. Occasionally it will leap back down to 1 after burying at 900, but there seems to be no rhyme or reason to it.

Now, if I disconnect either one of the pads from ground, the other one will stop acting weird and will behave like a piezo should. BTW, I've got other devices that use multiple (5 or more) piezos wired up in exactly the same way and have never had this problem before. However, the piezos used in those devices are larger, the size of an American 25 cent piece. Meanwhile, the piezos in this rig are about the size of a dime and are very thin. Could they potentially be the problem? I've got them connected with 1/8th watt resistors, might that matter?

Unfortunately these problematic piezos are built into a rig that is very time consuming to open up and modify, and before I go down a rabbit hole I figured maybe someone might recognize the issue I'm having.

Thanks for any guidance!

In my experience, piezos connected with that circuit will give sightly noisy readings that flutter around 75 when idle

If you have connected them with a 1Megohm resistor across, then they should give zero when idle.
Long unshielded wiring picks up hum that could give an unwanted A/D value.

Post your code.
The Arduino has only one A/D, and scans the analogue inputs one by one with a muxer.
More than one high impedance source might need pre-reading and/or averaging.
The knock sensor code is rather unreliable and insensitive.
Try this sketch.

// knock sensor/alarm
// Piezo, with 1Megohm load resistor across, connected to A0 and ground
// optional 5volt buzzer on pin 13

int threshold = 100; // alarm threshold from 1 (very sensitive) to 1022 <<<<<<<<
int alarmDuration = 100; // alarm duration in milliseconds <<<<<<<<

const byte piezoPin = A0;
int rawValue; // raw A/D readings
int piezoValue; // peak value
const byte onboardLED = 13; // onboard LED and/or buzzer

void setup() {
  analogReference(INTERNAL); // remove this line if too sensitive
  Serial.begin(9600); // serial monitor for raw piezo output
  pinMode (onboardLED, OUTPUT);

void loop() {
  // reset
  piezoValue = 0;
  // read
  for (int x = 0; x < 250; x++) { // multiple A/D readings
    rawValue = analogRead(piezoPin);
    if (rawValue > piezoValue) {
      piezoValue = rawValue; // store peaks
  // print
  if (piezoValue > 0) {
    Serial.print(F("Piezo value is "));
  // action
  if (piezoValue > threshold) {
    Serial.print(F("Knock was over the threshold of "));
    digitalWrite (onboardLED, HIGH);
    digitalWrite (onboardLED, LOW);

I guess you've solved your issue by now, but I just had exactly the same problem, and figured out how to solve it.

So the piezo knock sensor generates voltage when you knock it, and the resistor that you put in parallel to it determines how high the voltage spike is. Commonly, diagrams have 1 Megaohm resistors. It turns out, that when you generate too much voltage, your arduino might freak out (I'm using a Teensy 3.2), and then the bizarre behaviour where the idle analogRead() value goes to just under 900 happens, even if you unplug the sensor. I imagine some part of the arduino freaks out when you do it (might damage it too...).

So, to solve it, I used a smaller resistor in parallel. I'm using 50kOhm, and it works fine.