18

EDIT: I have been investigating in this problem for quite some time. It turns out to be a way more difficult project than I thought and not something for beginners. This requires expensive hardware (microphone & amplifier) and some sophisticated audio analyizig on the microcontroller. Even a complete microphone with amplyfier circuit does not provide the desired results (according to the comments on this product)


I am entirely new to the Arduino (but I'm familiar with programming). In order to built a VU meter, I want to put a microphone to the analog 0 pin of the Arduino and display the value via the serial connection.

I googled and found this circuit:

Simple Audio Pre-Amplifier

... and I tried to build it with this result:

(I'm now using the circuit suggested by Oli Glaser in his answer)

The values on the serial monitor don't change depending on the music volume.

What is the easiest way to measure the volume on the analog input of the Arduino?

Also, I have a TDA2822M, but I don't know if it is helpful for this project. The caption on the microphone reads XF-18D.

Edit: My arduino code:

void setup() {
  Serial.begin(9600); 
}

void loop() {
  Serial.println(analogRead(0));
  delay(300);
}

The serial output: 1023 1022 1022 1022 1022 1023 1022 and so on

How can I check if the microphone works at all? Is it directional?

Edit: I am now using a S9014 transistor. The ADC and the serial connection work (I tested them with a potentiometer).

The serial output is now around 57.

Also, I don't have a multimeter or oscilloscope. I have a multimeter now.

Toast
  • 363
  • 1
  • 3
  • 10

3 Answers3

14

The "easiest" way is simply to apply the signal and sample with the ADC. Store the results in a buffer then display as desired (in your case send to PC via RS232)
If you want the RMS level of the signal then you will need to calculate this at some point, either before sending to PC or afterwards.

Your amplifying circuit as shown is not ideal, but should work reasonably for a basic VU meter. EDIT - I just noticed C2, remove this as it will block the DC bias from the transistor, and the signal will swing below ground.

EDIT - here's a better circuit for the amplifying transistor:

Electret amp

This shouldn't care too much about the transistor used, the output bias should be around 2.5V.
The exact values for the input divider (R3 and R4) are not too important, it's the ratio of 1:4 that's more so. So you can use e.g. 400k and 100k, or 40k and 10k, etc (try not to go above or below these respective values). C2 should be >10uF. C1 should be >1uF (replaces C1 in your schematic)
R1 and R2 do need to be these values though.
All you need is the electret with it's bias resistor (R1 in your schematic)

One point of concern is the Arduino 3.3V and 5V lines seem to be tied together - I'm assuming this is a schematic error, but if this is the case in the actual circuit it will not work, and may damage something.
To pinpoint the problem(s) it would help to see your code, and what you are seeing on the PC side. Also what transistor are you using?

If you have an oscilloscope, then you can check to see if your mic/transistor are working correctly. If not, then a multimeter can be used to perform some more basic tests (e.g. confirm +5V present, confirm base of transistor is at ~0.6V, test collector to make sure it's not pinned to +5V or ground with no signal present)

Also you need to make sure the RS232 is working correctly, so writing some simple code to send some test values would be a good idea.

If you can provide the requested info, and let us know what tools you have available more specific help can be given.

EDIT - if you are sampling so slowly, then you will need a peak detect circuit like this:

Peak Detect

You would put this circuit in between the transistor and the Arduino pin (minus C2)

The diode can be just about any diode. The cap and resistor values are just a guideline, they can be changed a bit. Their values dictate how long the voltage will take to change with the signal level. You can calculate this using the RC constant (i.e. R * C - in the above example, the RC constant is 1e-6 * 10e3 = 10ms. The voltage will take around 2.3 time constant to fall by 90% of it's original value, so in the above example if the voltage starts at 1V and you remove the signal, it will have dropped to 0.1V around 23ms later.

EDIT - okay, think I found a major problem. Your S9012 transistor is a PNP transistor (as is the S9015), you need an NPN transistor for this circuit. The S9014 is an NPN transistor, so you will have to use this one.

The capacitors marked "104" are almost certainly 0.1uF ceramic capacitors. The value (in pF) is the first 2 numbers followed by a number of zeros set by the last number. So for 104, the value is 10 + 4 zeros, or 100,000pF. 100,000pF is 100nF or 0.1uF.

EDIT - Not having a scope or multimeter makes life very difficult here (you should get hold of one or both as soon as you can)
However, there are some basic PC soundcard oscilloscopes that could be used to test your electret/transistor circuit. Visual Analyser is quite a good example:

Visual Analyser

If you replace C2 (not strictly necessary but a good idea), you should be able to feed the signal into the PC directly and observe in the software to see if the microphone and amplification are working correctly. If your PC has line in use that, but the microphone input is usually good for up to 2V IIRC. You could also test the electret directly - just remove the transistor bit and keep R1 and C1, take signal from the other side of C1.
Note that this method will not test the DC levels, only the AC (due to a DC blocking cap in the souncard input) but the AC (audio) signal is what you are interested in here.

If you try this, post the screenshots so we can get an idea of what's happening.

Oli Glaser
  • 54,990
  • 3
  • 76
  • 147
  • 3.3V and 5V are not tied together. Its the first time I'm using this software - sorry. I will put my code in the question but there is nothing that could go wrong with it. Also, i made a project today that uses a photoresistor and displays the value on six leds like i want my vu meter to look like and I tested the serial connection with that. I have neither an oscilloscope nor a multimeter. The transistor has the caption "S9012 H 331" I also have "S9014 C 331" and S9015 ones. – Toast Jul 29 '12 at 23:26
  • @Toast - see edit about C2, remove this and connect directly. – Oli Glaser Jul 30 '12 at 00:16
  • I removed C2 and added the parts as Kristoffon described it in his answer. Still the same results. – Toast Jul 30 '12 at 00:27
  • @Toast - it's very difficult to debug this without a scope or multimeter. Your values of 1024 show the voltage is clamped at the supply voltage. This may be due to the transistor being biased incorrectly - check the resistor values (colour bands) carefully. You want the output to be at 1/2 the supply voltage with no signal present. With the peak detector, the voltage should vary between half and the supply voltage and full when the signal is turned up. – Oli Glaser Jul 30 '12 at 00:42
  • After replacint the transistor with another one the value is 54. I added the circle as described in the image. You can see the resistors I used on the photo I uploaded. Im pretty sure they are correct. Also, I haven't figured out yet how to determine a capacitors capacity. The two ones I'm using right now have the caption 104. – Toast Jul 30 '12 at 00:54
  • 1
    If you have a potentiometer or a variable voltage source, you can apply a 0-5V input to the input of the ADC to test your code, independent from your input circuit. You are trying to debug two things at once -- isolate the circuit and verify its behavior using an oscilloscope and/or isolate your code and provide a predictable but variable input to validate your code. – HikeOnPast Jul 30 '12 at 01:22
  • @DeanB - good idea, backing up a few steps here and confirming each part individually would probably help a lot. The pot is a simple/easy test that can confirm the ADC is working correctly. – Oli Glaser Jul 30 '12 at 01:57
  • @Toast - the transistor you are using is incorrect, see edit to answer. – Oli Glaser Jul 30 '12 at 02:06
  • I changed the transistor and made sure that the serial connection and the code are working. But I don't know if the microphone works. – Toast Jul 30 '12 at 12:28
  • I also tried another microphone with the same result. But both with both microphones I dont get a signal if I test them with a computer, although I dont know if I did that right. – Toast Jul 30 '12 at 13:05
  • @Toast - try changing R3 to 1k. – Oli Glaser Jul 30 '12 at 15:47
  • I bought a multimeter. Where should I measure? – Toast Aug 06 '12 at 14:26
  • Start by measuring the DC voltage at the collector of the transistor (without any significant input at the mic) You want it to be somewhere around half of the supply voltage, so +2.5V for a 5V supply. – Oli Glaser Aug 06 '12 at 14:59
  • @Toast - see edited answer for alternative circuit. Try this if you are still having issues. – Oli Glaser Aug 06 '12 at 15:29
  • Do I have to measure the voltage between ground and the collector? (that is 0) – Toast Aug 09 '12 at 19:16
  • Yes, between ground and collector. If it's 0V then your transistor is turned full on, or you have some other problem. Which circuit are you using? Disconnect from ADC input while to test, just in case you have the pin set to output low accidentally. – Oli Glaser Aug 09 '12 at 19:18
  • I tested it with the circuit in the quetion with the changes you and Kristoffon suggested. I will now assemble the circuit in your answer and then report the results. – Toast Aug 09 '12 at 19:44
  • The other pin of the microphone goes to ground, right? – Toast Aug 09 '12 at 19:52
  • I don't have any capacitors higher than 104 (0.1uF). I used them in your circuit and it doesn't work. The collector (and analog0 pin) voltage is 5V and the arduino reads 1023. – Toast Aug 09 '12 at 20:29
  • 0.1uF caps shouldn't cause a bias problem, they will just roll off the lower frequency gain. The circuit should work as shown (as should the other one too) so it must be a mistake you have made somewhere. Could you update your question to show *exactly* what circuit and components (transistor part number, capacitor/resistor values, etc) you are currently using? Also, measure all voltages relative to ground and mark on the schematic (e.g. base to ground, collector to ground, emitter to ground, etc) If we work through this methodically we are more likely to find the problem. – Oli Glaser Aug 09 '12 at 21:21
  • This is my result: [link](http://s.gullipics.com/image/o/e/x/4o7qff-jb1j5v-060b/v.png) The resistor values are the same as in the circuit, the capacitor values are both 0.1 uF ("104"), the transistor is a "S9014" (NPN) tansistor. The parts are from [here](http://www.ebay.com/itm/170842945777). I have two microphones available, one from disassembling a toy, one out of a headset (I'm quite sure this one works, but I'd be happy to find a way to test them) – Toast Aug 10 '12 at 20:56
  • Okay, there's a problem at the base of the NPN. R3 and R4 should be connected to the base. The voltage should be around 0.7V at the base. The fact that it's 0V tells us there is a bad (or incorrect) connection or possibly the transistor is faulty. Without the transistor plugged in, the voltage between R3 and R4 should be around 1V. Check carefully and let me know how it goes. – Oli Glaser Aug 10 '12 at 21:18
  • Okay, I found a mistake. R3 was "missing" (shame on me). Here are the [new values](http://s.gullipics.com/image/u/w/3/4o7pg3-jb2x0u-r43d/v2.png). – Toast Aug 11 '12 at 14:44
  • Okay, no problem. That looks a bit better, but something's still wrong. The voltage at the base should be around 950mV and the voltage at the top of R2 should be around 250mV. My suspicion is one or more of the resistor values is wrong - can you check them all using the multimeter? (add the values to the schematic if you can) – Oli Glaser Aug 11 '12 at 19:42
  • I checked the resistor values with the multimeter and they are the same as on the schematic. For R3 I'm using a series of 4 10k resistors. – Toast Aug 11 '12 at 21:54
  • Hmmm, I'm a bit puzzled as unless your transistor has very little gain it should work. You could maybe try changing it for another one of the same type (NPN) and see if it's better. You want a collector voltage of around 2.5V (you are using 5V - if not you should be for these values) One thing you can try is instead of R3, use a 50k or 100k potentiometer and vary it whilst watching the collector voltage - if you can set it for 2.5V, measure the resistance across it. If you only have say a 10k pot, then use it in place of one of the 4 10k resistors. – Oli Glaser Aug 11 '12 at 22:44
  • R3 is now a 50kΩ potmeter. When set to 4200Ω the collector voltage is 2.5V (512 at the A0 pin). Still not reacting to music. How can I check if the microphone is working? – Toast Aug 13 '12 at 20:57
  • Sounds like you have a 1k resistor for R4 then. This will probably still work to some extent, but will present a bit too low of an impedance for the electret signal. Better to use a 10k (or above) for R4. Make sure you still have the 2k resistor on the electret side (not shown on my schematic) TO check if the mic is working sample as quickly as you can (e.g. sample at least every 1ms, preferably faster) and speak loudly into the electret. You should see some variation. You could also monitor the collector signal with your multimeter on AC (low range) Probe from collector to ground. – Oli Glaser Aug 14 '12 at 04:20
  • R4 is actually a 10k resistor. Where does the 2k resistor go? I assumed the other microphone pin just goes to ground? – Toast Aug 14 '12 at 10:21
  • Somethings very strange then - are you sure you have the transistor the right way round? Sorry, I meant the 10k resistor (R1 in your schematic) for the electret. The other electret pin does go to ground - it has to be the right way round though to work properly, so make sure it is. It might be useful for you to update your question and post another picture of your current setup. – Oli Glaser Aug 14 '12 at 11:24
  • 1
    @OliGlaser I am confused by the circuit. The "electret" is a microphone? Where does the other wire of the microphone go, GND or VCC? Do I connect 5 or 3.3V to that circuit? Could you please somehow remove the `EDIT` blocks and edit it so that it can be understood without reading the comment thread? I am also a beginner and I don't understand how the problem was solved and whether I can use the circuit you posted as-is. – Tomáš Zato Mar 14 '16 at 09:54
4

Assuming your circuit works the audio signal is in the kHz range while the Arduino has an ADC suited for DC levels. The DC component on your signal is zero which is to say that it floats over a fixed voltage. It is that fixed voltage that your ADC is reading.

To fix that you would put a diode in series with your output connecting to the ADC and to a capacitor and resistor.

The cap will charge to the peak value being received while the resistor will discharge the cap when the signal dies down.

--|>|---*---- adc
        *---- resistor -----*----ground
        \----- capacitor ---/

Edit: The ADC input is actually floating as it has no bias whatsoever due to the series capacitor. If you're going to try my solution delete C2.

Kristoffon
  • 368
  • 1
  • 6
  • Okay, I added this to the circuit and the signal on the serial monitor now is 458 (but still doesn't change when there is noise). – Toast Jul 29 '12 at 23:51
  • I exchanged the transistor from "S9012 H 331" to "S9014 C 331" and the value is 56. – Toast Jul 29 '12 at 23:53
  • 1
    The Arduino ADC is capable of sampling fast enough for audio. I don't use them, but I think 10ksps (so up to 5kHz bandwidth) is possible with the library functions, which is fine for lo-fi stuff (I'm pretty sure the actual ATMega can sample faster if used normally) – Oli Glaser Jul 30 '12 at 00:10
  • @Toast - how fast are you sampling? If it's very slowly then the peak detector is a good idea. You can do this in software though. – Oli Glaser Jul 30 '12 at 00:13
  • I did a 300ms delay. But i tested it without delay or with short delay but the signal does not change significantly. – Toast Jul 30 '12 at 00:22
  • @OliGlaser clearly you never tried doing that then or you'd know those specs are unrealistic because while you may actually be able to get 10ksps you will be getting garbage readings and if you want that cheap adc they stuff into the microcontroller to give you more than 4 bits worth of data you wont be doing more than 1 ksps ever. – Kristoffon Jul 30 '12 at 01:14
  • 2
    @Kristoffon - Not with an Arduino no, but I have used similar 8-bit micros (e.g. PIC16F, 18F, etc) for sampling and playing back audio many times. 10ksps is easily doable. To quote [this AVR ADC document](http://www.atmel.com/Images/doc2559.pdf): `When using single-ended mode, the ADC bandwidth is limited by the ADC clock speed. Since one conversion takes 13 ADC clock cycles, a maximum ADC clock of 1 MHz means approximately 77k samples per second. This limits the bandwidth in single-ended mode to 38.5 kHz, according to the Nyquist sampling theorem.` – Oli Glaser Jul 30 '12 at 01:46
  • Also, if you check the [ATmega328 datasheet](http://www.atmel.com/Images/doc8161.pdf), you can see the same specs listed in the ADC section (page 323). It mentions an absolute accuracy of 2LSB at 200kHz (~15kHz sample rate) – Oli Glaser Jul 30 '12 at 01:54
4

Your readings of 1022, 1023 are basically full scale on the Arduino's ADC. Assuming you installed a non-faulty series capacitor as shown in your diagram, this level cannot be coming from the microphone circuit you built, since that can only couple changing voltages (ie, AC).

As a result, I suspect you are reading leakage current within the ATMEGA itself - you would probably get the same result on any of the other (unconnected) analog pins.

Try making a very "lightweight" voltage divider with some high value resistors (between 10K and 100K) and use this to bias the analog input to half the reference voltage (you could also use a potentiometer, which gives you some extra testing capability). Then your reading with no input should be in the neighborhood of 512.

Once you have the ADC input suitably biased, you can start working trying to see if you get variation through it. You may be undersampling your bandwidth some, which means you will get aliasing of high frequency components, but if all you are trying to do is estimate overall volume that should not be too much of a problem.

Chris Stratton
  • 33,282
  • 3
  • 43
  • 89
  • That sounds right, I guess it's overloaded. OP have you thought of connecting a small speaker to debug that analog line your reading. When I made a vu meter I took the lines from a headphone jack, basically straight into the AnalogRead and Mapped out the resulting. – Hellonearthis Jul 30 '12 at 10:15