Piezo knock sensor

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
walker
 
Posts: 77
Joined: Sat Aug 04, 2012 8:40 am

Piezo knock sensor

Post by walker »

I'm using a set of piezo sensors to detect hits of ping pong balls on a plexiglas panel (target hits from a ping pong ball gun.) The sketch I'm using is moderate in size... it's almost 10k of the 32k available on my Uno. (I'm just putting that out there since it may have an impact in the sample rate on the piezo.)

I'm missing a lot of hits at the moment. And I suspect a few things:

1. I'm wondering if the speed of going through the loop in my Arduino code means that the sample I'm getting with a single read is hit or miss (no pun intended.) Maybe the read is missing the vibration or maybe its catching the vibration at the midpoint of a wave where the piezo isn't deformed. Would it make sense to take a number of samples for each read? Like... read the port three times in succession and average the results?
2. The connection to the panel at the moment is just a strip of electrical tape over the top of the sensor. I'm guessing the tape is muting the vibrations... and I believe I'll have to change this. Does anyone have a suggestion for mounting the piezo? Superglue? Mounting tape?
3. The piezo is in a corner of the plexiglas panel. The panel is clear and I want to keep the piezo as 'out of the way' as possible. Would it make sense to mount several piezos wired in parallel? Would I risk the port at all given the voltages these things can create? Maybe I would need a larger resistor across the leads?

I know using interrupts for this application would be great but I don't think I can use them since the sensors are connected to a Sparkfun MUX board. I just need more panels than I have ports. I'll likely be trying all of the ideas listed above but thought that somebody might have some experience with piezo sensors and could pass on some wisdom.

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: Piezo knock sensor

Post by adafruit_support_bill »

It might help to post your code. As you say, the speed of your polling loop is a likely cause of missing hits. Using a mux is likely another contributing factor as it will slow down your poll rate. you might consider using something like n MCP23017 port expander. It will handle interrupts: https://www.adafruit.com/products/732

User avatar
walker
 
Posts: 77
Joined: Sat Aug 04, 2012 8:40 am

Re: Piezo knock sensor

Post by walker »

I've gone ahead and ordered a few of the MCP23017 chips but now reading the data sheet I think I see a problem. The MCP23017 only provides digital ports doesn't it? That's not really going to be appropriate for reading a piezo sensor. Or am I mistaken about being able to get more than a 1 or 0 from this chip? Any ideas for alternatives?

I've done a little testing with the Sparkfun MUX board. With a stripped down sketch that only reads the piezo using an arduino port directly I can get a read just about every 20ms. But using the MUX board my reads happen every 100ms. And that's before accounting for the rest of my script. I can see that I need to do something better.

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: Piezo knock sensor

Post by adafruit_support_bill »

That's not really going to be appropriate for reading a piezo sensor
I am assuming that you code is just looking for the signal to rise above some threshold. As long as the signal from the sensor rises above the digital logic HIGH threshold (about 3v) it will register as a logic HIGH and can generate an interrupt.

User avatar
walker
 
Posts: 77
Joined: Sat Aug 04, 2012 8:40 am

Re: Piezo knock sensor

Post by walker »

Mmmm... So I suppose the threshold would be handled in hardware with the value of a resistor then? I can give that a try. I could use a trim pot to adjust.

Do you think I could make the pot common across all 24 of my piezo sensors? If I put it on the positive lead it will act more like a pull-up won't it? If I put it on the negative side it will dtw different amounts of current depending on how many piezos are activated. I'm thinking I'll need one for each piezo.

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: Piezo knock sensor

Post by adafruit_support_bill »

You will probably need to adjust it per sensor.

User avatar
walker
 
Posts: 77
Joined: Sat Aug 04, 2012 8:40 am

Re: Piezo knock sensor

Post by walker »

So, I'm struggling a bit with making this design decision. And I thought I would post my embarrassment here so that it can haunt me forever on the internet even after I've mastered the electronics of this. Right now I'm between the choice of switching to a digital mux chip that supports interrupts (as graciously suggested above) or using the analog mux board that I have and try to make the reads to it more frequent. After a lot of reading on different sites I'm beginning to think that what I really need to do is condition the output of the piezo sensors to accomodate the analog mux a little better. I found some great resources about this at the following links:

http://leucos.lstilde.org/wp/2009/06/pi ... ditioning/
http://www.ti.com/lit/an/sloa033a/sloa033a.pdf

I'm sad to say that I don't have a scope to measure what is really going on with the piezo inputs. (And frankly reading the detail in these links really shocked me considering how simply put the demo code and explanation are on the arduino.cc site.) What I can say is this... my existing code can read one sensor (and do a lot of other stuff) every 80ms. A fully stripped down script can read the piezo around every 20ms.

But even at 20ms polls on the target I'm only getting a reading from the piezo on one of the polls when there's a hit. That is to say that the piezo probably excites and settles within around 30ms. That leaves lots of time for my full script to miss lots of hits. That's with 20mm raw piezos (no casing) and a 1m resistor between the leads.

Now I think I made a rookie mistake connecting these sensors as well. Each sensor has been wired to the end of a 10' length of CAT 5 cable (one pair) with the resistor at the far end from the piezo (i.e. piezo... cable... resistor... arduino port) I'm guessing that's probably not right. I'll bet the resistor need to be close to the piezo, right? Is cable capacitance attenuating my signal a little? (Can CC really have that much of an affect at the voltages these things put out... although I know it is a very small current.)

I'm hoping that I can adjust the piezo signal to be less spikey and last longer so that I have a better chance of sensing it. I gather that a capacitor across the positive and negative leads would help adjust this... although it will attenuate the signal a bit. Or... some of the schematics I've seen show a capacitor in-line on the positive lead. Would this be better?

The scope traces on the first link above show a large negative current spike on the signal. What does the arduino ADC do with negative current? Does it just ignore it? Should I be concerned with filtering it? I assume I could put a diode across the piezo leads to handle that right? Does anyone have any hints about how to go about sizing these components? Or am I just way off?

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: Piezo knock sensor

Post by adafruit_support_mike »

Both the references you cited suggest basically the same thing that I would: catch the incoming signal in a capacitor so it sticks around long enough for you to read it. The fact that you're working with an Arduino gives you a nifty trick to make the process work better though.

The hardware is similar to what they showed in the references, but simpler:

Image

When the sensor delivers a high pulse, the current will flow through the diode and into the capacitor. The diode blocks the current from flowing back out of the cap, so the pulse ends up being trapped in the capacitor until do something else with the circuit.

The 'something else' comes from what you do with the input pin, and its properties when you tell the microcontroller to do different things. The code you want is:

Code: Select all

const int inputPin = 7;   //  or whatever

void loop () {
    if (digitalRead( inputPin )) {
        //  we got a hit
    } else {
        //  nothing
    }
    pinMode( inputPin, OUTPUT );
    digitalWrite( inputPin, LOW );
    pinMode( inputPin, INPUT );
}
When an I/O pin on the Arduino is in INPUT mode, it has a very high impedance. Any signal trapped in the capacitor will take a long time to decay. When you change the pin to OUTPUT mode, its impedance drops to almost nothing, so writing a LOW signal to the pin will drain any signal trapped in the cap almost instantly. Setting the pin back to INPUT mode traps that low value in the cap until the next polling period, or until the next signal arrives from the sensor.

User avatar
walker
 
Posts: 77
Joined: Sat Aug 04, 2012 8:40 am

Re: Piezo knock sensor

Post by walker »

Ah! Brilliant! That is exactly what I'm looking for. It's simple and (at least sounds like) it will work well.

I don't suppose you have any suggestions for appropriate values of the diode and cap? I have some 1N914's lying around and from the datasheet I see they're rated for 75v peak reverse current. I also have some 1N4004's. They're rated for 400v peak reverse current.

I have a few caps around as well, and I'm thinking a ceramic disc cap would fit well here. Or should I prefer an electrolytic? (Just doing a little reading it seems I should be preferring the electrolytic caps for this application... high voltage, low current.)

I'll try a few combinations tonight and see how it goes.

User avatar
walker
 
Posts: 77
Joined: Sat Aug 04, 2012 8:40 am

Re: Piezo knock sensor

Post by walker »

Wow! That circuit works great. A little too great with the first cap I tested (a .1uf electrolytic.) When I gave the target a tap the analog port value went to about 60 and took about 45 seconds to come down to 2. And that was without setting the port to output. I can tell it won't take a very big capacitor to drive this circuit. :-)

My second test was with a 1000pf ceramic and that was only slightly more sane. A light tap on the target took the analog port to 430 and it took 1.6 seconds for it to drop to 1.

I have a bit of a challenge to work out since I forgot I was using a multiplexer for the analog ports. (The board uses a TI CD74HC4067.) So I'm not sure these ports will have the same impedence effect when they are set to output as the native arduino ports. And frankly, I'm not sure it matters at this point. So long as I can get a capacitor sized to keep the port up for 150-180ms I think I'll be good to go.

I do have one worry though... I noticed if I tap the piezo successively the port value (voltage) goes up as the voltage accumulates in the capacitor and doesn't have time dissipate. I wonder if multiple hits on my targets could run the voltage up high enough to damage the port? Maybe a smaller value resistor than the 1m across the piezo leads would allow some of that voltage to bleed off to ground faster?

I do have some 5v voltage regulators but that seems like overkill for a circuit like this.

User avatar
walker
 
Posts: 77
Joined: Sat Aug 04, 2012 8:40 am

Re: Piezo knock sensor

Post by walker »

Forget about what I said about changing the resistor value. I realize now the resistor should be on the sensor side of this circuit which is on the wrong side of the diode... so curent won't flow that direction. Gotta run to the electronics store to get a few more appropriately sized caps.

User avatar
walker
 
Posts: 77
Joined: Sat Aug 04, 2012 8:40 am

Re: Piezo knock sensor

Post by walker »

After trying a few more capacitors I have decided to go with the smallest one I could find (47pf.) It dissipates in about 300ms and that is fast enough that repeated hits to the piezo won't generate more that 5v at the port. Thanks for your help! I think I learned another bit of electronics here. And now its time to cobble up a bank of targets and give it a full test.

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: Piezo knock sensor

Post by adafruit_support_mike »

The voltage across the terminals of a capacitor is proportional to the amount of charge stored in it. The official relationship is "1 Coulomb of stored charge produces 1 Volt of potential across the terminals of a 1 Farad capacitor."

In this case, the piezo sensor generates a more or less fixed amount of charge when it senses a hit. As you proved experimentally, packing that charge into a smaller capacitor will produce more voltage.

Your concern about overloading the microcontroller's pins is valid, but shouldn't be too much of a problem. IC pins get exposed to small bursts of static all the time, so vendors have learned to build over- and under-voltage protection diodes into the parts of a chip that contact the outside world. You can add one your own if you want to be absolutely sure though: put a reverse-biased diode between the top of the cap and the VCC rail.

You want the cathode to point toward the VCC rail. That way, any voltage more than .65v above VCC will forward-bias the diode and the current will flow into VCC.

User avatar
walker
 
Posts: 77
Joined: Sat Aug 04, 2012 8:40 am

Re: Piezo knock sensor

Post by walker »

Updating this thread with new developments. First of all the circuit Mike came up with works pretty well with an Arduino Uno. Using a 1n914 diode worked pretty well but I am told that a 1n4004 might be more appropriate given the current coming from the piezo. The 47pf capacitor reliably gives about 300ms of total signal... a bit less depending on how high you need to set the threshold in your sketch. Larger diodes give a longer signal.

However, the Uno only has 6 analog ports and that is not enough for me. So I'm using the Mayhew Labs MUX shield to get a total of 48 analog inputs. Unfortunately the circuit listed here tends to confuse the mux shield. The impedence difference between the piezo and the input port causes cross-talk across all of the ports (or I should say all of the ports on one of the mux chips.) For my project this means that it doesn't matter which target in my range you hit... it always registers a score.

There is a thread about this issue and potential solutions over on the Sparkfun forums here: https://forum.sparkfun.com/viewtopic.php?f=32&t=35546. There is a lot of detail there confirming the issue and modeling it in LTSpice.

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: Piezo knock sensor

Post by adafruit_support_mike »

You don't necessarily need an analog input for the diode-and-cap sensor. You also aren't tied to the cap's native discharge rate.

If you look at the sample code I posted before, it sets the pin to OUTPUT mode (low impedance) and then applies a LOW signal to the capacitor. If you disconnected the signal coming from the piezo sensors and diode, the cap would never go HIGH.

In other words, the only thing that can ever send the cap's voltage HIGH is a signal from the piezo sensor. As soon as you see that HIGH value, you know everything about the signal you need to know: it happened. You don't need to wait for the cap to discharge naturally. Just do:

Code: Select all

pinMode( inputPin, OUTPUT );
digitalWrite( inputPin, LOW );
pinMode( inputPin, INPUT );
again and make the cap ready for the next input signal. It takes far less than a millisecond to detect a signal and reset the cap for the next one.

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”