Preamp Mic with Goertzel Frequency Algorithm

Heey!

Me and a buddy are having a school project. The project is that we are going to do one or more LEDs that flash to bass tones. But it was harder than we thought! At start (before we started to code) we thought that the analog signal from the microphone already was in frequency but it was in amplitude?

We are basicly new to programming and we are here to learn so please dont rage if you see we did something retarded in your opinion. :slight_smile: (We have only a basic course experience.)

What we have found out is that the simplest way to do this is to use Goertzel algorithm to find bass tones. This is what we found about Goertzel algorithm that we think we need:

double tandemRTgoertzelFilter(int sample, double freq) {
    static double s_prev[2] = {0.0,0.0};
    static double s_prev2[2] = {0.0,0.0};  
    static double totalpower[2] = {0.0,0.0};  
    static int N=0;       
    double coeff,normalizedfreq,power,s;
    int active;
    static int n[2] = {0,0};
    normalizedfreq = freq / SAMPLEFREQUENCY;
    coeff = 2*cos(2*M_PI*normalizedfreq);
    s = sample + coeff * s_prev[0] - s_prev2[0];
    s_prev2[0] = s_prev[0];
    s_prev[0] = s;
    n[0]++;
    s = sample + coeff * s_prev[1] - s_prev2[1];
    s_prev2[1] = s_prev[1];
    s_prev[1] = s;    
    n[1]++;
    N++;
    active = (N / RESETSAMPLES) & 0x01;
    if  (n[1-active] >= RESETSAMPLES) { // reset inactive
        s_prev[1-active] = 0.0;
        s_prev2[1-active] = 0.0;  
        totalpower[1-active] = 0.0;  
        n[1-active]=0;    
    }
    totalpower[0] += sample*sample;
    totalpower[1] += sample*sample;
    power = s_prev2[active]*s_prev2[active]+s_prev[active]
       * s_prev[active]-coeff*s_prev[active]*s_prev2[active];
    return power / (totalpower[active]+1e-7) / n[active];
}

Source: Efficiently detecting a frequency using a Goertzel filter | Networking Embedded Systems

We dont know is how to put it in the Arduino code. If someone could explain how to use this code and show which value who is output and input etc.. I've searched but have not found anything.

We did a code for amplitude and we aren't happy about it cuz it doesn't do what we had in our minds when we started the projekt.. I will post it anyway if you have any suggestions to improve it.

const int pinMic = A0; //Analog input.

const int pinLED0 = 7; //digital output LED 0
const int pinLED1 = 8; //digital output LED 1
const int pinLED2 = 12; //digital output LED 2

int count = 0;
int valBaseline;
int delayLED = 0;


void setup() {
    Serial.begin(115300); 

    pinMode(pinLED0, OUTPUT);
    pinMode(pinLED1, OUTPUT);
    pinMode(pinLED2, OUTPUT);
    pinMode(pinMic, INPUT);
}

void loop() {
  
  ++delayLED;
  int valMic = analogRead(pinMic); 
  Serial.println(valMic);  

  int valBaseline = valMic * 0.8;

    if (valMic > valBaseline + 108){ 
      digitalWrite(pinLED0, HIGH);
        if (valMic > valBaseline + 110){
          digitalWrite(pinLED1, HIGH);
             if (valMic > valBaseline + 112){
               digitalWrite(pinLED2, HIGH);
             }
         }
     }
        
    if(delayLED > 20){
      digitalWrite(pinLED0, LOW);
      digitalWrite(pinLED1, LOW);
      digitalWrite(pinLED2, LOW);
      delayLED = 0;
    }
}

Feel free to ask anything! I've probably missed something.

Sorry for the awful English... :blush:

Well before you worry about the software signal analysis method how are you handling the electrical interface from the microphone to the analog input pin? You know that audio is an AC voltage of variable amplitude and frequencies, right? An arduino cannot safely measure the negative portion of an AC signal, just DC voltages in the range of 0 to +5vdc. Also a microphone without additional amplification outputs a very small AC voltage range just some millivolts. So how is your electrical part set-up so far?

Lefty

Thanks for the fast reply!
I havn't thought about that. Ye, I know that the audio is a voltage of variable amplitude and frequencies. But I'm not so into the AC/DC part... We made a amplifier to the mic and it works good with amplitude. But do we need other amplifier to sample frequency?

This should be the same amplifier as we have at the moment: http://www.electrokit.com/mikrofonforstarkare.46099

Stronk:
Thanks for the fast reply!
I havn't thought about that. Ye, I know that the audio is a voltage of variable amplitude and frequencies. But I'm not so into the AC/DC part... We made a amplifier to the mic and it works good with amplitude. But do we need other amplifier to sample frequency?

No your understanding of electronics is lacking. The audio signal from the microphone contains both the amplitude information and the frequency information. Your software will have to perform the various extraction methods of the information you seek from the composite audio AC signal.

This should be the same amplifier as we have at the moment: http://www.electrokit.com/mikrofonforstarkare.46099

Well that amp lists it's output voltage as 300 millivolts max from the microphone signal. That means if will not use up much of the voltage measurement range of an arduino analog input pin which is 0-5vdc, so you are only going to have 6% of the measurement range in effect. Also the 300 millivolts is still an AC voltage and again an arduino pin cannot safely measure the negative portion of a AC signal without risking damage to the input pin. A 300 millivolt signal means the voltage can vary anywhere within a +150 millivolt to a -150 millivolt range, and the arduino analog input pin cannot handle the 0 to -150 millivolt part. So usually you will see a opamp buffer stage added to allow a DC offset value to be added to the AC signal such that the total positive and negative peaks values of the audio signal are contained within a DC 0-5vdc range.

I only bring these issue up because before you can have any success with your software methods you first must have the electrical interface proper or you will just end up with a lot of frustration as garbage in will always result in garbage out. I would suggest you search the web for projects that already perform what you are trying to do and look at how they handled both the electrical side and the software side.

Good luck;

Lefty

I know it is fun to do your own FFT, but this chip does all the work for you, too bad it is backordered:

retrolefty:

Stronk:
Thanks for the fast reply!
I havn't thought about that. Ye, I know that the audio is a voltage of variable amplitude and frequencies. But I'm not so into the AC/DC part... We made a amplifier to the mic and it works good with amplitude. But do we need other amplifier to sample frequency?

No your understanding of electronics is lacking. The audio signal from the microphone contains both the amplitude information and the frequency information. Your software will have to perform the various extraction methods of the information you seek from the composite audio AC signal.

This should be the same amplifier as we have at the moment: http://www.electrokit.com/mikrofonforstarkare.46099

Well that amp lists it's output voltage as 300 millivolts max from the microphone signal. That means if will not use up much of the voltage measurement range of an arduino analog input pin which is 0-5vdc, so you are only going to have 6% of the measurement range in effect. Also the 300 millivolts is still an AC voltage and again an arduino pin cannot safely measure the negative portion of a AC signal without risking damage to the input pin. A 300 millivolt signal means the voltage can vary anywhere within a +150 millivolt to a -150 millivolt range, and the arduino analog input pin cannot handle the 0 to -150 millivolt part. So usually you will see a opamp buffer stage added to allow a DC offset value to be added to the AC signal such that the total positive and negative peaks values of the audio signal are contained within a DC 0-5vdc range.

I only bring these issue up because before you can have any success with your software methods you first must have the electrical interface proper or you will just end up with a lot of frustration as garbage in will always result in garbage out. I would suggest you search the web for projects that already perform what you are trying to do and look at how they handled both the electrical side and the software side.

Good luck;

Lefty

KeithRB:
I know it is fun to do your own FFT, but this chip does all the work for you, too bad it is backordered:
Graphic Equalizer Display Filter - MSGEQ7 - COM-10468 - SparkFun Electronics

Hehe, I know my understanding of electronics is lacking. It's our first time we do something like this practical in school... And we've never done anything with microphones and amplifiers... No wonder? But we're still going to do this because we want to learn!

So what I've understand is that we need a stronger audio signal from the amplifier who can do 0-5VDC and not 0-0.3VDC as our does? And to to that easy, is to replace the chip to something that KeithRB mentioned? Again, electronics are sadly not our best section... We suck at it.

According to the data sheet you need about 100 mV peak to peak to drive the chip. So some gain from the mic might be required. Use a scope to see how much you are getting now.

Another H/W tip would be to use a low pass filter so that your only getting the Bass. You really won't get any where until you do get AC/DC. You could also check out op-amps to shift the voltage level and as just an amp. You may won't to look at 5v single rail op-amps as well as the 741's that you will see in the books.

Write up EVERY thing you try with your results. Wrong methods discarded with your logic for doing so will score points.

Good luck,

Mark

KeithRB:
According to the data sheet you need about 100 mV peak to peak to drive the chip. So some gain from the mic might be required. Use a scope to see how much you are getting now.

This is the values I got when I measured the voltage level. Am I doin it right or what? :roll_eyes:

Measure results microphone with amp:
Output(Power):
AC = 10.1V?
DC = 4.8 V

Input (Analog in A0):
AC: 4.5V
DC: 2.4V

What do you say? What's wrong and what needs to be different to make it work properly?

holmes4:
Another H/W tip would be to use a low pass filter so that your only getting the Bass.

We are going to add some more functions such as treble later so we dont wanna put a lowpass filter in. Right now we focus on bass because we need to be finish before Christmas...

You really won't get any where until you do get AC/DC. You could also check out op-amps to shift the voltage level and as just an amp. You may won't to look at 5v single rail op-amps as well as the 741's that you will see in the books.

Write up EVERY thing you try with your results. Wrong methods discarded with your logic for doing so will score points.

Good luck,

Mark

We'll try to get the voltage level right but we find it very hard because we don't know much electricity... Thanks for the tip, will check that out! We are writing down every step we make under our progress:)

Our understanding in technical English suck as well. Again, can someone explain what's wrong with the voltage level in a easier way?

Measure results:
Output Power (Arduino -> Amp):
AC = 10.1V?
DC = 4.8 V

Input Analog A0 (Amp -> Arduino):
AC = 4.5V
DC = 2.4V

Since you only care about measurements, not fidelity, the negative half of the signal can simply be clipped with a diode (half wave rectification). And a single transistor amp stage ought to suffice to get the signal into proper Arduino sensing territory.

Thank you!

can someone explain what's wrong with the voltage level in a easier way?

The ac signal's negative is being clicked by the clamping diodes so you only see the positives.

dhenry:

can someone explain what's wrong with the voltage level in a easier way?

The ac signal's negative is being clicked by the clamping diodes so you only see the positives.

Thank YOU! :sweat_smile: I finally know what's actually wrong. And thanks all you other people who tried to help, you all brought something useful up!

Now we just need to put that algorithm in. Is it someone who can explain that part too?

One more question at the microphone part.

Should this Opamp be a better choice? Should this work good for our type of usage?

Instead of our preamp:
http://www.electrokit.com/mikrofonforstarkare.46099.

Does it work if we only replace the chip in our preamp to: