3

I'm working on a project that uses an Arduino Uno to listen for a bell ring and then uploads to a web server the exact time the bell was rung using a WiFi Shield.

I want to know how I can listen for the bell ring (a three second long high pitch tone) and be able to detect that that's what the Arduino heard. I think the best way may be to pre-record the sound and then the Arduino will constantly try to match the incoming sounds to the prerecorded sound. I'm wondering how I could go about doing this (or are there better methods).

The bell sounds kind of like this: bell sound

  • 1
    I would suggest a sound detector module and a timer to measure the length of the sound. If the duration is predictable this might be enough to discriminate from random sounds. Or if the bell is electronic, can you get access to the output wires and just detect a voltage? – DaveP Feb 22 '15 at 7:25
  • I can't get access to the output wires, but I can place the detector within about 10 feet of the bell. Then I can listen for a certain volume level and once it reaches that level, i'll see if the duration remains for three seconds. This wouldn't be fool proof because there's background noise but it may work. – Ben Feb 22 '15 at 15:59
3

About the simplest starting point is to use an FFT (fast Fourier transform) library (like ArduinoFFT at openmusiclabs.com) to characterize the spectrum of an audio stream.

[Edit: An alternative method (digital bandpass filter) is mentioned below.]

Audio typically is made up of many frequencies of many amplitudes and phases, mixed together. FFT sorts some of that out; it estimates the amplitudes of the various frequencies that make up a bit of audio.

The general idea is to use an Arduino ADC to take readings of an audio voltage for a fraction of a second, then use FFT to convert the large set of readings to a small set of numbers, in eg a set of 32 or 64 frequency-bins, to represent amplitudes in given frequency ranges. For example, if the sound during a sample is a mix of five sine waves at five frequencies, the bins those five frequencies are in should have large numbers assigned, while other bins should have small numbers.

The approach would amount to sampling at 10KHz for 0.1 second or so, computing an FFT with 32, 64, etc. bins in the next 0.1 second, and comparing bin counts to a training pattern. Whenever bin count patterns match reasonably well, start a three-second timer; if several seconds of matching samples occur, declare a match.

If the bell is electronically generated and mostly a mix of pure sine waves, then its sound will have an easily recognized spectrum. But if the sound source is buzzy and there is background noise, it may be difficult to compare spectra. See eg
Comparing an audio signal with a previous 'taught/profiled' signal
How do I compare chords played on a guitar with a known sample?
How do I compare 2 audio files, returning a percentage of difference
What does the phase of a FFT bin of an audio signal represent?
Sound pattern matching using Fast Fourier Transform in Windows Phone
How do I go about detecting whistles, pops and other sounds in live audio input?
The Frequency Domain Section 3.4: The DFT, FFT, and IFFT

An alternative: digital bandpass filter

Digital bandpass filters are based on processing a signal in a way that detects the amplitude of the signal's frequency component within designated limits.

For theoretical background see wikipedia's Digital filter article. Also see Vaseghi, Chapter 5, Digital Filters, (eg section 4.6.6, Design of Band-Pass FIR Filters) pdf file and ECE438 digital filter design lecture notes pdf file.

You can use MatLab or Octave to do most of the work of designing a filter. For example, if you have the Signal package installed and loaded into Octave, commands like

v=cl2bp(30, 0.48*pi, 0.52*pi, [0.02, 1.02, 0.02], [-0.02, 0.98, -0.02], 2^11);
freqz(v);
v

will compute coefficients for a Constrained L2 bandpass FIR filter, plot the freqency response (as below), and display the 60 coefficients. To use the filter, copy the 30 non-zero coefficients into a program, set up a rolling array of readings, and at each sample compute a new filtered value. If at some point high filtered values occur, and if they recur for about three seconds at the bell's frequency or twice its frequency, then the bell is ringing. Note, there are other kinds of bandpass filters; the Constrained L2 bandpass FIR filter is shown for convenience, but other kinds may be better.

Octave graph of freqz

If you are unfamiliar with signal processing, you might need to try the following approach:
1, On your development system, obtain a few seconds of audio to use for tests. (Eg, allocate two buffers of several dozen bytes each; fill one buffer while using the other buffer to send data from the Uno to your development system. Use (eg) Serial.write(buf, len) and a high data rate, eg 115200 bps, to send binary data, with three ADC readings packed per four bytes.)
2, Use Octave or similar software to try out several different FFT or filter approaches. You would use FFT to determine the bell's fundamental frequency and then could try out digital bandpass filters while developing a recognizer. You can also use mkfilter to design filters to try out in C programs on your system, and should be able to iterate more quickly while developing your approach than if you were developing it using the Uno. When you get satisfactory results on your development system, you then can code a sketch to test the technique on your Uno.

Note, for a given filter order, filters implemented using fixed-point integer arithmetic on an Uno can handle more samples per second than those implemented using floating arithmetic. An Uno might support 50000 to 100000 floating multiplies and adds per second (1,2,3,4), vs. two to four times as many fixed-point operations per second. If your filter uses a dozen floating point ops per sample, your sample rate probably would have to be under 5000 samples per second. If it uses half as many floating ops or uses fixed point instead of floating point, your sample rate could be twice as much.

  • This is likely too involved an approach for the limited memory and computational resources of an Uno. Unless the algorithm can be substantially simplified, it is likely the wrong platform for the job. – Chris Stratton Feb 21 '15 at 7:20
  • @ChrisStratton, I don't see Uno mentioned in question. Also don't know that Uno is too limited for FFT. But if so, consider an ATmega2560 Arduino board. However, I plan to mention an alternate method. – James Waldby - jwpat7 Feb 21 '15 at 20:52
  • @jwpat7 I will be using an Arduino Uno as it's the only one I have. The bell sounds kind of like this sound. Does that mean your second method will work better? Furthermore, would I need to figure out the frequency of the bell and then use the digital bandpass filter on the incomming sound to check for a match? – Ben Feb 22 '15 at 0:04
  • Ben, I added some paragraphs about development methods at the end, that may help you figure out answers to those questions. – James Waldby - jwpat7 Feb 22 '15 at 7:04
  • @Chris Stratton's comment is on the mark. This would be a job for a DSP, not an Arduino. – DaveP Feb 22 '15 at 7:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.