3
\$\begingroup\$

I have built the following circuit based on a proven MSGEQ7 based circuit design, which comes from the datasheet and elsewhere on the internet. I have built and coded to this circuit previously, with a 5V power supply, no problem.

enter image description here

The audio input is a sparkfun electret microphone breakout board with onboard op-amp-based amplification circuit. This too, I have successfully used on a previous project hooked up to the MSGEQ7. It worked fine there, but at that time I used an Arduino 3.3v pin to power this (here both the MIC BoB and the MSGEQ7 are on 3.3V rails).

The only difference between this circuit and the last one I built (that I can tell anyway) is the fact that I'm now running both MSGEQ7 and the BOB off a 3.3V rail.

The circuit "kinda" works, but the analog readings do not seem calibrated properly.

Here is a sample of the the output I'm getting:

RAW EQ      392 406 630 803 842 973 886 
RAW EQ      341 818 936 1022    1022    1022    1021    
RAW EQ      590 812 950 860 1023    1023    1021    
RAW EQ      550 894 1022    1022    1023    1022    1020    
RAW EQ      561 926 953 1023    1023    1022    1006    
RAW EQ      565 805 918 966 1022    1023    1013    
RAW EQ      525 835 1013    999 1023    1023    1022    
RAW EQ      611 862 884 1015    1022    1023    1012    
RAW EQ      541 794 802 849 1023    1023    1012    
RAW EQ      449 759 993 928 1023    1022    1002    
RAW EQ      400 858 1006    1013    1023    1022    1015    
RAW EQ      460 876 934 1023    1022    1023    1013    
RAW EQ      617 845 869 976 1023    1022    1022    
RAW EQ      729 814 981 1023    1023    1022    1015    

As you can see the last 3/4 bands are all pretty much maxing out!

Here is the relevant Arduino code:

Init Routine

//initialise MSGEQ7 chip
void initMSGEQ7(int analog, int strobe, int reset)
{
#if defined DEBUG
    Serial.println("MSGEQ init");

    Serial.print("Analog Pin");
    Serial.println(analog);

    Serial.print("Strobbe Pin");
    Serial.println(strobe);

    Serial.print("Reset Pin");
    Serial.println(reset);

#endif
//set up MSGEQ7 pins
pinMode(analog, INPUT);
pinMode(strobe, OUTPUT);
pinMode(reset, OUTPUT);
analogReference(DEFAULT);

//turn off comms to MSGEQ7 to start with
digitalWrite(reset, LOW);
digitalWrite(strobe, HIGH);
//prep the MSGEQ7 to read in the frequency bands
digitalWrite(reset, HIGH);
digitalWrite(reset, LOW);   
}

Reading code

//read the EQ
void readEQ(int strobe, int analog, int (&bands)[7])
{
#if defined DEBUG
    Serial.print("RAW EQ\t\t");
#endif

//read in the bands
for (int i = 0; i < 7; i++)
{
    digitalWrite(strobe, LOW);
    bands[i] = analogRead(analog);
    delay(5);
    #if defined DEBUG
        Serial.print(bands[i]);
        Serial.print("\t");
    #endif
    digitalWrite(strobe, HIGH);
}
#if defined DEBUG
    Serial.println();
#endif
}

The question: How do I make this give me readings in a better spread from 0 to 1023 via the Arduino's analog inputs.

I have rebuilt the circuit a number of times, using completely new components (passives, IC, cable and the BoB), the results are the same.

I also have an unregulated 3.7V rail (from a LIPO battery) which I could use -- the 3.3V regulated supply comes from an Arduino Pro Mini 8MHz 3.3V edition which takes in the unregulated 3.7V LIPO power supply.

\$\endgroup\$
  • \$\begingroup\$ What's your current draw between the Pro Mini, the BoB, and the MSGEQ7? The Pro Mini has a mic5205 regulator, 150mA max. (Plus any leds you may be using off the same rail) \$\endgroup\$ – Passerby Jun 6 '13 at 23:45
  • \$\begingroup\$ My LEDs are on the 3.7V unregulated rail-- switched by IRLML2502 MOSFETs. I'm not sure the answer to your question... How will knowing it assist me in resolving the problem? The MSGEQ7 datasheet says 1mA output drive and a 0.8mA typical "supply current". The BoB refers me to datasheets for both the SMD onboard op-amp and the mic itself -- it appears from both of those that the current drawn is no more than 0.5mA (although I could be misreading the datasheets)... \$\endgroup\$ – Brad Jun 7 '13 at 11:28
  • \$\begingroup\$ Did you ground your audio input? I was having the same problem using a 5 pin audio jack. I connected the 5th pin to ground and it worked. \$\endgroup\$ – Stephen F Miller Jun 23 '14 at 22:11
  • \$\begingroup\$ I just hooked up an MSEQ7 to a Teensy3.0 on the 5V rail with a Sparkfun BOB-09964 as input and I'm getting every band showing the same value (but not saturated at 1023—the values bound up and down, but each read all channels are within +/- 3 of each other.) Do you have a schematic of what you ended up with, @brad? \$\endgroup\$ – Robert Atkins Nov 22 '15 at 19:31
5
\$\begingroup\$

Observations from the data:

  • First row of data appears to be a statistical outlier and can be rejected: All readings are lower than the profile for subsequent rows, probably due to start-up behavior.
  • The last band is not saturating, it varies from 1002 to 1022, so it is capturing valid data
  • Bands 4, 5 and 6 are nearly saturated, but are not "stuck to the rail", they do show some variation, so they aren't in a failed, stuck-to-Vcc state

This indicates that the signal generated by the preamplified electret microphone is very high at the frequency bands represented by output 4, 5 and 6. This can be verified using a reverse biased avalanche diode or a zener diode (Vzener > 7 Volts) as a white noise source replacing the electret microphone in the BoB's preamplifier, and checking the output using an oscilloscope in spectrum analysis mode.

This is not surprising at all, as electret microphones are not very linear, and the preamplifier in the break-out board does not have any equalization built in, as per SparkFun's schematic. Hence net result is expected to be a rather non-linear output profile.

The MSGEQ7 frequency response, on the other hand, is pretty linear across bands:

Band response

If the problem just involves getting the signal levels for all bands into usable range, a simple resistor voltage divider to attenuate the incoming signal to perhaps 50 or 75% should do the trick, across all bands. 50% will leave plenty of headroom to capture signal spikes on any band, as will invariably occur with normal audio.

schematic

simulate this circuit – Schematic created using CircuitLab

If it is also necessary to equalize the signal such that the mid-range and tweeter bands are attenuated while the relatively weak woofer bands are not affected, then a circuit such as a bandstop filter can be used, with a very low Q, and the pole frequency between the band-5 (~ 2200 Hz) and band-6 (~ 6000 Hz) frequencies. In effect, this will be more of a "band attenuate" filter, for the problematic bands, with some effect on the lower and higher bands as well:

Band Reject Filter (source)

Such a filter is non-trivial, and perhaps deserves a separate question if required.

\$\endgroup\$
  • \$\begingroup\$ as always, a great answer. Worked a treat! \$\endgroup\$ – Brad Jun 7 '13 at 19:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.