I’m trying to calculate the speed of a shock wave through steel due to an impact. I was wondering if I used an Arduino uno with piezo sensors (SEN-10293) spaced about a foot apart would a simple time stamp of when the shock first arrived at each sensor be accurate enough to calculate speed? I’ve used time stamps in the past but never needed this much accuracy. I’m worried that even at a foot apart the two sensors time stamps may have inaccurate or even the same value.
The analog-digital converter (ADC) on the Arduino, as configured by default, takes (nominally) 104 microseconds to complete. This conversion is what lets you record the voltage from the piezo sensor. This means that your sensor will only be sampled every 100us (roughly), and so your event time will only be accurate to this scale.
Even more difficult is the fact that the Arduino can only convert one channel at a time. This means that each channel will only be sampled every 200us, and the two channels will be sampled out of phase with each other.
How fast are your shock waves moving (roughly)? Is this much jitter going to make the measurements unusable? If so, there may be other ways to approach the problem. Let us know!
At a 1’ distance … that might be tough to get really good accuracy. As noted above using the A/D is not going to work well, you need to use the digital ports and condition the piezo output into a digital signal. Since all you want is a time, this conversion to a single bit is all you need. Depending on your test setup, 2 such detectors one foot apart might be OK, I’d have to calculate how long the code takes to run (as was done above). Let’s take a SWAG at it just to see what might be possible.
The speed of sound in steel is about 20,000 ft/sec when the wave travels longitudinally … like when you whack one end of a long rod of steel and time how long it takes to get to the other end. If you hit a plate of steel and time how long the wave takes to go from one surface point to another, then the wave propagates at about 1/2 of the 20,000 ft/sec.
So coding in assembly you might have a loop that reads the digital port that’s connected to the conditioned piezos. If a there’s a hit detected, store the loop count. When 2 hits are detected stop the loop and turn the difference in loop counts into a time interval (having measured how long the loop takes). I might prefer this over using an interrupt based method because I’m not sure what variability there is in the interrupt latency. A clock cycle on a 16 MHz Arduino is 62.5 nsec. Let me SWAG a tight loop takes 20 instructions and so the port is sampled at 800 kHz (1.25 usec). A wave on a plate of steel will take about 100 usec to go 1 ft. So there will be an error of up to 2.5% just due to the timing uncertainty. I will assume any difference in detector lag will be calibrated out.
How accurate do you need your measurement to be ? Can you place the detectors more than 1’ apart ?
It seems that this is perhaps more complicated than I was first anticipating. I didn’t expect it to sample one channel at a time which certainly lowers the accuracy. I was actually hoping to be able to place detectors less than a foot apart in order to kind of map out how the wave propagates. At the most basic though I want it to be able to handle the one foot spacing. Its really a limitation on material size.
My plan was to start with just the two sensors to get a basic program going but then to use an array hooked up to the digital I/O pins to give more detail on how the wave propagates with time.
I was always under the impression that the arduino time stamp is a value independant of location or the order of the pin giving the information. Does this mean that if I (hypothetically) had 10 sensors at the same location I would get 10 different time stamps spaced 104 microseconds apart?
Mee n Mac mentioned calibrating out detector lag. Is that simple subtraction of the 104 microseconds from the seconds channels value? And if a third sensor was in place would it then have 208 microseconds subtracted? And is this still with respect to the time stamp arduino assigns?
Finally with respect to the accuracy desired I am only looking for the ability to resolve the wave within 1 inch. And so following mee n mac’s 20,00ft/sec I would need the sensing accuracy to be within 4.16 microseconds?
Again thanks for the help. This is my first time using Arduino outside of robotics and so its the first time I’ve had to worry about the speed of things this much.
A digital port is 8 pins. When you read the port, you get 8 detectors at the same time by my concept. More detectors would mean another 1.25 usec wait, assuming my SWAG at timing is anywhere near correct. More and more detectors would no doubt add to that time. I can think of a method where an arbitrarily large number of detectors would be sampled all the same time but that would mean adding hardware, to be controlled and read by the Arduino. Basically you’re talking about an “N” channel logic analyzer.
As for calibrating out detector lag, that could be done I suppose but it’s the difference in lags that I was talking about. So long as all the detectors add the same amount of time, the difference btw any 2 will be just as if there was no lag. So I would set-up the experiment accordingly.
Your 4.16 usec is correct if it’s measuring the longitudinal wave, which would be the worst case.
A more detailed description of what your trying to do might get you more applicable answers.
If you are doing this for fun, cool. However the propagation of shock waves in most common materials has been well studied (beginning in the early 20th century) and is rather well understood. A quick check by Google reveals many books on the topic, including some highly specialized studies on steel. Here is a link to a 1948 publication on the propagation of shock waves in steel and lead: http://iopscience.iop.org/0959-5309/60/1/302
You might want to consider a different CPU, many ARMs give you much faster A/Ds, with conversion times of 2.5 to 5 microseconds. The multiple AD inputs still share the same converter, but they can also be tied to a DMA channel such that the conversions will always occur x microseconds apart, so without any CPU intervention you can get a stream of equally spaced in time conversions.
If the piezo output can be converted to a digital signal, then capture logic and time that to within 5-10 nanoseconds in most mid range ARMs.
First, if you really want that analog signal, you can find a faster A/D converter, or even get multiple converters. Whether this is inside the processor, or an additional component, that’s a design choice.
Second, you can use some clever gaining and circuitry to get your piezo elements to deliver digital high or low to the processor, negating the need for an ADC. Doing this, your theoretical sample rate for 8 channels is above a MHz on the Arduino.
Either way, I’ll second Mee_n_Mac’s request: Hearing about what you are trying to do and why might help surface another elegant solution!
Back when I was shooting semi-competitively (very very very loose definition) I had the idea to make a remote target for the rifle guys. The idea was a steel plate about 3’ on a side w/ piezo “mics” at each corner. A PIC collected the differences in sensed hits as I said above and then computed an X and Y distance from center of the target. It kinda worked but the sensors kept getting blown off and the divots in the plate (and IMO the lead desposited) made for different timings than the unhit plate calibrations. Since I wasn’t a rifle guy I never persued it and suggested they could go with the “air target” instead (a better concept IMO).