Noise on Due DAC when reading from MicroSD through SPI

Hi all,
I know this has already been asked (Noise on Due Dac - Arduino Due - Arduino Forum) but since noone is answering on that topic I'm hoping to have better luck here.
I'm an experienced programmer but I'm just beginning with electronics, so please bear with me if I write silly stuff.
I'm trying to run the SimpleAudioPlayer example on a Due (see the code at Audio - Arduino Reference), reading a mono WAV file from a microSD card and playing it through the DAC, which is connected to an amplifier breakout, which in turn is connected to a speaker. See the attached images for details.
Everything works fine, except that there's a ground noise mixed with the audio that seems to be related to the microSD card reading.
The microSD card socket is directly wired to the SPI interface of the DUE, since it already works at 3.3v which is the required level for microSD. More specifically, I've attached the pins as follows (see SD card - Wikipedia for microSD pin numbering, and SPI - Arduino Reference for Arduino SPI header pin numbering):

  • microSD pin 2 (nCS) to Digital Pin 10
  • microSD pin 3 (DI) to SPI MOSI (pin 4 of the SPI header)
  • microSD pin 4 (VDD) to 3.3v Pin
  • microSD pin 5 (CLK) to SPI SCK (pin 3 of the SPI header)
  • microSD pin 6 (VSS) to GND Pin
  • microSD pin 7 (DO) to SPI MISO (pin 1 of the SPI header)
  • microSD pin 1 and 8 not wired to anithing

The WAV files reads fine, so I guess my wiring is correct (at least from at logic level).

I'm using Sparkfun's Mono Audio Amp Breakout with TPA2005D1 as an amplifier, see https://www.sparkfun.com/products/11044. The DAC0 and GND pins are connected to the amp's input + and - respectively. The amp's power + and - are connected to pins 5.5v and GND on the arduino (I've already tried using 3.3 but the noise is still there). The amp's output + and - are connected to a 1.5W speaker (http://it.rs-online.com/web/p/altoparlanti-miniatura/7564618/).
All grounds (amp input-, amp power- and microsd pin 6) are connected to the same rail on the breadboard, which is then connected to a single GND pin on the arduino.

Things I've tried so far:

  • switching DAC0 with DAC1: STILL noise
  • powering the amp with 3.3v instead of 5v: STILL noise
  • disconnecting ONLY DAC0 from the amp's input+: STILL noise at a lower volume
  • disconnecting the microSD card completely so that nothing is read but the amp is powered: NO noise
  • removing sparkfun's amp and attaching an external amplifier with speakers to DAC0: NO noise
  • disconnecting DAC0 and GND from the amp's input, and connecting an external audio source to the amp's input (while it's still powered from the arduino): NO noise

Please help me, I have to ship this project for next week and the noise isn''t really acceptable. If required I can provide an mp3 with an example of the noise I'm hearing, and/or a complete schematic of the circuit.
Thanks in advance to everyone!
lorenzo

Finally, the code I'm using (it's the same as the SimpleAudioPlayer example, just modified to loop the wav indefinitely and use pin 10 as CS for the SPI):

/*
  Simple Audio Player

 Demonstrates the use of the Audio library for the Arduino Due
 
 Hardware required :
 * Arduino shield with a SD card on CS4
 * A sound file named "test.wav" in the root directory of the SD card 
 * Speaker attched to ground and DAC0

 Original by Massimo Banzi September 20, 2012
 Modified by Scott Fitzgerald October 19, 2012
 
 This example code is in the public domain
 
 http://arduino.cc/en/Tutorial/SimpleAudioPlayer

*/

#include <SD.h>
#include <SPI.h>
#include <Audio.h>

void setup()
{
  // debug output at 9600 baud
  Serial.begin(9600);

  // setup SD-card
  Serial.print("Initializing SD card...");
  if (!SD.begin(10)) {
    Serial.println(" failed!");
    return;
  }
  Serial.println(" done.");
  // hi-speed SPI transfers
  SPI.setClockDivider(4);

  // 44100Khz mono
  // 100 mSec of prebuffering.
  Audio.begin(44100, 100);
}

void loop()
{
  int count=0;

  // open wave file from sdcard
  File myFile = SD.open("DAFT.WAV");
  if (!myFile) {
    // if the file didn't open, print an error and stop
    Serial.println("error opening test.wav");
    while (true);
  }

  const int S=1024; // Number of samples to read in block
  short buffer[S];

  Serial.print("Playing");
  // until the file is not finished
  while(true) {
    if(!myFile.available()) myFile.seek(0);
    // read from the file into buffer
    myFile.read(buffer, sizeof(buffer));

    // Prepare samples
    int volume = 1024;
    Audio.prepare(buffer, S, volume);
    // Feed samples to audio
    Audio.write(buffer, S);

    // Every 100 block print a '.'
    count++;
    if (count == 100) {
      Serial.print(".");
      count = 0;
    }
  }
  myFile.close();

  Serial.println("End of file. Thank you for listening!");
  while (true) ;
}

Does that not suggest that it is Sparkfun's amplifier causing the problem?
It looks like you could try and improve that with extra supply decoupling.

It is also a class D amplifier that is probbly where the noise is being generated.

Thanks for your reply, unfortunately I'm sure that it's not the amp because if I use it without the arduino, or even if I power it with the arduino but feed it with an external audio source, it works fine without any noise at all. Moreover, I've tried 3 of them (I have to build 3 prototypes), and all three have the noise problem when I read from the sd card.

But you said

  • removing sparkfun's amp and attaching an external amplifier with speakers to DAC0: NO noise

So that suggests very strongly to me that the amplifier is the source of the noise. Why does it not to you?

You can try as many as you like but it is the fundamental design that is screwing you.

Sorry I didn't explain myself very clearly.
If I leave the circuit exactly as it is but I don't read from the sd card, there's no noise at all.
If I connect the amp's input to an external audio source (leaving the amp powered from the arduino), there's no noise either.
If I just disconnect the amp's input+ from DAC0 (leaving input- connected to arduino's GND), I obviously don't hear the audio playing, but I hear the ground noise at a lower volume when I read from the sd card. For this reason I'm quite convinced that the problem is related to the microsd messing with the ground level (sorry for the phrasing, I hope it's understandable).
Do you still think it may be the amp's fault?

To determine if the noise is coming from the SPI traffic (it shouldn't matter what is connected to the SPI) generate a sine wave in software and play it without changing any wiring and see if you still have noise.

I suspect the noise is being coupled through the wiring connecting the amp and sdcard to the Due. If so these may help:

1 Breadboards have a lot of stray capacitance don't route audio through one. The capacitance will couple other signals routed through the breadboard into the audio.

2 Use a twisted pair for audio signals.

3 Try sending a differential signal by using both DAC's and sending an inverted signal on one. This is the whole reason for the differential inputs on the amp any noise picked up in the wiring will be cancelled.

Thank you so much noblepeeper! I'll try your suggestions asap and tell you the results.
In the meantime, maybe it's also worth quoting what user pito suggested in the previous thread by bglsmith:

That could be caused by grounding loops. Try to connect each module's GND wire to a good decoupled "single ground point" ("star" topology). Maybe a decoupling of each module's power (small resistor in series and capacitor to gnd) could help as well.

While bglsmith tried the "star" topology solution with little success, he said he would have tried "decoupling each module's power" next, but he didn't say if that solved the problem.
I could try this too, but I need someone to explain me what I have to do, i.e. which values for cap and resistors and how to connect them to my circuit.
Thanks again!

noblepepper* sorry :stuck_out_tongue_closed_eyes:

Ok noblepepper, I've followed your advice and written a sketch that generates an infinite sine wave with a constant frequency, and run it without changing anything (clearly the sd card isn't read anymore).
Unfortunately, the noise was still there, just now it's plain white-ish noise, without the recognizable pattern of sd-card reads. It sounds like someone is frying something nearby.

So I've done the following things:

  • removed the sd card and all related wiring altogether
  • replaced the audio cables with twisted pairs (well, I've just twisted together each couple of cables :slight_smile: )
  • written a sketch that generates an infinite alternation of sine wave and pause; the program sends this signal to DAC0, and the inverse of this signal to DAC1
  • connected the amp's input + and - to DAC0 and DAC1 respectively
  • removed the breadboard, connecting everything together just with cables
    You can see the modified layout in the attached image (just the breadboard is still there but I removed it later).

The result is: STILL noise. You can hear the actual noise (both mixed to the sine wave and alone) in the attached arduino_amp.mp3

Then I've disconnected the amp's input from the arduino (leaving the amp's power connected to it though), and connected the amp's input to an external audio source.
Result: NO noise. Hear it in arduino_amp_external_audio_source.mp3 (the song is noisy because i've recorded it at home with crappy hardware, but the ground noise is definitely gone).

Finally, I've disconnected the amp altogether from the arduino, and connected the arduino's DACs to an external amplifier and speakers (my home hi-fi).
Result: NO noise. Hear it in arduino_external_stereo.mp3

I really don't know what's going on here. The DAC's output is ok, the sparkfun's amp is ok, but when the amp is plugged BOTH to arduino's power AND DACs, here comes that F****NG noise.
Any help is really, really appreciated. Thanks :~

arduino_amp.mp3 (372 KB)

arduino_amp_external_audio_source.mp3 (315 KB)

arduino_external_stereo.mp3 (242 KB)

I did another test, it was pretty obvious but I missed it at first. I connected the amp's power to arduino, and the arduino's DACs to an external amp+speakers (my hi-fi).
Result: NOISE.
So the fact that the amp is powered by the arduino introduces the noise directly on the DAC output, the amp is working fine.
Problem not solved, but it's a step forward at least.
Next thing I'll try is powering the amp with an external battery and connecting the DAC to it. I'll post the results shortly.

I powered the amp using an external 4V supply and connected its input to arduino's DACs.
Aaaaand the noise is still there.
I'm a bit confused now, anyone can explain this?

Can you post a schematic of the amplifier circuit.
The confusion you are experiencing when you connect the DAC outputs to another amplifier may have to do with different methods of decoupling within the different amplifiers you have tried.
i haven't tried playing audio from these units but have had similar issues when interfacing balanced to unbalanced signals. if i am in any doubt i will use completely separate battery supplies for each unit and use a transformer 1K:1K to couple the audio. if the problem disappears then i incrementally re-intergrate the two systems until the problem re appears (join the grounds, then the supplies, dc block the audio (with capacitors) then, finally directly couple the audio, at some point the noise will come back) and you have a starting point to investigate, experiment, identify and eliminate the cause.

Your "noise" is at least two undesired signals, you need to consider them one at a time.

SPI noise: With the sine wave through the differential output, twisted pair setup and no audio through a breadboard you have white noise but we don't know anything about the SPI noise issue yet. With this setup hook the SD card back up, play the wav file and see if the noise is less than your original setup. It is fine to use the breadboard for the SD hookup, just keep it physically away from the audio wiring. If this reduces the SPI noise then we have found one undesired signal is coupling in the input wiring. I would also move your ground lead connection from the Arduino to the power header near the 5v connection as in your original setup. Keep the audio signal as far away physically from the power connection and SD card wiring as you can.

White noise: What signal level are you outputting from the DAC's? Noise picked up on the amplifier input wiring will be constant and amplified with the desired signal, if you can increase the desired signal and decrease the amp gain you will have a better SNR.

lencinhaus:
Hi all,
I know this has already been asked (Noise on Due Dac - Arduino Due - Arduino Forum) but since noone is answering on that topic I'm hoping to have better luck here.
I'm an experienced programmer but I'm just beginning with electronics, so please bear with me if I write silly stuff.
I'm trying to run the SimpleAudioPlayer example on a Due (see the code at Audio - Arduino Reference), reading a mono WAV file from a microSD card and playing it through the DAC, which is connected to an amplifier breakout, which in turn is connected to a speaker. See the attached images for details.
Everything works fine, except that there's a ground noise mixed with the audio that seems to be related to the microSD card reading.
The microSD card socket is directly wired to the SPI interface of the DUE, since it already works at 3.3v which is the required level for microSD. More specifically, I've attached the pins as follows (see SD card - Wikipedia for microSD pin numbering, and SPI - Arduino Reference for Arduino SPI header pin numbering):

  • microSD pin 2 (nCS) to Digital Pin 10
  • microSD pin 3 (DI) to SPI MOSI (pin 4 of the SPI header)
  • microSD pin 4 (VDD) to 3.3v Pin
  • microSD pin 5 (CLK) to SPI SCK (pin 3 of the SPI header)
  • microSD pin 6 (VSS) to GND Pin
  • microSD pin 7 (DO) to SPI MISO (pin 1 of the SPI header)
  • microSD pin 1 and 8 not wired to anithing

The WAV files reads fine, so I guess my wiring is correct (at least from at logic level).

I'm using Sparkfun's Mono Audio Amp Breakout with TPA2005D1 as an amplifier, see https://www.sparkfun.com/products/11044. The DAC0 and GND pins are connected to the amp's input + and - respectively. The amp's power + and - are connected to pins 5.5v and GND on the arduino (I've already tried using 3.3 but the noise is still there). The amp's output + and - are connected to a 1.5W speaker (http://it.rs-online.com/web/p/altoparlanti-miniatura/7564618/).
All grounds (amp input-, amp power- and microsd pin 6) are connected to the same rail on the breadboard, which is then connected to a single GND pin on the arduino.

Things I've tried so far:

  • switching DAC0 with DAC1: STILL noise
  • powering the amp with 3.3v instead of 5v: STILL noise
  • disconnecting ONLY DAC0 from the amp's input+: STILL noise at a lower volume
  • disconnecting the microSD card completely so that nothing is read but the amp is powered: NO noise
  • removing sparkfun's amp and attaching an external amplifier with speakers to DAC0: NO noise
  • disconnecting DAC0 and GND from the amp's input, and connecting an external audio source to the amp's input (while it's still powered from the arduino): NO noise

Please help me, I have to ship this project for next week and the noise isn''t really acceptable. If required I can provide an mp3 with an example of the noise I'm hearing, and/or a complete schematic of the circuit.
Thanks in advance to everyone!
lorenzo

Finally, the code I'm using (it's the same as the SimpleAudioPlayer example, just modified to loop the wav indefinitely and use pin 10 as CS for the SPI):

/*

Simple Audio Player

Demonstrates the use of the Audio library for the Arduino Due

Hardware required :

  • Arduino shield with a SD card on CS4
  • A sound file named "test.wav" in the root directory of the SD card
  • Speaker attched to ground and DAC0

Original by Massimo Banzi September 20, 2012
Modified by Scott Fitzgerald October 19, 2012

This example code is in the public domain

http://arduino.cc/en/Tutorial/SimpleAudioPlayer

*/

#include <SD.h>
#include <SPI.h>
#include <Audio.h>

void setup()
{
  // debug output at 9600 baud
  Serial.begin(9600);

// setup SD-card
  Serial.print("Initializing SD card...");
  if (!SD.begin(10)) {
    Serial.println(" failed!");
    return;
  }
  Serial.println(" done.");
  // hi-speed SPI transfers
  SPI.setClockDivider(4);

// 44100Khz mono
  // 100 mSec of prebuffering.
  Audio.begin(44100, 100);
}

void loop()
{
  int count=0;

// open wave file from sdcard
  File myFile = SD.open("DAFT.WAV");
  if (!myFile) {
    // if the file didn't open, print an error and stop
    Serial.println("error opening test.wav");
    while (true);
  }

const int S=1024; // Number of samples to read in block
  short buffer[S];

Serial.print("Playing");
  // until the file is not finished
  while(true) {
    if(!myFile.available()) myFile.seek(0);
    // read from the file into buffer
    myFile.read(buffer, sizeof(buffer));

// Prepare samples
    int volume = 1024;
    Audio.prepare(buffer, S, volume);
    // Feed samples to audio
    Audio.write(buffer, S);

// Every 100 block print a '.'
    count++;
    if (count == 100) {
      Serial.print(".");
      count = 0;
    }
  }
  myFile.close();

Serial.println("End of file. Thank you for listening!");
  while (true) ;
}