See The Sounds

Analog to Digital Signal Processing

Victor Casado

Issue 37, August 2020

This article includes additional downloadable resources.
Please log in to access.

Log in

Build this RGB LED VU meter and OLED spectrum analyser project and learn about data acquisition systems and filter design at the same time.


In this project, Victor explains what makes up a Data Acquisition System (DAS). It covers the fundamental theory of a DAS and how to use one, how to design basic filters, with some buildable prototypes to demonstrate their applications visually.

We're going to focus on application with audio signals, however, the same theory can be applied to most waveforms.


You may be all familiar with the analogRead() command on an Arduino, but have you wondered how a “real world” data acquisition system (DAS) is structured, how to design one for a specific purpose, and how to implement an end-to-end system?

This project will give you a practical understanding of the building blocks of a basic DAS and how to make all of them work together.

We will cover some basic filter designs and how you can calculate them manually, and then using online tools.

Finally, you can see the filters in action by building either the spectrum analyser or VU meter projects.


A data acquisition system can be used to convert all sorts of real world inputs, into a more sanitised signal that's compatible with the logic level of your Analogue to Digital Converter (ADC).

The basic structure of a DAS may vary based on application, but generally will be comprised of four main parts.

  1. First Filter;
  2. Amplifier;
  3. Second Filter;
  4. Analogue to Digital Converter (ADC).

First Filter - band pass

The first filter is used to suppress any unwanted noise from the input signal. For lack of better phrase, its job is to "clean up" the signal.

In the case of audio signals which can contain many different frequencies, it is often a Band Pass filter.

Band pass filters are essentially gatekeepers. They'll let certain frequencies through, while rejecting others.

The band pass filter can be built for different frequencies using parameters that we will review shortly.


While not essential in all cases, the amplifier is used to “adapt” the signal from the input signal amplitude ranges to the input amplitude needed by the ADC in the system.

For example, a mobile phone audio output has more or less a 1.5V maximum amplitude at the headphones jack, and if you want to use a 5V max ADC to get the maximum performance and resolution, you have to amplify the signal.

The parameter that we are going to look for here is the Voltage Gain (not current, because we are only interested in voltage that carries the information of the signal, not the power of it).

Second Filter - Anti-aliasing

This filter is also known as an Anti-aliasing Filter (AAF). The job of the AAF is to further condition the signal to approximately or completely satisfy the Nyquist-Shannon sampling theorem for the frequencies we're interested in.

The adjustable parameter here is the cut off frequency. We will go into this and the Nyquist-Shannon sampling theorem in more detail later in the project.

Analogue to digital converter (ADC)

An ADC will “translate” the input analog signal to quantified digital values. There are many different resolutions for ADC.

The parameters that we are going to look for are, number of channels, input modes (single or differential), max input voltage amplitude, resolution (bits), sampling rate (samples/second), and the digital interface (SPI, I2C).

The filters are implemented usually with operational amplifiers (Op-Amps), but can also be designed with transistors (we are always going to use active filters).

The amplification stage, for low and medium power (max 50-70W), we are going to use Power Operational Amplifiers. For high power, we will use transistor-based amplifiers (internally, the power op-amps are transistor-based).

For this project, the Analog to Digital Converter (ADC) that we will use an MCP3008, which is an 8 channel IC with single/differential (can be configured as required), 5V, 10 bits, 200ksps, and SPI. You can learn more about this IC in our Classroom article from Issue 30.

The basic structure of a DAS


We are going to build a DAS for audio purposes that has a bandwidth of 20kHz approx. This bandwidth is almost in baseband, so to simplify the design, we are going to implement only an Active Low Pass Filter with gain, so in one simple circuit, we will have the first three stages covered.

We mentioned baseband just now, however it's important we explain what that is.

Baseband is the concept of having our signals near to frequency zero. If those signals are not at zero frequency, the spectrum of the signals must be near to zero, as audio signals are.

The circuit will take a sinusoidal audio signal at the input, composed of different audio frequencies, which we will explain in further detail shortly.

This will filter and amplify the signal with the Active Low Pass, and then we are going to send it to the ADC.

Fourier Transform

The Fourier transform is a mathematical Domain transformation that takes a signal input in the Time Domain and transforms it to the Frequency Domain. This can be a difficult concept at the beginning, but let's show you a simple example to visualise it.

If you have a basic sinusoidal wave with a frequency of 1Hz, the angular speed of it will be: ω = 2 π f = 2 π rads/s or s^-1

The representation in the Time Domain vs Frequency Domain of that signal is shown in the diagram below.

Time Domain to Frequency Domain

For example, an audio signal is a summation of sine waves that have frequency components from 20Hz to 20kHz, so the Fourier Transform of a summation of sine waves is a summation of Dirac’s Delta functions, shifted by the ω of those sine waves.

That’s why, for example, the spectrum analysers looks like the image below, with levels broken up into frequency sub-ranges.

Anti-aliasing Effect

The Anti-aliasing Effect, is a concept based on the Nyquist Theorem that says that, in order to properly recover a signal (after we digitally process it and we convert it from digital to analog), the frequency at which the signal is sampled (this is the frequency that our ADC will be getting samples of the signal), must be at least twice the maximum frequency of our signal.

For example, we know that the maximum audio frequency is 20kHz, so if we want to digitise it, process it and then we want to recover the analog signal, our sampling frequency should be at least 40kHz.

This is why the usual CD quality audio is sampled at 44,1kHz or 48kHz, but this can be greater. For example, in pro audio, the sampling frequency can be up to 192kHz (the higher the better, but more expensive too).

The Fundamental Build:

The Core DAS

Parts Required:JaycarAltronicsCore Electronics
2 x 1N4733 5.1V Zener Diodes #ZR1403Z0614CE05193
2 x 100µF 16V Electrolytic Capacitors or similarRE6130R4825CE05258
1 x 56Ω 1/2W ResistorRR0542R7728-

Parts Required:

* Quantity required, may only be sold in packs. Breadboards, prototyping hardware and an audio source with cables are also required.

# 1W Zener diodes between 5.1V to 5.6V will work

Now with a little theory behind us, we're going to build several application examples. We will create the DAS portion of the circuit as the fundamental build here, and then provide two different output options; a small screen as a spectrum analyser, and an RGB LED as a digital VU meter.

It's important to note that you don't need to worry if you don't fully understand the previous theory. There's a lot to take in there.

You can still build this project without following all the theory, however understanding what you can from the theory may help you adapt it to your own purposes too.

We have broken up the build in to various stages to assist with construction and comprehension. It's also important to note that there are two different filter options (though fairly similar)


First, we are going to design the power supply. This might surprise you, because, why not just use the 5V our Arduino provides?

Well, as the audio signal is sinusoidal, to process it, we need a symmetric supply as well. We will build a simple symmetric power supply that will be fed by 12 to 15 volts by using 5.1V to 5.5V Zener diodes.

Based on the lower current being used, 500mW Zener diodes will work fine, however, we are using the 1N4733 1W 5.1V Zeners that we had available. Seeing that we are going to have a voltage drop of 11.2V at the diodes, we recommend a minimum 12V supply.

The circuit is quite straight forward, and you can reference the schematic and fritzing diagrams. Pay close attention to the orientation of the diodes and capacitors. We have a small resistor to current limit the input too. If you have a 12V supply capable of high current such as a battery or lab supply, the Zeners can burn out.

When installing the capacitor in particular, it may feel like it's backwards as the negative side will go to the red power rail. However because it's a symmetric power supply, the current flows in reverse between the floating ground and -5V, compared to regular +5V and ground would.

If you would like to ensure everything's correct, you can apply power to the 12V inputs as indicated.

Using your multimeter, you should find 5.1V as you'd usually expect on the +5V rail. When measuring the -5V rail, still touch red lead to red rail and black lead to blue/black rail, however you should see negative 5.1V, just as you would when polarity is reversed.

If everything checks out, move on to the filter stage!


Next, we are going to design the Active Filter, which will be a very common Active Filter topology called Sallen-Key.

A second-order filter is a very good starting point, and the calculations are relatively straightforward. We will design one for a cutoff frequency of 20kHz, and as common consumer audio devices like phones have a maximum output voltage of 0.5V, we are going to set the gain to 10V/V.

This means the maximum amplitude at the output will be 5V, which is why the minimum supply must be 12V, so the supply is enough for the maximum output voltage at the Op-Amp.

One important thing to keep in mind when designing filters is their stability. They should not have a phase bigger than 180 degrees or π radians at any of the passband frequencies, so the signal is not inverted. In our filter, the 180 degrees are reached at 20kHz, which is our cutoff frequency. In our case, this is ok.

Other concepts to ensure that a filter is stable is a second-order type, which are unconditionally stable due to the maximum number of poles being two, and the maximum phase shift is 180 asymptotic.

With all that said, let’s design our Low Pass Sallen-Key filter circuit.

We are going to analyse this using the Laplace transform, which is a mathematical domain transformation used to characterise systems. It simplifies a lot of the complexity of the analysis of circuits that are not in a DC steady state.

It lets us make the analysis of transitional effects, and then if the systems are stable, we can easily obtain the frequency response of them by particularising the Laplace variable “s”( s = σ + jω). When the real part of s is equal to 0 (Re{s} = σ = 0) we obtain that s = jω (Yes, the Fourier Transform is a particularisation of the Laplace Transform).

To simplify the development of this project, we are going to give the general equations and then take a few steps to design this audio filter. You can use the equations to design more complex filters or adapt the values to your needs.


The general voltage gain Av(s) = Vo(s)/Vi(s) is:

We want to achieve something like this because it is the canonical expression of the Low Pass Filter:

So we have:

Then, we want a double pole at the cut off frequency, so we have a good stopband curve slope.

To make the design easier, R1 = R2 = R, and C3 = C4 = C, we get:

Note: The lower the resistor values, the lower the noise. Also, the bigger the capacitor values, the better. We used polyester capacitors because they have a flat response over temperature.

As we want a 20kHz cutoff, if we use 100nF capacitors, we need a theoretical resistor of 79.57 Ohms. If we use 75 Ohm or 82 Ohm resistors (commercial values) we can get cutoff frequencies of around 21.220kHz and 19.409kHz respectively. We will use 75 Ohm resistors.

To achieve a gain of 10, we are going to build a non-inverting amplifier that will be cascaded with the filter, as shown. Gain Av = 1 + Rb/Ra, so we will set Rb to 10k and Ra to 1.1k to get a gain (Av) of 10.09.

This is how you can design a basic filter, but nowadays there are lots of online tools that help us design filters.

For example, Texas Instruments provides a filter design tool that you enter the parameters that you want and it generates the design for you. We used it to obtain this fourth-order Butterworth Filter with a Stopband attenuation of -80dB.


Both approaches to filtering are acceptable, however the slightly more complex version from Texas Instruments will do a better job of attenuating (ie reducing) noise, resulting in a better sample.

Here's a few frequency graphs which demonstrate the difference in attentuation across frequencies from 1Hz to 100MHz.

second order FILTER Frequency Response

fourth order FILTER Freqency Response

As demonstrated by the frequency response curves, both filters do a great job of attenuating frequencies above around 20kHz.

However the fourth order filter has a much more significant attenuation curve when compared to the second order filter.

Both filters will do a good job of cleaning up your signal for this type of purpose, however we feel it's a worthwhile exploration and comparison when learning about and working with these different types of filters.

You may wish to experiment and review results between the two types provided, or just pick one and stick with it.

filter / amplifier builds

As we have noted previously, you will find two build options for the active filter / amplifier stage.

While we're using the same amplifiers for both circuits, the way they are integrated changes between the two, so the filter / amplifier stage is treated as one for build purposes.

Filter circuits

For our prototype, we will implement two separate circuits to demonstrate the two different filters. The first breadboard has the filter based on our calculations. The second breadboard has the Texas Instruments based filter. Both boards have the power supply, amplifier, and MCP3008 IC.

We have provided wiring diagrams to show you how to wire both circuits.

Note: We have used two TL071 Op-amps, however, if you have a TL072 Dual Op-amp or TL074 Quad Op-amp, they will work fine as well. The newer TL08X types would also be suitable.


To feed the filters with the audio signal, you need an audio jack. We have recommended “Breadboard-Friendly” type 3.5mm sockets for simple connectivity.

If you have trouble finding breadboard friendly options, you can of course solder a few jumper wires to whatever you can find and connect it appropriately. You can also optionally use a 3.5mm plug and have it connect directly to your audio source, without the need for a 3.5mm plug to plug lead.

Connect the common pin of the jack to our audio frequency (AF) GND, and the channel to the input of the filtering stage (first resistor).

Filter & Amplifier Build Option 1:

Second Order Filter

A second order filter is deemed to be 2nd order by the rolloff rate of 40dB per decade, which provides good filtering properties with only a handful of components.

ADDITIONAL Parts Required (2nd order filter):JaycarAltronicsCore Electronics
2 × LM741 Op-AmpZL3741Z2590CE07194
4 x 1nF (0.001µF) Polyester Capacitors or similarRM7010R3001BCE07195
1 x 3.5mm Audio Socket (Breadboard Friendly Where Possible) or Inline PlugPP0114P0028ADA1699
2 x 75Ω 1/4W Resistors*RR0545R7531CE07196
1 x 1.1kΩ 1/4W Resistor*RR0573R7559CE07197
1 x 10kΩ 1/4W Resistor*RR0596R7582FIT0118
2 x 100nF (0.1µF) Polyester Capacitors or similarRG5125R2736BCE05188

ADDITIONAL Parts Required (2nd order filter):

* Quantity required, may only be sold in packs. Breadboards, prototyping hardware and an audio source with cables are also required.

% 5% tolerance carbon film resistors

A 2nd order filter for applications such as our VU meter is possibly all you'll ever need, as we're not needing to be too precise.

When constructing this filter, there's little to watch out for as the connections are fairly straight forward.

Naturally the op-amp chips must be oriented correctly or they will not function. They're robust chips but as with all ICs, take care with their handling.

If you couldn't find a breadboard-friendly audio socket, take extra care with your wiring.

You want the tip to connect to the resistor, which goes to the input of the op-amp. The sleeve should connect to the ground of our symmetric power supply, which is available on either of the breadboard ground rails if you've followed our power supply wiring.

Filter & Amplifier Build Option 2:

Fourth Order Filter

ADDITIONAL Parts Required (4th order filter):JaycarAltronicsCore Electronics
2 × LM741 Op-AmpZL3741Z2590CE07194
1 x 3.5mm Audio Socket (Breadboard Friendly Where Possible) or Inline PlugPP0114P0028ADA1699
4 x 1nF (0.001µF) Polyester Capacitors or similarRM7010R3001BCE07195
1 x 1.1kΩ 1/4W Resistor*RR0573R7559CE07197
2 x 2.4kΩ 1/4W Resistors*RR0581R7567CE07198
1 x 3.3kΩ 1/4W Resistor*RR0584R7570FIT0118
1 x 4.7kΩ 1/4W Resistor*RR0588R7574FIT0118
2 x 5.6kΩ 1/4W Resistors*RR0590R7576CE07199
1 x 12kΩ 1/4W Resistor*RR0598R7584FIT0118
1 x 18kΩ 1/4W Resistor*RR0602R7588FIT0118

ADDITIONAL Parts Required (4th order filter):

* Quantity required, may only be sold in packs. Breadboards, prototyping hardware and an audio source with cables are also required.

% 5% tolerance carbon film resistors

A fourth order filter is deemed to be 4th order by a rolloff rate of -80dB per decade, which is a substantial filtering ability. The component count is still manageable though is certainly higher than our comparative 2nd order filter.

While the 2nd order option is still a good option for audio signals, a fourth order filter is useful for particularly noisy environments.

While we're allowing virtually the whole audible spectrum through, there are many applications where you may want to create a notch filter to allow say, 1kHz signals.

This is where a fourth order filter really has powerful applications, as the sampled waveform will be far more restricted than when using a second order filter.

Construction is still fairly straight forward, however see the construction notes on the second order filter if required.

ADC Build:

The MCP3008

ADDITIONAL PARTS REQUIRED (ADC):JaycarAltronicsCore Electronics
1 x Arduino Uno or Compatible BoardXC4410Z6280A000066
1 x MCP3008 ADC ICZK8868-ADA856


While there is an ADC built in to our Arduino UNO, it's not quite up to the specification we need for processing audio signals.

Why not ? The UNO runs at 16MHz - that's far more than 20kHz!!

Well yes, however that's not the maximum sampling rate of the ADC inside the UNO, that's the clock speed.

For a 10-bit ADC such as the one inside the Arduino UNO, the operating frequency is 16,000,000Hz / 128, which is the internal prescaler. This equals 125,000Hz (125kHz) for the clock speed of the ADC.

According to resources we found, conversion in the ADC takes 13 clock cycles to compute (that is, analyse the incoming analogue data and produce a digital value). 125kHz / 13 clock cycles, means it has an actual sampling rate of about 9,615 samples per second, or 9,615Hz. Let's say 10kHz because we're feeling generous.

That's a powerful tool for many applications, however human audio range is between around 20Hz and 20kHz.

If all we are sampling is subsonic bass, then you can probably just use the UNO. However we want to cover the full audio spectrum.

For this reason, we'll use the MCP3008 which has a sampling rate of up to 200,000 samples per second, or 200k samples per second.

We've already noted that you need to sample a frequency with at least twice the frequency of the sample itself. If the upper limit of our source is 20kHz (approximate human threshold), then we need to sample at 40kHz as a minimum.

200k samples per second is many times that rate, so the MCP3008 is a perfect choice for this application. It's a robust chip, which operates up to 5V, which is perfect for an Arduino environment.

It's an 8-channel ADC and provides an SPI output. We're just using one channel here.


While we have no tangible output at this point, we should have a working circuit which we can test.

All we'll achieve here is a serial output which is relatively meaningless, but it will provide you with enough information to confirm your system is working.

Power up your circuit with 12V, and connect your audio source.

We have provided Serial_Test.ino in the downloads. Open the file in your Arduino IDE and compile it to your UNO.

Now play your favourite tunes from your audio source. It might feel a little anti-climactic as there'll be no sound output. However open your serial monitor.

If you look carefully, you should see a value outputting to your serial monitor. Now pause the music. Did the value drop significantly?

Note - it may not fall to zero due to noise - this isn't generally an issue unless the value doesn't fall below 50.

If this is the case, your filter may not be performing correctly, and you should potentially re-check your wiring.

As you can see from the sample outputs, you'll get a high degree of variability from the numbers output.

That all comes down to the specific music you're playing, amplitude (volume) of the audio source, and so much more. Just as you expect a VU meter output to dance up and down with the levels, so do the numbers here in the serial output.

Now you can proceed to the display builds!

Display Option 1:

LED VU Meter

ADDITIONAL Parts Required:JaycarAltronicsCore Electronics
1m x RGB WS2812B LED strip-X3223ACOM-14015

ADDITIONAL Parts Required:

Large RGB VU meters are loads of run to play with.

Addressable LED strips are so versatile, and well suited to this purpose. Even with this basic audio sampler, you could drive metres and metres of addressable strip making huge visual displays.

Naturally, you can just have a few LEDs of strip if you're after something a little more low-key!

If you have tested your filter and amplifier circuit this far, then connecting the strip is fairly straight forward.


As we described earlier, our power supply is using small Zener diodes to provide a symmetric supply.

It's possible that with more than a few LEDs, your current demands will be more than you can reliably supply. As a guide, many WS2812 style RGB strips are around 1A per metre.

Check the specifications of your strip, but if you're running more than a few LEDs, you probably want to look at an alternative 5V power source for the strip.

This will ensure adequate current is available to your strip and you can achieve full brightness without risking damage to your symmetric power supply.

Of course, you can upgrade the Zener diodes, but it's probably much easier to find a secondary 5V source. Take care to not merge the different GND connections between the, as they are not the same and there is potential between GND and the false AF-GND we create.


There are two code options provided to run

Both examples require the "FastLed" and MCP3008 libraries installed.

You will also need to adjust the code examples for the length of strip you're using, adjust brightness (refer to our current warning also), and update the pin if you're not using pin 4 like our diagram.


The VU meter code example will read the value from channel 0 of the ADC and will represent an RGB VU-Meter with a peak hold that slides at 20ms.

In this code, we sample the audio signal using the MCP. We then proportional number of LEDs that it has to switch on based on the amplitude of the signal it has sampled. Every 30ms it recalculates the peak, and updates the LED strip accordingly.


The spectrum analyser code will read the ADC, and when the input amplitude of the signal is bigger than a threshold, it will represent a “pulse” that propagates through the RGB strip, changing the colour of the pulses every 250ms to a random colour. We need the same libraries as the VU meter example.

As with the VU meter code, we sample the signal via the MCP. When the amplitude of the signal is greater than the threshold set, it will switch on the first LED of the screen.

Then every 10ms, that LED is "shifted" to the end of the strip. Every 250ms or so, the colour is recalculated.

It's really quite a fun display output to watch, while the timing naturally falls to the beat too!

Display Option 2:

Spectrum Analyser

ADDITIONAL Parts Required:JaycarAltronicsCore Electronics
1 x SSD1306 or SH1106 OLED 128x64 Display ^XC3728-DFR0650

ADDITIONAL Parts Required:

^ Display needs to support SPI

On the opposite end of the visual scale, is our tiny OLED display.

While it's totally understated compared to our VU meters, this circuit displays the audio levels across the full spectrum, which can be totally mesmerising to watch.

Each column represents a ~2.5kHz band of frequency (2.5kHz x 128 columns is approximately 20kHz of range). This is only approximate however. There may be crosstalk between frequency ranges, however the display is visually stunning!

Be careful with the SSD1306 when applying power. The display itself is generally rated at 3.3V, however most boards will have a Vin pin which is 5V capable.

Our wiring diagram provides 5V to this Vin pin. You can optionally take 3.3V from the 3.3V pin on your Arduino and power your display from that. Just ensure you only ever provide 3.3V to the 3.3V pin if that's what you choose to do. 5V on that pin can easily cause failure of the display.


We have used the SSD1306 128 x 64 OLED display, which is SPI controlled. Some of the displays you'll find which look like this are actually SH1106 controlled displays. They're still SPI and work much the same, however the libraries are different. We've included code for both chipsets so you have more versatility in choosing a display.

Changing this display out for another SPI-capable display would be fairly achievable if you wanted a full colour display, or perhaps just something larger.

You just need to be conscious of the processing power required to drive the display, as it may reduce refresh time on the display considerably if you try and do too much.

Since the MCP chip is doing the actual Audio sampling, it wouldn't affect the quality of sampling being done, however the refresh rate on the display could be slowed.

Push this too far, and your display might not refresh quickly enough to show each beat, for example.


This code example is a spectrum analyser that uses FFT (Fast Fourier Transform) to get the amplitude of each frequency component of the signal, and represents it on an OLED display.

Note: Due to the limitations of the Arduino Uno’s clock and SPI frequencies, the sampling will be done at 3,333kHz. This isn't really a problem however, as the MCP3008 is still sampling the audio source itself at full speed.


This uses the standard SPI and Wire, ‘Adafruit GFX’, ‘Adafruit SSD1306’, ‘MCP3008’, ‘fix_fft’ libraries.

Note: To install the fix_FFT library, you will need to extract the file into the Arduinolibraries folder of your computer.

Here you can modify the number of lines represented and the number of samples that the FFT will process. However, keep in mind that the Arduino does not support 256 FFT samples due to lack of memory, so any power of two lower than 256 will work.


This code is precisely the same output as the previous code, however caters for differences with the SH1106 libraries. You will need to load this code, as well as the associated library if you don't have it installed.

Where to from here?

Now you should have experienced how to design and build your own filter circuit, and how the MCP3008 can be used as a high speed ADC in conjunction with an Arduino UNO to create a powerful analyser circuit.

The options from here are relatively endless. Here's just a handful of things you can try:


Why not try varying the filter values to explore the different frequency response curves.


The MCP3008 is an 8-channel ADC; we're only using the first channel. You could try creating multiple filters with varying characteristics, each feeding in to different channels of the ADC.


To deploy this project into a working environment, you'd really want a PCB for it. This would help reduce noise which can be a challenge with breadboard-based circuits sometimes. Naturally you'd almost never use a breadboard circuit "in the wild" as things are too unstable and easily bumped too.

The odd exception perhaps is if you wanted to create a set of VU meters for a party decoration or similar, but it's probably still wise to move to veroboard or similar in that case too.


You could adjust the VU meter code to make the RGB LEDs behave differently. For example, we have included an extra file (Vu-Meter_Logarithm.ino) that illuminates the RGB LEDs based on a logarithmic scale and the peak in natural units.

The possibilities are endless, and this is an amazing project to springboard from.

Maker Inspiration

The following two videos were made by Stef Rid. Follow Stef on Instagram here:

Victor Casado

Victor Casado

Electronics Engineering Student, Spain