How to Wire a Piezo as an Impact Sensor

Thanks for that schematic, Paul. I think I understand 'clamping diodes' better now.

That may be beyond me for this project. I'm already in over my head, and if I can reach a good way to do the wiring, and to understand why, that's great for this step.

On that note...

How can it be done well without the 100K:100K divider? I don't have one, and I need to start building this. I'm sure to need a lot of time for problem solving the code. Once I get through this project, I'll be curious to learn about the role of dividers.

If I need to do the approach that Paul posted, but when I picture doing the wiring, I'm a bit intimidated. I can do it, but if there's a workable method without the two four-junction links between the resistors and diodes, that'd sure help.

Will this work? Meaning, will it protect the Arduino while still registering impact on the piezo?

If not, can it be improved with a more direct approach than the schematic from post 19?

That's great - thank you! If that's enough to read the piezo signal while protecting the Arudino, I'll get working on it.

To help improve my understanding,

  • What's the purpose of the VCC link (to 5v)? The vibration the piezo provides energy, so is the 5v link to power the signal to the Arduino? Does the A0 pin not provide any power?
  • Is the 1M resistor in parallel there to make the piezo less sensitive to vibrations across the room?
  • What's the problem with the plans that included zener diodes? I see that they provide no protection when the Arduino is off, but it looked like the 5.1V was also not a good choice? Post #12 gives some info, but the article linked in post #15 sure makes it sound like a 5.1V zener is a good way to limit directional voltage to that amount. What more should I know?
  • Without the 100K to ground, what would this circuit fail to do? I get how the 100K to the VCC helps protect it, and I'd like to see why to include the one to ground.

Nothing to do with power.
It moves the piezo mid-voltage, about 2.5volt. So the A/D can catch positive peaks as well as negative peaks. This makes the circuit fast and sensitive. You might not need that sensitivity for what you're doing.

The resistors limit current, so the two clamping diodes that are already inside the Arduino can't be overloaded. Like the 10k that is used in the diagram in post#21.
That diagram should be good enough for what you're doing.
Don't overthink it.
Leo..

No, the piezo is actually a capacitor, so there is no other DC path to actually determine the voltage on the analog input. However with a 1M plus 50k in series, you may have some difficulties with repeatedly reading the analog input.

The article linked in post #15 may be rather misleading. If you actually examine the curves given, you will seen that the Zener conduction is anything but sharp; it has very significant internal resistance. To use Zeners as a voltage reference you must arrange to operate them at a constant current (not to mention temperature compensation).

This is why diodes - even not Schottky - to ground and the supply rail are the proper approach. For a digital input where you only need to reasonably exceed a Vcc/2 threshold, a 3.7 V Zener would be appropriate but this would interfere with analog measurements.

As explained by Wawa, nothing to do with protection as such, but setting a resting value from which the ADC can detect changes of either polarity.

Thanks, Leo, Paul. I'm ready to work with that setup, but I'm worried that I misunderstood the schematic.


It looks like there's a line running from 5v to ground, with only the two 100k resistors between it.

  • Is that right?
  • Is that ok?

I've got it laid out on the breadboard like this:
IMG_5029

That's 100K Ohm resistor linking power to

  1. another 100K, which goes to GND
  2. Leg 2

Leg 2 goes to

  1. 1M
  2. Piezo +

The 1M goes to Piezo -, which together link to A0.

Is that right, or do I need corrections?

I guess the black wire goes to the brass plate and the red wire to the white ceramic.

I said to connect the brass to the voltage divider (the 100k resistors),
so swap the piezo wires.

I guess the white wire goes to the Arduino A/D pin (which is ok).
Leo..

Since the piezo is not polarised, one might wonder why? :astonished:

(Yes, I know why I automatically would ,,,)

That's right.

Thanks.

I read every post here, but some statements become clear with explanation. I saw the whole piezo as a 'brass disk,' but now I see the earlier statement meant to connect the brass side - not the white ceramic - to the 100K pair. I'll do that and get it running today.

Accurately following instructions.
Leo..

Wow.

There's a scene in Mr Holland's Opus where Mr. Holland complains about a student who isn't learning his lessons, despite putting in effort. A fellow teacher notes that if Mr. Holland can't teach a willing student, he needs to turn his critical eye on his teaching, not his student.

There is a saying in Dutch.
"wie duidelijk leest, verstaat het meest."

Some (untested) sample code

const byte piezoPin = A0, ledPin = 13;
int rawValue, maxValue, minValue = 1023;
const int samples = 250;
const int threshold = 100; // sensitivity

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  maxValue = 0; // reset
  minValue = 1023; // reset
  for (int i = 0; i < samples; i++) {
    rawValue = analogRead(piezoPin);
    if (rawValue < minValue) minValue = rawValue;
    if (rawValue > maxValue) maxValue = rawValue;
  }
  if (maxValue - minValue > threshold) {
    Serial.println("Bingo...");
    digitalWrite(ledPin, HIGH);
    delay(1000); // to see LED
    digitalWrite(ledPin, LOW);
  }
}

This one up to 30V = +15 and - 15V, so you need 5V zener and 2.5V bias.
images

and 30V across 1Meg ?

That's the piezo I'm using and the schematic that seems closest to getting consensus among the the competing arguments. See above about the skepticism of applying zeners here.

Would you suggest one of the previously posted plans, or something different?

I've been appreciative about suggestions here and diligent in trying to understand them. I read every post in the thread and think about each before responding.

But as a newcomer, I'll naturally misunderstand some directions when they're given with sparse explanation. And like anyone learning, I may need some concepts explained a different way before fully grasping them.

Enough on that and back to the project. Your code looks a lot like what I've come up with, along with values that seem to work. If there's anything I should do to refine the code for this, I'd be glad to.

// these constants won't change:
const int knockSensor = A0; // the piezo is connected to analog pin 0
const int threshold = 550;  // threshold value to decide when the detected sound is a knock or not
const int threshold2 = 470; 

// these variables will change:
int sensorReading = 0;      // variable to store the value read from the sensor pin

void setup() {
  Serial.begin(9600);       // use the serial port
}

void loop() {
  // read the sensor and store it in the variable sensorReading:
  sensorReading = analogRead(knockSensor);
     Serial.print("Sensor Reading = ");
    Serial.println(sensorReading);

  // if the sensor reading is greater than the threshold:
  if (sensorReading >= threshold || sensorReading <= threshold2) {
    // send the string "Target hit!" back to the computer, followed by newline
    Serial.println("Target hit!");
   
  }
  delay(100);  // delay to avoid overloading the serial port buffer
}

The sensor readings are more fiddly than I expected, with 'hits' (for now, I'm tapping the piezo) returning values just outside the threshold limits. I've kept those limits as narrow as the range of values returned when I'm not tapping the piezo.

I'm building the target now, and if I can get that to work, I'll mark this as 'Solved' with Leo's post from #22, unless another post makes more sense. I'll also add notes that may help any other newcomer hoping to do a similar project.

I read that, according to that statement voltage +5.1V will go up to 9V when arduino power is off = strange.


I would use this circuit, connect piezo to ground and " AC input" and zener parallel to R2

Tom, I appreciate the help, but I'm really new, and I'm not sure how to read your suggestions. Can you please help with these questions?

  • 'Strange' that the voltage will go up to 9v, or 'strange' to read that someone claims it would do so?
  • Is the first schematic showing you should expect up to 9V in with that arrangement?

And can you help me understand the second, suggested schematic? I get the R2 to ground and the R1 to VCC, but the horizontal leg is less clear to me.

  • There's a capacitor, even though the piezo is also a capacitor?
  • the AC inputs on both sides correspond to the two wires of the piezo? One gets wired to the capacitor, and the other to A0 and VCC - with no resistor - and both join the line with resistors R1 and R2?

No you don't.
It's all about current, and there is very little of it.
100volt or more across the piezo couldn't damage the Arduino pin.
Leo..

Strange to me too. Where did you read that nonsense.
Voltage on the Arduino supply = 0volt when off, or at least close to it.

It is always assumed that max pin voltage is 5volt, which it is not.
Leo..

Only one reading every 120 100ms is poor coding.
You could easily miss an event.
Leo..

On A0 max voltage will be 5V regardless arduino power is on or off, even if across piezo is 100V.