Audio processing

So I have a quick question for everyone. I don't want to sound stupid at all but. If I put an amplifier and then a rectifier on the signal. Would i be able to make a reasonable VU meter. Or am I being to simplistic. Not quite sure how rectifiers work but was wondering.

Generally the way I've personally seen this done is to use the line level through a really high ohm resistor.

You try not to leech any of the audio signal where possible.

Most systems use a 2V output on line level, which you can easily read on the Arduino's Analog input. Use a diode to eliminate the negative portion of the audio signal.

A rectifier converts AC to DC, so in a sense it might work for you, but what you are really doing is converting the clean AC audio signal into a pulsed DC signal.

Although rectifier can mean as little as a Diode, usually it's in reference to a bridge rectifier.

Check into the following link. It's a cheap but effective chip to make a VU meter from.
http://www.national.com/mpf/LM/LM3914.html

So what you are saying is to not even use an amplifier and instead use a large 100k ohms resistor and a simple diode. The one thing i have a problem with this non-amplifier based audio monitoring is that the swings in the different amounts of voltage with the music will be quite small. I do not see the point in the resistor. Would it be better to go diode then the resistor. That way there is no way of hurting the audio source. Thanks any input appreciated.

Those "Minor" voltage differences are quite readable to the Arduino.

Even leaving all the original settings alone, the Arduino can read 1024 points between 0 volts and +5 volts.

If you have a line level audio, and roughly 2ish Volts out (Call it 2.5 max) then the Arduino can return 512 points of resolution on the voltage.

A small change and the Arduino can be made to measure between 0 and 2.5 volts, giving you 1024 points of resolution.

The way i thought that the audio line outputs work is that it would never drop to 0 or anything really cool. That setting up of the arduino to doing the 1024 points in between 0 and 2.5V. Do you use the scaling feature? Really like all of the help. Thanks a lot. I had hit a bit of a wall.

Read up on this page:

Hello! :slight_smile: I have 2 questions at the end of this.
I was also trying to make a sort of UV meter with my Arduino, but I was trying to do it using an audio amplifier from Radio Shack. I don't have an Electrical Engineering degree, so if this is an extremely silly idea please go ahead & tell me!

I cut an old stereo headphone cord, untwisted the 3 wires inside and soldered short copper wires to each of them. Then attached the right channel to the Red Transformer Wire and the stereo grounding wire to the White Transformer Wire (the left channel is just kinda' left hanging :stuck_out_tongue: )

Then I plugged the Blue Transformer Wire into the +5V on my Arduino Diecimila, and the Green Transformer Wire into my Analog In 0 on my Diecimila.

Here's the code I used based on the Analog Input Tutorial:

 int sensorPin = 0;    // select the input pin for the potentiometer
 int ledPin = 13;      // select the pin for the LED
 int sensorValue = 0;  // variable to store the value coming from the sensor

 void setup() {
   // declare the ledPin as an OUTPUT:
   pinMode(ledPin, OUTPUT);
   Serial.begin(9600);  
 }

 void loop() {
   // read the value from the sensor:
   sensorValue = analogRead(sensorPin);                     
   Serial.println(sensorValue);
 }

My Results: When no music was playing the sensorValue stayed pretty consistently at 1023.

When I plug the headphone cord into my iPod and start playing music, the sensorValue number starts dancing all over the place. I've seen it go all the way down to 1.

2 Questions:
1) Am I actually measuring the signal strength coming from my iPod headphone jack?
2) What on earth is the Black Wire on the Transformer for? :-[

The middle black wire is most likely a "center tap" wire. Transformers typically have 2 coils, but usually they give you a lead to the very center of the second coil.

If you have a 24VAC transformer, the 24VAC would be from one of the outside leads to the other outside lead.

From one of the outside leads to the center tap is 1/2, or 12VAC in this example.

Are you measuring voltage from iPod. Sort of... the ability to answer that question depends greatly on the transformer. Got any specs? 1:1 ratio, 1:100 ratio.. Intended for Audio? Step up/ Step Down? These all affect how voltage interacts with the windings. A 1:1 Audio matching transformer performs a lot differently than a 1:10 step down transformer.

Thank you! That third black wire has been driving me crazy. :slight_smile:

As for the transfomer specs, I haven't been able to find any. It is intended for audio, frequency response: 300Hz to 10kHz, and "low-level impedance matching." It came from Radio Shack:

It's listed as model "EI-19" there but I can't find any data sheets on it. This is the closest one I could find:

but I'm not sure it's the same thing. That one has 6 leads while mine has 5. Although all the dimensions match except the length, but it's off by just under .1 inches.

Does this help?
Thank You!!!

So I have completely reworked my ideas and the software that I am running on it but I am still running into a few little hiccups and was looking for some help. The first thing would be with possible setting up a logarithmic scale with my values.

1000 Ohm Primary, 8 Ohm Secondary.

It says impedance matching, so the voltage reading should at the very least indicate a relative level, just not the exact voltage measurement.

What do you mean by primary and secondary. Do you mean a 1000 ohm resistor and a 8 ohm between the line and ground?

Every transformer is made up two different coils.

Rather than me bumbling trying to explain it, I'll quote people much smarter than me.

From Explain That Stuff:

A transformer is based on a very simple fact about electricity: when a fluctuating electric current flows through a wire, it generates a magnetic field (an invisible pattern of magnetism) or "magnetic flux" all around it. The strength of the magnetism (which has the rather technical name of magnetic flux density) is directly related to the size of the electric current. So the bigger the current, the stronger the magnetic field. Now there's another interesting fact about electricity too. When a magnetic field fluctuates around a piece of wire, it generates an electric current in the wire. So if we put a second coil of wire next to the first one, and send a fluctuating electric current into the first coil, we will create an electric current in the second wire. This is called electromagnetic induction because the current in the first coil causes (or "induces") a current in the second coil. The current in the first coil is usually called the primary current and the current in the second wire is (surprise, surprise) the secondary current. What we've done here is pass an electric current through empty space from one coil of wire to another. This phenomenon is called electromagnetic induction.

I think it does a good job at explaining the basics, if you're hungry for more info, check out Wikipedia

Looking back this thread got hijacked somewhere in the middle.. the 1000 Ohm/8 Ohm doesn't apply to you, but if you're interested in transformers there is a couple of links :wink:

Just to point out that all these solutions seem to be feeding AC into and Arduino input pin. This is not good (damage will happen to the arduino) and you will need a diode to stop the input going negative of 0v. A capacitor from the input to ground will also smooth out the variations of the audio signal and give you just the envelope which is what you want to measure for a VU meter. I would advise also using catching diodes on the analogue input:- Protection

The problem is that you are trying to measure something that is logarithmic with a liner detector (the A/D) and so the range you can get out is going to be limited.

I understand what you are saying about the decoupling capacitor. I had already put a 100nf capacitor in to clean the signal. I also have already put in a diode. It took me a little while to figure out the whole diode thing and that I need it, but i think my arduino is still fine. It is sensing just like it always did. I have a slight off topic question. If I am only using a usb to hook up to my computer. There is no way that the arduino can hurt my computer right?

There is no way that the arduino can hurt my computer right?

The worst that can happen is that you could blow up the USB port by having a short on the power rails. There is a poly fuse to protect against this but these take a long time to blow and might not be fast enough to prevent damage from all USB ports. However we have herd of the occasional USB port going here but most of them shut down before too much damage has occurred requiring a simple reboot.

However if you go sticking mains voltages on your arduino you will blow that and probably take a chunk of your computer with it.

So "no way" is putting it a bit strong, but in general it is quite tolerant of mistakes. :slight_smile:

Still having a little trouble with my code and i can not see where it is. What is happening is none of the led are turning on. I think the problem is with the write function. The problem is when i am turning them on and off. I want a little bit of a delay before it turns the light on so I used the delay function. When the delay is in the arduino does not turn on any of the leds. When it is not in, they turn on just fine.

#define SENSOR 0
//int ledPin[]={6,5,4,3,2,1,0};
int ledPin[]={7,8,9,10,11,12,13};


void setup() 
{
  for(int k=0;k<=13;k+=1)
  {
    pinMode(ledPin[k],OUTPUT);
  }
}

//int grab()
//{
//  int value;
//  value=analogRead(SENSOR);
//  int Led;
//  Led=map(value,0,175,0,6);
//  return Led;
//}

int grab()
{
  int value;
  int group=0;
  for(int i=0;i<=50;i+=1)
  {
    value=analogRead(SENSOR);
    group=group+value;
  }
  group=group/50;
  int Led;
  Led=map(group,0,175,0,6);
  return Led;
}

void Write(int Led, int oldLed)
{
  int diff;
  if(Led > oldLed)
  {
    diff=Led-oldLed;
    for(int n=oldLed;n<=Led;n+=1)
    {
      delay(50);                     //This is where the problem is
      digitalWrite(ledPin[n],HIGH);
    }
    return;
  }
  if(oldLed > Led)
  {
    diff=oldLed-Led;
    for(int n=oldLed;n>=Led;n-=1)
    {
      delay(50);                     //This is where the problem is
      digitalWrite(ledPin[n],LOW);
    }
    return;
  }
  return;
}


      
void loop()
{
  int Led;
  int oldLed;
  for(;;)
  {
    Led=grab();
    Write(Led,oldLed);
    oldLed=Led;
    delay(1);
  }
}

Any help is appreciated.

I can't see why the delay(50) statements in the Write() function would be the cause of what you report.

However, your definition of ledPin[] contains 7 elements, and the loop in setup() loops 14 times. This puts the code somewhat into the "unpredictable results" category, though it should be in that category with or without the delay(50) lines.
:-/

So I have gotten over the disappointment of the delay mentioned above and moved on to my next conundrum. I think that I may have broken my arduino some where down the line, because i keep having weird little hiccups. This is my problem:

int grab()
{
  int value;
  int group=0;
  for(int i=0;i<=50;i+=1)
  {
    value=analogRead(SENSOR);
    group=group+value;
  }
  group=group/50;
  int Led;
  int music=analogRead(POT);
  int high=map(music,0,1023,0,200);
  Led=map(group,0,high,0,6);
  return Led;
}

What is happening has to do with the POT sensor. What I am doing is running a potentiometer. From this POT value i will adjust the high for the leds. This is so I can adjust the VU meter levels so that the Ipod or audio source does not need to be at a certain volume to look right. For some reason the value is always screwed up and nowhere near the value on the POT sensor. It just goes crazy for some reason. Any help is needed. Thanks.

you are potentially adding 50 values of 1023 which will overflow an int value because the highest value it can hold is 32767.

Try changing group to an unsigned int and see if it then works as expected because an unsigned int can hold up to 65535.

--
Martyn.