I’m working on a project where I cycle through audio files each time a button is pressed. The device plays the audio files, but there is significant static noise that drowns out the audio, making it barely legible. Here’s what I’m using:
Components:
Arduino Nano v3.0
PAM8302 amplifier
Micro SD card reader (SKU: CE09444)
4-ohm / 3W speaker (SKU: ADA1314)
4x AAA batteries in series (4.8V / 1A)
What I’ve Tried: I’ve added a high-pass and low-pass filter at the power source and a low-pass filter between the Arduino and the amplifier input, which has greatly improved the signal. However, while a continuous audio file now plays legibly, the noise is still problematic. Any other audio files containing voice are completely overwhelmed by static.
Details: The audio files are in .wav format. I’ve attached the code below and a circuit diagram for your reference.
Code Snippet:
#include <SD.h>
#include <TMRpcm.h>
#include <SPI.h>
#define CS_PIN 10 // Define the CS pin for the SD card
#define BUTTON_PIN 2 // Define the pin for the button
TMRpcm audio;
int currentFileIndex = 0;
const int numFiles = 8; // Adjust based on the number of audio files
String audioFiles[] = {
"aaa.wav",
// Other filenames commented out for simplicity
};
void setup() {
pinMode(CS_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
Serial.begin(9600);
if (!SD.begin(CS_PIN)) {
Serial.println("SD initialization failed!");
return;
}
Serial.println("SD initialized.");
audio.speakerPin = 9; // Connect your amplifier input to pin 9
audio.quality(1); // 0 = 8-bit (low quality), 1 = 10-bit (higher quality)
audio.setVolume(0); // Set to 0 for the loudest volume (range is 0 to 7)
}
void loop() {
static bool buttonPressed = false;
if (digitalRead(BUTTON_PIN) == LOW) {
if (!buttonPressed) {
buttonPressed = true;
playNextAudio();
}
} else {
buttonPressed = false;
}
}
void playNextAudio() {
if (audio.isPlaying()) {
audio.stopPlayback(); // Stop current playback before starting a new one
}
Serial.print("Playing: ");
Serial.println(audioFiles[currentFileIndex]);
audio.play(audioFiles[currentFileIndex].c_str()); // Play the audio file
currentFileIndex = (currentFileIndex + 1) % numFiles; // Loop through files
}
Question: Does anyone have suggestions on how to further reduce static noise or ideas for other potential issues that might be causing this? Any advice would be greatly appreciated!
You can power the amplifier and the Arduino from separate regulated supplies. Shared power supplies can introduce noise from the Arduino’s digital circuits.
Hi Patrick
Firstly if that circuit diagram is correct this set up will not work at all. You have a 0.1µF cap in series with the power line.
As It is making a noise I assume the circuit diagram is incorrect. Some better accuracy please.
Has this ever worked properly? Hs this “noise” always been there? or has it just happened.
“D9” is listed as a digital pin. What sort of signal do you expect here. I am not familiar with getting Audio out of a Nano so I am assuming it is some sort of PWM. If so it would need filtering to recover the audio to input to the audio amp.
Where did this circuit come from. Is it published somewhere to is it one you devised.
The capacitor is part of your “power source filtering”. As @Robert93820 stated, the capacitor will block the power source (capacitors block DC) and as such, your entire circuit will not work (as drawn in the diagram, at least). This is also the “high-pass” portion of the filter. If you are filtering out high frequencies (noise) you likely don’t want to pass them, so it seems unnecesssary.
Regarding the lowpass filter on your Arduino output, the cutoff frequency (or -3dB point) of this filter is according to the equation below:
Plugging into a calculator you will find that the cutoff frequency is approx. 1600 Hz, thus anything higher than that will be attenuated significantly. For audio filtering, this is not ideal as audible frequencies can range up to 20 kHz. I can send you some resources on AC filters if you would like!
It seems the method you are using for audio output is using the library seen below:
I am not super familiar with this library, but it seems it expressly makes use of the timers for audio output. This is fine, but as Bob said, the output will be digital. Without any filtering this will likely achieve an undesired effect anyway. Are you following a guide of sorts? If so it would be awesome if you could send it through for us to take a look.
Lastly, “noise” is a very general term. Is there any way you could send a video of the issue? It may be easier for us to help if we can identify the sound.
Hi Zac, Patrick
Just had a brief look at that link.
A bit confusing as the author says
Quote
If using an amplifier, consider that the output is a choppy digital PWM signal, not a smooth analog signal.
End quote
This I agree with but right underneath he says
Quote
Note: Advice is often given NOT to connect a speaker directly to the digital pins on an Arduino. This is typically true, but TMRpcm is designed and tested with this configuration:
End quote
Don’t quite understand.
Regarding that 0.1µF cap shown in series with the power line I think it should be between the power line and ground. The 1k resistor to ground is only using up an extra 5mA or so. Does not do anything else. Maybe a pull down for Vcc ??? Just joking.
Cheers Bob
The rest of the description indicates that the writer believes that the use of a high-speed pulsed signal removes the risk that might be associated with loading a Arduino GPIO port with what looks like a 8-Ohm load. In other words, it is the choppiness he refers to in the first part that makes the configuration he is recommending possible. So the two statements are consistent.
This is a circuit I designed myself and I am not using any sort of guide.
It has been a number of years since I have done any electrical design and I confused when to use decoupling and high/low pass filters. Removing the filtering from the power source and just having a capacitor in parallel has had an unnoticeable affect on the system.
the system does play sound. I can hear the audio file underneath the static. If you download the attach zip, you can hear the ‘imperial march’ underneath the static
The plan was to use the TMRpcm library to create a PWM single and smooth it using a filter
I was only hoping to using the resistors and capacitors I had on hand to do my filtering but it is looking like I will need to go purchase the appropriate sizes. Sound recordings.zip (1019.0 KB)
Hi Patrick
I don’t quite know how you are going to go about this without using a Codec. You might be able to get the Arduino to do it .
My take is if you try to eliminate this "static (which is obviously audible) using a simple R/C low pass filter you are going to filter out the wanted audio as well so you will finish up with only the lowest base frequencies. With a PWM (class D ??) amplifier the speaker inductance and voice coil inertia are part of the output filtering circuit and you have to select the coupling Caps to match voice coil impedance. You are attempting to drive a high input impedance analog amplifier which you may not be able to do and you will need to convert the PWM to audio first (analog).
Cheers Bob
Hi Patrick
Add on:
You are feeding a digital signal (wav.) into an Arduino and trying to convert that into another type of digital (PWM) signal
The trouble as I see it is the native Arduino PWM frequency is quite slow, in the order of 400 to 500 Hz. Now if you filter that out you will have no audio either. I believe the PWM frequency has to be several octaves above audible and then you may stand a chance of filtering that out to leave an analog audio signal.
Could be wrong here but these are my thoughts.
Cheers Bob
I’ve used TMRpcm before.
It’s not perfect but it can give better results than the audio you have provided
To rule out some variables, what happens when you use one of the examples provided in the github repository? Maybe this one for instance.
If it doesn’t work you know hardware is where to focus the debugging efforts.
If it does work maybe it’s your code? (although the code seems ok to me).
I’d also recommend trying audio.setVolume(3). (or even quieter).
I like use this breakout which also uses the PAM8302 and it, in my experience, prefers low voltage inputs and high gain. Based on the audio you provided I don’t think your hard clipping the amp… but It’s hard to be certain based on recordings so it’s worth exploring.
1 Like
And you can get our latest projects and tips straight away by following us on: