Getting audio information from MP3 shield

I have a VS1053B MP3 shield like this, piggy-backed on my Arduino Uno, and the SFEMP3Shield Library installed, with a couple of MP3’s on a micro SD card for testing. I’m using this basic code below:

#include <SPI.h>
#include <SdFat.h>
#include <SdFatUtil.h> 
#include <SFEMP3Shield.h>

SdFat sd;
SFEMP3Shield MP3player;

void setup() {

  Serial.begin(9600);
 
  sd.begin(SD_SEL, SPI_HALF_SPEED);
  MP3player.begin();
  MP3player.playTrack(2);
}

/*********** LOOP **************/
void loop() {

  int incomingAudio = analogRead(A0);
  Serial.println(incomingAudio);

}

Everything is working fine, and the MP3 plays no problem.

What I’d like to do is be able to read the sound levels so I can later apply that information to something else like blinking an LED or moving a servo in sync to the MP3 playing. I have tried reading the left and right channels from the shield into an analog pin, but it just spits out a 250 average consistently regardless what the song is playing. Does anyone know how to access the sound levels?

I have tried reading the left and right channels from the shield into an analog pin,

That is the only way you will do it, you can’t get that information form the MP3 chip.

How did you wire this up? You need a peak detector circuit between the audio output and the analogue pin.

Thanks Mike, never heard of a peak detector. Is it as simple as hooking up a diode and capacitor between my A0 pin and the left or right channel?

Here's a quick diagram of the hookup, pretty straight forward.

Thanks Mike, never heard of a peak detector. Is it as simple as hooking up a diode and capacitor between my A0 pin and the left or right channel?

Maybe... There's an approximate 0.7V drop across the diode, so low-level AC audio signals might not get through.

I use an [u]active peak detector circuit[/u], but that requires an op-amp and a dual (positive and negative) power supply.

A peak detector charges-up a capacitor and holds it for a period of time depending on the RC time constant. (There is no resistor in the circuit Mike linked to, and you really need a resistor across the capacitor.) I use a time-constant of about 1/10th of a second for audio activated lighting effects.

A peak detector removes the negative part of the AC audio waveform (a full-wave peak detector will invert negative voltages) and since it holds the voltage you can read the "volume" about 10 times per second instead of reading the audio waveform thousands of times per second.

(The Arduino can be damaged by negative voltages, so you do need to deal with that somehow.)

but it just spits out a 250 average consistently regardless what the song is playing.

Does silence also read about 250? ...That could be a good thing.

With the default 5V reference, 250 is about 1.25V. That means the audio output is biased at ~1.25V (and the headphone output uses a virtual ground at the same voltage).

A normal audio waveform is positive half the time and negative half the time and the average is zero. If your signal is biased so that silence reads 250, the average will also be 250, no mater how loud the audio is.

But, you should get readings above and below that average depending on the volume, and you can pick-out the peaks in software, or make your software do something when the peak readings are above a certain threshold.* You can optionally ignore the negative values (readings below the 250 bias), and/or you can subtract-out the bias and/or you can take the absolute value of the readings.

You do not need a peak detector, but you should know that with an audio signal half your readings are negative (or below the bias) and most of your readings will be somewhere between zero and the positive or negative peak. i.e. Since you'll be getting lots of low readings, even with a loud audio signal, you may want to do something like peak detection in software, or every time the LED comes on, hold it on for a fraction of a second, etc.

Bias on the output will also take care of the diode voltage-drop if you use a passive peak detector. You'll get slightly lower readings through the diode, but the readings will go up when audio is present.

If silence is reading zero, you can add your own [u]DC bias circuit[/u] to take care of the negative voltage issue. (With two equal-value resistors the bias will be half the supply voltage, so your signal should be biased at an ADC reading of about 512.)

  • One lighting effect I have keeps a 20 second moving average of the peak-detected value to use as a threshold. The light flashes on when the signal is above average and goes off when it's below average.

DVDdoug:
Does silence also read about 250? ...That could be a good thing.

Yes, even in silence it stays between 240-260.

DVDdoug:
But, you should get readings above and below that average depending on the volume, and you can pick-out the peaks in software, or make your software do something when the peak readings are above a certain threshold.*

I would prefer to have the hardware do the peak detection to free up the Arduino for other purposes, I'm just not sure how to figure out what type/size of diode/capacitor/resistor I would need. Would a 10 uf capacitor and 1n4140 diode work like you have in your sketch? or can I use a smaller capacitor? and a 1n4148 diode? along with a 10k ohm resistor?

Ideally I would like to get both the high and the low points of the audio file so I can use that information to drive a servo/LED's based on that information.

Just something to add, since my MP3 shield is a VS1053 and comparable to the one on Sparkfun, I noticed in figure8 on this page they are doing something similar, but they don't use any diodes. Would this work in my situation also?

Ok, time for a really stupid question. Is the analog pin on the Arduino the input and the channel the output, or the other way around? I'm attaching an image of how I understand a peak resistor schematic, can someone verify this is basically what it looks like.

I would like to have a resistor in there to pull down the signal after the peaks, so is the second diagram good or what needs to be changed?

Edit, the Uno in the diagram should be the MP3 shield.

No... Those are both wrong...

Look at the link Mike gave you. The signal needs to go through the resistor and diode before going into the Arduino. Then the capacitor goes across the Arduino's analog input and ground.

The diode blocks the negative part of the signal, giving you a signal that's positive (and of course it has a positive average value).

The resistor prevents the capacitor from "shorting out" the audio signal.

The capacitor holds the voltage.

I would like to have a resistor in there to pull down the signal after the peaks

I'd suggest a resistor that's about 10 times the series resistor value. (There are a couple of reasons for that.)

Would a 10 uf capacitor and 1n4140 diode work like you have in your sketch? or can I use a smaller capacitor? and a 1n4148 diode? along with a 10k ohm resistor?

Just about any diode will work.

There is a concept called the [u]RC Time constant[/u].

If you multiply the resistance (in Ohms) by the capacitance (in Farads) that gives you the RC time constant, which is the time it takes for the capacitor to charge-up to 63%, or to discharge by 63%. For example, a 1M resistor and a 1uF capacitor have a time constant of 1 second. 10K and 10uF is 0.1 second.

With the diode in the circuit, the charge time depends on the "parallel" resistance of the series resistor and the resistor across the capacitor (if any). Since the capacitor can't discharge through the diode, the discharge time only depends on the resistor across the capacitor. (The capacitor charges faster than it discharges, and that's generally what you want.)

Edit, the Uno in the diagram should be the MP3 shield.

That is just such a stupid thing to expect us to cope with. This is why Fritzing is hated here, those who use it simply can not cope. Please use a real schematic that you draw with pen and paper then you can label things as they really are. I did spend some time trying to work out what the hell you were doing before I got to that edit note.
Do not do this again.

That is just such a stupid thing to expect us to cope with. This is why Fritzing is hated here, those who use it simply can not cope. Please use a real schematic that you draw with pen and paper then you can label things as they really are. I did spend some time trying to work out what the hell you were doing before I got to that edit note.
Do not do this again.

You might hate Fritzing, but not everyone does. Being new to electronics I can't easily make sense of even basic schematics yet (or more specifically how to apply them to a breadboard), so seeing things visually is much more helpful to me at this point in time. If I see how it works on a breadboard I can go back to the schematic and understand it, but I know best what works for me. Don't assume Fritzing is hated here, its not just a forum for professionals or hobbyists with years of experience. Most of what I have learned up to this point has been through diagrams people have posted, videos, and reading, not schematics. In any case, I don't want to debate the usefulness of Fritzing, but if it bothers you feel free to ignore my posts in the future, as I plan to keep using Fritzing and asking stupid questions until I have a better understanding of electronics.

The signal needs to go through the resistor and diode before going into the Arduino. Then the capacitor goes across the Arduino's analog input and ground.

The diode blocks the negative part of the signal, giving you a signal that's positive (and of course it has a positive average value).

The resistor prevents the capacitor from "shorting out" the audio signal.

The capacitor holds the voltage.

Ok, does one of these make more sense?

There is a concept called the RC Time constant.

If you multiply the resistance (in Ohms) by the capacitance (in Farads) that gives you the RC time constant, which is the time it takes for the capacitor to charge-up to 63%, or to discharge by 63%. For example, a 1M resistor and a 1uF capacitor have a time constant of 1 second. 10K and 10uF is 0.1 second.

With the diode in the circuit, the charge time depends on the "parallel" resistance of the series resistor and the resistor across the capacitor (if any). Since the capacitor can't discharge through the diode, the discharge time only depends on the resistor across the capacitor. (The capacitor charges faster than it discharges, and that's generally what you want.)

Cool, this is good to know, thanks.

I tried the last image I posted and variations of it, and it always seems to stay around 250. I created an MP3 file with a separate left and right channel, with me counting from 1-10 on the left and humming on the right channel. It's looping over and over for testing, but no luck. I tried following this guide, but it's not working, and it seems the resistor is placed differently then the schematic Mike linked to. Here is my current set up. I tried both figure 1 and 2 from the fritzing, doesn't seem to work.