I’m still working on determining whether the ultrasonic rangefinder project is feasible for the freshmen in the design seminar. I don’t have the transmitters and receivers from China yet, so I’ve been looking at the burst put out by a Maxbotix rangefinder using an electret microphone and the audio preamp I built for the applied electronics class.
Today, I wrote code on the Teensy 3.1, using only the Teensyduino environment (no direct access to the K20 peripheral registers—not even using the DMAChannel interface in Teensyduino), to record a burst of 2800 16-bit samples, filter them with a simple, fixed-point, digital filter, and output the result. I set the clock speed to “48MHz optimized”, which gave me a sampling rate of about 202.68kHz. I started recording the burst when the Maxbotix rangefinder started its pulse-width output, which should be near the leading edge of the output burst, if I understand what they are doing. There may be an arbitrary delay, as long as the end of the pulse-width output has the same delay.
The filter requires only a few lines of code:
static volatile int32_t x_0, x_1, x_2; static volatile int32_t y_0, y_1, y_2; // filter parameters for biquad bandpass filter #define a0 (2) #define a1 (-1) #define a2 (1) #define gain (2) // b0= - b2= gain*a0 // b1=0 #define DELAY_XY (x_2=x_1, x_1=x_0, y_2=y_1, y_1=y_0) #define GENERAL_BANDPASS (y_0 = ((gain*a0)*(x_0-x_2) -a1*y_1 -a2*y_2)/a0, DELAY_XY)
The loop to use this code contains
x_0 = samples[i]; GENERAL_BANDPASS; Serial.print(y_0);
as well as the other printing code.
Note that the multiplies are all by ±1 or powers of 2, and all divisions are powers of 2, so that they can be very fast, even if we didn’t have multiplier hardware—though the Teensy 3.1/3.2, as a Cortex M4 processor, does have single-cycle 32-bit multiplies, so we could use coefficients that were not such nice round numbers. (The a0 parameter should remain a power of 2, since we don’t have fast division, just fast shifting.)
I picked the parameters for the filter by using the bessel function in SciPy’s signal processing library, and asking for a single biquad stage of a Bessel bandpass filter for 40kHz±20% (32kHz to 48kHz) with a sampling rate of 202.68kHz. This gave me a=[1, -0.53466721, 0.59589277], which I rounded to [1, -0.5, 0.5], and b=[0.20205361, 0, -0.20205361], which I rescaled to [2,0,-2]. A 36kHz–44kHz bandpass would have a=[1, -0.58203377, 0.77834434], which could be rounded to [1,-0.5,0.75]. I checked that the filters were stable (poles inside unit circle) and plotted the frequency response with gnuplot:
Both filters worked ok, but I thought that the simpler [2,-1,1] filter gave slightly cleaner signals, so I’ll probably teach the students that one. It will have to be as a black-box, though, as there is not time to do z-transforms and filter theory for only 3 students out of the 11 in the class.
Note that there are a second and third round trip visible for the close reflector, and a second round trip from below the table. I’m not sure what the second echo for the bounce off the ceiling is—it seems to correspond to a distance of about 72″, which is a little too close for it to be the corner reflection from the wall and ceiling (that should be around 80″).
In all three traces, there is a large direct-path signal at the beginning, which has to be ignored. Using a shorter burst of 40kHz would reduce how much of the early signal we have to ignore.
The Maxbotix transducer is being driven with ±5V, not ±3.3V, so is likely to be louder than the one the students wire up, and Maxbotix is letting the burst build up for several cycles, then ring for quite a while, which results in large signals but poor time resolution. If we use a shorter burst, and actively damp the end of it to reduce the ringing, we can get better time resolution, but the range may be limited by the signal attenuation—the echo may be too quiet to distinguish from noise.
It certainly looks like the ultrasonic rangefinder will be a doable project, though there are several parts to it: creating the driver pulse, amplifying the receiver/microphone signal, recording the amplified signal, filtering the recorded signal, and picking the times for the echoes to report as distances. Converting the times to distances requires the speed of sound, which is temperature-dependent (and, to a lesser extent, humidity-dependent). For the freshman design project, I won’t have them add a temperature and humidity sensor, though there are some nice ones on the market.