Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

new to Ardunio but trying to compile

Status
Not open for further replies.
-Les,
The mic preamp module he's using has a DC bias added to it (VCC/2) so that the output is always positive V.
As long as the module and ADC have the same VCC this should give an ADC value approx half-scale (512) when there's no sound.
I was joking about adding the rectifier to the positive-voltage only output since the posts never seem to be read.

-Jon,
Didn't mean to confuse things. All I meant was that the offset isn't going to be exactly 512 so it would be better to measure the
output with no sound and use that value as the offset, but at this point that's likely overly complicating things.
 
Visitor, I think it is a good way to solve the problem with minimal hardware. My point is the TS does not seem to read replies and UNDERSTAND them.
I would do it differently by using an active rectifier followed by a low pass filter but I would not suggest it in this case as it would be too difficult for the TS to understand.

Les.

Essentially he needs a VU meter circuit, which would give a DC voltage output dependent on the audio level.

Here's one such example:

 
Yeah, maybe, but he's probably already spent enough money on this. He's already switched platforms, bought multiple modules, etc.

What he has should work, it's just that unless there's example code given that works pretty much exactly as he needs this is all a fruitless exercise.
 
Well your half right. This is what I have so far BUT changing the volume dosen't seem to have much effect.
values are 70-75
low volume = 70 am still adjusting the values for the leds. Have adjusted the gain on the amp and dosen't have any effect. contemplating using the LM386 module to see if any difference. Even contemplated a pot on the amp output?
high = 74-75
Code:
[code]
const int MIC = A0; //the microphone amplifier output is connected to pin A0
int adc;
int dB, PdB; //the variable that will hold the value read from the microphone each time

void setup() {
Serial.begin(9600); //sets the baud rate at 9600 so we can check the values the microphone is obtaining on the Serial Monitor
  pinMode(2, OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(4,OUTPUT);
}

void loop(){

  PdB = dB; //Store the previous of dB here
 
adc= analogRead(MIC); //Read the ADC value from amplifer
//Serial.println (adc);//Print ADC for initial calculation
dB = 20 * log10 (analogRead(MIC)/ 0.1); //Convert ADC value to dB using Regression values

if (PdB!=dB)
Serial.println (dB);

if (dB>70)

  digitalWrite(2, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(200);                       // wait for a second
  digitalWrite(2, LOW);

//delay(10);
if (dB<70)
digitalWrite(3,HIGH);
delay(200);
digitalWrite(3,LOW);
if (dB<60)
digitalWrite(4,HIGH);
delay(200);
digitalWrite(4,LOW);
}
[/CODE]
 
Remember where I suggested you print out the ADC value AND the dB value? To see if anything makes sense? Twice?

Don't try to do ANYTHING beyond printing out numbers at this point. If you have GARBAGE IN, you can't expect anything but MORE GARBAGE OUT.

And you have absolutely ignored the entire discussion about the analog output being biased at Vcc/2, and the need to deal with that.

Perhaps we should try something new. If you don't understand something, rather than ignoring it, ask questions? I know it's a difficult concept you have avoided all these years....

As a first step, please go back to where I suggested you get rid of all the garbage and do three simple commands:

Read the ADC count

Convert the ADC count to dB

Print the ADC count and the dB value.

This is the first tiny step to see if you are actually getting data. Nothing else matters until you see believable data.
 
I did that but the numbers don't seem to change when changing volume but will run it again
Code:
[code]

const int SoundIn = A0;
void setup()
{
  Serial.begin(9600);
}
// put your setup code here, to run once:
void loop()
{
  int val = 20 * log10(analogRead(SoundIn)) / 0.1;

                       Serial.print(val);
                       Serial.println("db = ");
}
[/CODE]
 
Let's see if we can inch this process along. PLEASE read the comments on EACH line and understand what's happening.

Try this, and POST THE OUTPUT.

Code:
const int SoundIn = A0;


void setup() {
  // put your setup code here, to run once:

  Serial.begin(9600);
}


void loop() {
  // put your main code here, to run repeatedly:

  int ADCValue = (analogRead(SoundIn)) ;          //this line reads the ADC input into the variable ADCValue

  int dBValue = 20 * log10(ADCValue);                //this line calculates the dB level of ADCValue and puts it in the varialbe dBValue

  Serial.print("ADC count: ");                                //this line, with the "print" command prints the label "ADC count: " and leaves the cursor at the end of the line
  Serial.print(ADCValue);                                     //this line prints the value of ADCValue where the last line left off and leaves the cursor at the end of the line
  Serial.print("     dB level: ");                               //this line prints the label "    dB level: " and leaves the cursor at the end of the line
  Serial.println(dBValue);                                     //this line, withe the "println" command prints the value of dBValue at the end of the line, and moves the cursor to
                                                                            //the beginning of the next line for the next measurement

  delay(100);                                                        //this line delays for 0.1 second before the process repeats
}

//Code courtesy of Jon, to inch the process along
 
I increased the delay to 2000 so I can read the output
461=53db
510 = 54db
497=53db
499=53db
484=53db
529=54db
these are pretty much in a quite room next to computer.
thinking averaging and taking say 100 samples then averaging? Just a thought.
 
Please take a Screen shot and post it with your code. And a picture of the board you are using and connections.
 
put on CCR music and adjusted volume up and down but readings stay about the same.

How much is "about the same"? Show some output please.

I've been burned too many times by accepting things at face value from MrDEB.
It's not that he's trying to be deceptive; he just doesn't appreciate what's significant.
 
Crank the gain trim pot all the way up, and sample as fast as you can, not just once in 2 secs. The serial terminal should buffer a few screens of readings which you can look at later.

From the description:
With it turned down, normal speech will only give about 200mV PTP change, so if you're running the module at 5V that's a change of about 40 counts (512 +/-20).
With it cranked up they say about a 1V PTP change, which is more like 200 counts.

The module looks to be a ripoff of the one from Adafruit https://www.adafruit.com/product/1063
 
I'm trying to decipher what's going on here. So please answer the following questions.

From post #149:

>Are you using the purple module with a MAX4466 chip?

>What are the connections made to this module? be specific.

>You said you're getting readings over 500dB with the code from post #136:

I had originally suggested this equation:

dB = 20 * log10(ADCReading/0.1) to shift the dB reading up 20dB from zero, but later said leave out the 0.1 division.

Your code in #136 is

int val = 20 * log10(analogRead(SoundIn)) / 0.1;

The 0.1 divisor is outside of the log function. So instead of shifting the dB level up 20dB, it multiplies the dB level by a factor of 10.

If you had printed out the ADC count AND dB level as suggested, this error would have been apparent, as the ADC count would have been about 500, which should have resulted in a dB level around 50. You need to print both to verify the math.


From Post #164

You changed code versions. Now your dB function is:

dB = 20 * log10 (analogRead(MIC)/ 0.1); //Convert ADC value to dB using Regression values

The comment has nothing to do with this code. But more importantly, this time the 0.1 divisor is within the log calculation instead of outside of it. study this until you see the difference! When you change code versions, all the work anybody has done to understand what you're doing has turned to garbage.


From Post #166

You switched back to the first version of the software, introducing the error again.

int val = 20 * log10(analogRead(SoundIn)) / 0.1;

Study this until you see the difference. Please understand that trying to help is is futile if you keep switching versions of the software.


Post #169

I am assuming you are using my code from post #168. Please keep using this code to print out the ADC value and dB value. We must see both numbers to verify operation.
 
thinking averaging and taking say 100 samples then averaging? Just a thought.
This is what I said... BUT!! there are better audio buffs out there than me.. Audio is from couple of hertz to to 8 Khz ( for older farts like the majority here, including me )

So! they recommend twice the frequency.... That is 16000 samples a second.. Well.. That's DSP territory, So try and sample 24 times on the trot. divide average that down to 12bit by dividing by 6... do that say five times a second... add the running totals and divide by 5... you will have a "kinda" averaged volume over a second period...

In Jons code, there is a 100mS delay... Just use that time to just sample...
 
I'd go with Nigel's VU meter solution. Slow time constant - 1/10 second. Average done in hardware. Simples.

Mike.
 
As Tumbleweed pointed out earlier on, sampling an audio waveform at random times will always give a mean value centred somewhere around the zero bias point.

Averaging "raw" ADC samples will have the effect of removing the signal and leaving just the DC bias level; never any useful audio or "level" data.

It needs the _difference_ between the sample value and the DC level. like
Code:
level = abs(adc_sample - 512);
(Assuming the ADC reading is 512 with no signal).

And preferably, batches of a few hundred samples taken at some thousands of samples per second (as Ian says), with each sample differenced and the sum or mean of each batch used as the basis of any further level calculations,

Or just use an external VU meter module to get a simple "level" voltage for the ADC, then work from that.
 
All the comments regarding proper ways of dealing with the signal have some validity, however, before moving ahead, making sure there is a real signal is an extremely necessary step.

So far in this thread, we have:

▪︎ Attempted to take analog data from a comparator output.

▪︎ Flip-flopped between

dB = 20 * log10 (ADCValue) / 0.1 and

dB = 20 * log10(ADCValue / 0.1)

▪︎ Varied the gain on the mic amplifier by a factor of 5 with no effect reported.

Observing some reasonable change in the raw signal corresponding to reality is a necessary first step.

Taking measurements at a high rate, and looking at peak values (not average values) in the samples will verify the following:

▪︎ Reasonable levels at approximately Vcc/2 in a quiet condition.

▪︎ A reasonable response in levels in a noisy condition. Put a blender on high speed near the mic and look at the peak levels.

▪︎ The function of the gain pot. With the blender near the mic, rotation the pot from one extreme to the other while observing peak values in the data.

Determine which direction is minimum gain
and which is maximum.

Determine if maximum gain is too much
with the blender as a noise source.


Once it's been determined that reasonable measurements are being made, then discuss what to do next.
 
MrDEB,

Here's what I suggest you do now.

From my code in #168, temporally comment out the three Serial.print lines shown below. The only thing you want to print is the ADCValue, the second print line. Also comment out any delay statements. You want to take readings as fast as possible.

Code:
//Serial.print("ADC count: ");                                //this line, with the "print" command prints the label "ADC count: " and leaves the cursor at the end of the line
  Serial.print(ADCValue);                                     //this line prints the value of ADCValue where the last line left off and leaves the cursor at the end of the line
 // Serial.print("     dB level: ");                               //this line prints the label "    dB level: " and leaves the cursor at the end of the line
//  Serial.println(dBValue);                                     //this line, withe the "println" command prints the value of dBValue at the end of the line, and moves the cursor to
                                                                            //the beginning of the next line for the next measurement

With a quiet room, start the serial plotter from the Arduino menu where you start the serial monitor.

arduino serial plotter.jpg


Let this run until the plot is full and screen capture it. It will look sort of like this:

data plot.jpg


Look at the highest and lowest peaks and write down the numbers, In the case above, the highest peaks are around 1000, the lowest close to zero. In a quiet room, they should be close to 512.

Next, put a constant noise source near the microphone. Blender, vacuum cleaner. Something loud and constant. Rotate the pot all the way in one direction and make another graph. Write down the largest and smallest peaks again. The numbers should be greater than what you got when it was quiet.

Rotate the pot all the way the other direction and do it again. The numbers will be bigger if the pot is set for maximum gain; if they are smaller, the pot is set for minimum gain.

With the noise source going, the desirable outcome is a graph sort of like the above. Some peaks should reach 1023, some should reach zero. Just some though. If the many of the peaks reach 1023 and zero, turn the gain pot to reduce sensitivity.

Let us know the results.
 
It would be ideal to log the print data, but the Arduino serial monitor has no provision to do that. Other terminal software could be used to do so, but that further complicates the issues. But the serial plotter should suffice.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top