Music visualizer DFMiniPlayer + MSGE7 + WS2812B

Hi Everyone, I'm traying to make my own music led visualizer with MSGQE7, DFMiniPlayer and LED STRING WS2812B 60 LED.
This are all the schema and datasheet that I'm following.

LED STRING
I'm using a laboratory power supply, a resistor of 330Ohm, and a capacitor of 670uF (Reading Adafruit documentation, these are safe values).
LEDPIN = 6, GND in common with Arduino

Adafruit Documentation
image

Instead of using SPK_1/2, I'm using DAC_R/L. These pins are both connected to a jack female (for external speaker) and PIN 5 of MSGQE7,
image

Both DFMini and LED (Adafruit/FastLed) work with their own libraries.

MSGQE7: [datasheet](https://mix-sig.com/images/datasheets/MSGEQ7.pdf)

I'm actually following this schema, but I've connected only DAC_R, so remove L and 1 22 kohm resistor
image

To test this CHIP I'm actually doing this step:

  1. Grounding ADKEY_1 of DFPlayer to start the music

  2. I'm running this code to read all the possible frequencies, but I don't understand if there is something wrong.

int strobePin  = 2;    // Strobe Pin on the MSGEQ7
int resetPin   = 3;    // Reset Pin on the MSGEQ7
int outPin     = A0;   // Output Pin on the MSGEQ7
int level[7];          // An array to hold the values from the 7 frequency bands

void setup() {
  Serial.begin (9600);
 
  // Define our pin modes
  pinMode      (strobePin, OUTPUT);
  pinMode      (resetPin,  OUTPUT);
  pinMode      (outPin,    INPUT);
 
  // Create an initial state for our pins
  digitalWrite (resetPin,  LOW);
  digitalWrite (strobePin, LOW);
  delay        (1);
 
  // Reset the MSGEQ7 as per the datasheet timing diagram
  digitalWrite (resetPin,  HIGH);
  delay        (1);
  digitalWrite (resetPin,  LOW);
  digitalWrite (strobePin, HIGH); 
  delay        (1);
}

void loop() {
   // Cycle through each frequency band by pulsing the strobe.
  for (int i = 0; i < 7; i++) {
    digitalWrite       (strobePin, LOW);
    delayMicroseconds  (100);                    // Delay necessary due to timing diagram
    level[i] =         analogRead (outPin);
    digitalWrite       (strobePin, HIGH);
    delayMicroseconds  (100);                    // Delay necessary due to timing diagram  
  }
 
  for (int i = 0; i < 7; i++) {
    Serial.print       (level[i]);
    Serial.print       ("   ");
  }
 
  Serial.println ();  
}

This is the actual output (Almost same values in loop)
image

Moreover, I've ran several scripts trying to make a music visualizer, but all of them doesn't works.
Here one example:
It turns on the led (defined in setup) but there isn't any effect.

//Neopixel main script
#include <Adafruit_NeoPixel.h>

#define PIN 6 //strip pin
int analogPin=0; //A0 pin for reading frequency
int strobePin=2; //Ask MSGEQ7 for data
int resetPin=3; //End communication with MSGEQ7
//int spectrumValue[7]; //Array for frequencies
int filter=80;
int highest;
int rotation=0;
int rotationdelay=0;

int pattern = 0;


Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);

//Define Specific colors
uint32_t red = strip.Color(255, 0, 0);
uint32_t orange = strip.Color(255, 127, 0);
uint32_t yellow = strip.Color(255, 255, 0);
uint32_t green = strip.Color(0, 255, 0);
uint32_t blue = strip.Color(0, 0, 255);
uint32_t purple = strip.Color(75, 0, 130);

void setup() {
  //Serial.begin(9600); //Debugging serial port
  /**
  pinMode setup for MSGEQ7
  **/
  strip.begin();
  strip.show();
  pinMode(analogPin, INPUT);
  pinMode(strobePin, OUTPUT);
  pinMode(resetPin, OUTPUT);
  analogReference(DEFAULT);
  digitalWrite(resetPin, LOW);
  digitalWrite(strobePin, HIGH);
}

void loop() {
  if(pattern ==0){
      colorLoopProgression();
  }else if(pattern == 1){
      RainbowEqualizer();
  }
}

void RainbowEqualizer(){
  digitalWrite(resetPin, HIGH);
  digitalWrite(resetPin, LOW);

  int spectrumValue[6];
  for (int i = 0; i < 6; i++)
  {
   digitalWrite(strobePin, LOW);
   delayMicroseconds(30); // to allow the output to settle
   spectrumValue[i] = map(analogRead(analogPin), 0, 1023, 0, 9);
   setPixel(i*10, i*10+spectrumValue[i]);
   setReverse(i*10, i*10+spectrumValue[i]);
   strip.show();
   digitalWrite(strobePin, HIGH);
  }
  delay(30);
}

  void colorLoopProgression(){
    int spectrumValue[7];
    digitalWrite(resetPin, HIGH);
    digitalWrite(resetPin, LOW);
    for (int i=0;i<7;i++){
      digitalWrite(strobePin, LOW);
      delay(10);
      spectrumValue[i]=analogRead(analogPin);
      spectrumValue[i]=constrain(spectrumValue[i], filter, 1023);
      spectrumValue[i]=map(spectrumValue[i], filter,1023,0,255);
      //Serial.print(spectrumValue[i]);
      //Serial.print(" ");
      digitalWrite(strobePin, HIGH);
    }
    //Serial.println();

    highest =0;
    for(int i=0; i<7; i++){
      if(spectrumValue[i]>spectrumValue[highest]){
        highest = i;
      }
    }
   // Serial.println(highest);
    for(int i=30; i<60; i++){
      if(i<30+(spectrumValue[highest]/9)){
        int highestt=0;
        if(highestt==0){
          strip.setPixelColor(i, Wheel(rotation+(spectrumValue[highest]/6)+(highest*8)));
        }
        else if(highest==1){
          strip.setPixelColor(i, strip.Color(spectrumValue[highest], (255-spectrumValue[highest])/2, 0));
        }
        else if(highest==2){
          strip.setPixelColor(i, strip.Color(255-spectrumValue[highest], spectrumValue[highest], 0));
        }
        else if(highest==3){
          strip.setPixelColor(i, strip.Color(0, spectrumValue[highest], 0));
        }
        else if(highest==4){
          strip.setPixelColor(i, strip.Color(0, 0, spectrumValue[highest]));
        }
        else if(highest==5){
          strip.setPixelColor(i, strip.Color(75, 0, 130));
        }
        else if(highest==6){
          strip.setPixelColor(i, strip.Color(100,100,100));
        }

      }
      else{
        strip.setPixelColor(i, strip.Color(0,0,0));
      }
    }
    for(int i=30; i>0; i--){
      if(i>30-(spectrumValue[highest]/9)){
        int highestt=0;
        if(highestt==0){
          strip.setPixelColor(i, Wheel(rotation+(spectrumValue[highest]/6)+(highest*8)));
        }
        else if(highest==1){
          strip.setPixelColor(i, strip.Color(255, 127, 0));
        }
        else if(highest==2){
          strip.setPixelColor(i, strip.Color(255, 255, 0));
        }
        else if(highest==3){
          strip.setPixelColor(i, strip.Color(0, 255, 0));
        }
        else if(highest==4){
          strip.setPixelColor(i, strip.Color(0, 0, 255));
        }
        else if(highest==5){
          strip.setPixelColor(i, strip.Color(75, 0, 130));
        }
        else if(highest==6){
          strip.setPixelColor(i, strip.Color(100,100,100));
        }
      }
      else{
        strip.setPixelColor(i, strip.Color(0,0,0));
      }
    }
    if(rotationdelay>=1){
      rotation++;
      rotationdelay=0;
    }
    rotationdelay++;
    strip.show();
  }

  void setPixel(int start_bit, int pixelValue){
    for(int j=start_bit; j<pixelValue; j++){
      strip.setPixelColor(j, colorChoose(start_bit));
    }
  }


  void setReverse(int start_bit, int pixelValue){
    for(int k=start_bit+9; k>pixelValue;k--){
      strip.setPixelColor(k, 0,0,0);
    }
  }

  uint32_t colorChoose(int start_bit){
    switch (start_bit){
      case 0:
        return red;
        break;
      case 10:
        return orange;
        break;
      case 20:
        return yellow;
        break;
      case 30:
        return green;
        break;
      case 40:
        return blue;
        break;
      case 50:
        return purple;
        break;
    }
  }


  uint32_t Wheel(byte WheelPos) {
    WheelPos = 255 - WheelPos;
    if(WheelPos < 85) {
      return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
    }
    if(WheelPos < 170) {
      WheelPos -= 85;
      return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
    }
    WheelPos -= 170;
    return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

QUESTIONS

  1. Talking about MSGQE7, It's possible that i've made some connection error? I don't know how to make diagrams, so this is the real circuit (It's following MSGQE7 diagram, the white cable with my finger is DAC_R connecting to pin 5):

  2. I'm trying to understand at programming level how to make this effect, but i don't find any documentation around the web. If you can help me by giving any links, it would be wonderful.

As far as I can see, you are working with the MSGQE7 chip incorrectly.
Before reading each series of 7 frequency bands, a reset signal must be given.
But in your code you send a reset only once - at the start of the code.

There are numerous projects with MSGQ7 in the net. See, for example GitHub - donnersm/14ChannelAnalyzerV2.0: 14 Channel Spectrum analyzer V2.0

I'm not sure that's true:

But on the other hand, no harm in trying it!

There is zero point trying other code. The test code for the MSGEQ7 should be producing far more variation in the readings than your image shows

(By the way, please don't post images from serial monitor/terminal window which is just text. Copy the text and post it between code tags.)

The datasheet is very short and does not go into details. However, in most projects that I have seen, a reset is given each time before "rewind" the reading freq bands:

void readLevels() {
  
  digitalWrite (resetPin,  HIGH);
  delay(1);
  digitalWrite (resetPin,  LOW);
  delay(1);
  
 
  for (int i = 0; i < 7; i++) {
    digitalWrite       (strobePin, LOW);
    delay              (1);
    level[i] =         analogRead (outPin);
    digitalWrite       (strobePin, HIGH);
    delay              (1);
  }
  Serial.print   ("Reading from 400Hz frequency band: ");
  Serial.println (level[2]);
  Serial.println ();
  Serial.println ("Press button again to reread...");
}

In any case, an extra reset will definitely not be a mistake.

But do you have a speaker connected to SPK_1/2, or powered speakers attached to the jack socket, so that you can be sure that audio is actually playing?

Have you tried some other line-level audio source? Even an audio source with headphone output would be ok. Just start with very low volume and slowly increase volume until some variation in the readings is seen.

Yes, but it's hard to spot any error from your photos. Try moving the df player onto the same breadboard and use solid core wire to connect everything. Make everything neat, keeping all the resistor leads as straight as possible with minimal neat bends. Then take a bright, clear photo from directly above so that both ends of every wire and component can be clearly seen, where they are connected to the breadboard.

Connecting the Uno to the breadboard with neat wires isn't possible. It is always going to look like a mess. That's why I never recommend using Uno with breadboards. For breadboard projects, a classic Nano is a much better choice.

Hi, I've moved everything to only 1 board.

  1. There isn't anything connected to SPK_1/2
  2. The jump wires are connected to Arduino to correct pins.
  3. Brown solid core wire is DAC_R pin.
  4. I've changed some resistors to make it cleaner, but I'm still using the correct value which is reported in the datasheet.
  5. I'm playing Thunderstruck (ACDC) .wav file
  6. Everything is connected to the same GND/5V which comes from Arduino
  7. I've disconnected the led string

Talking about the code, I've changed it to make it more readable. I can confirm that DF Players is playing music (I've tried with headhpone and speakers).

#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;

void printDetail(uint8_t type, int value);
int strobePin  = 2;    // Strobe Pin on the MSGEQ7
int resetPin   = 3;    // Reset Pin on the MSGEQ7
int outPin     = A0;   // Output Pin on the MSGEQ7
int level[7];          // An array to hold the values from the 7 frequency bands


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

  mySoftwareSerial.begin(9600);


  if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while(true){
      delay(0); // Code to compatible with ESP8266 watch dog.
    }
  }
  Serial.println();
  // Define our pin modes
  pinMode      (strobePin, OUTPUT);
  pinMode      (resetPin,  OUTPUT);
  pinMode      (outPin,    INPUT);
 
  // Create an initial state for our pins
  digitalWrite (resetPin,  LOW);
  digitalWrite (strobePin, LOW);
  delay        (1000);
 
  // Reset the MSGEQ7 as per the datasheet timing diagram
  digitalWrite (resetPin,  HIGH);
  delay        (1000);
  digitalWrite (resetPin,  LOW);
  digitalWrite (strobePin, HIGH); 
  delay        (1000);
  
  myDFPlayer.volume(30);  //Set volume value. From 0 to 30
  myDFPlayer.play(1);
}

void loop() {
  // Reset the MSGEQ7 as per the datasheet timing diagram
  digitalWrite (resetPin,  HIGH);
  delay        (1000);
  digitalWrite (resetPin,  LOW);
  delay        (1000);
   // Cycle through each frequency band by pulsing the strobe.
  for (int i = 0; i < 7; i++) {
    digitalWrite       (strobePin, LOW);
    delayMicroseconds  (1000);                    // Delay necessary due to timing diagram
    level[i] =         analogRead (outPin);
    digitalWrite       (strobePin, HIGH);
    delayMicroseconds  (1000);                    // Delay necessary due to timing diagram  
  }
  
  Serial.print("63Hz: ");
  Serial.print(level[0]);
  Serial.println();
  Serial.print("160Hz: ");
  Serial.print(level[1]);
  Serial.println();
  Serial.print("400Hz: ");
  Serial.print(level[3]);
  Serial.println();
  Serial.print("1000Hz: ");
  Serial.print(level[4]);
  Serial.println();
  Serial.print("2500Hz: ");
  Serial.print(level[5]);
  Serial.println();
  Serial.print("6250Hz: ");
  Serial.print(level[6]);
  Serial.println();
  Serial.print("16000Hz: ");
  Serial.print(level[7]);
  Serial.println();


  Serial.println       ("#############");
  //for (int i = 0; i < 7; i++) {
    //Serial.print       (level[i]);
    //Serial.print       ("   ");
  //}
 
  Serial.println ();  
}

This is the actual output:

  1. The 16 kHz loop from negative to a positive value, the others don't change so much.
  2. Nothing change if I've connected/disconnected the jack port to the breadboard or not
  3. Nothing change if I don't give anything in input.
63Hz: 779
160Hz: 779
400Hz: 780
1000Hz: 777
2500Hz: 780
6250Hz: 778
16000Hz: 30284
#############

63Hz: 779
160Hz: 778
400Hz: 778
1000Hz: 780
2500Hz: 778
6250Hz: 778
16000Hz: 20845
#############

63Hz: 781
160Hz: 779
400Hz: 781
1000Hz: 779
2500Hz: 781
6250Hz: 779
16000Hz: 11022
#############

63Hz: 781
160Hz: 778
400Hz: 780
1000Hz: 781
2500Hz: 781
6250Hz: 778
16000Hz: 1324
#############

63Hz: 781
160Hz: 781
400Hz: 781
1000Hz: 781
2500Hz: 781
6250Hz: 780
16000Hz: -8374
#############

63Hz: 794
160Hz: 795
400Hz: 795
1000Hz: 794
2500Hz: 794
6250Hz: 795
16000Hz: -18072
#############

63Hz: 794
160Hz: 793
400Hz: 794
1000Hz: 794
2500Hz: 793
6250Hz: 793
16000Hz: -27636
#############

I've 5 MSGQE7 and they are giving almost the same value. I can't find what is wrong

there are many fake MSGQE7 in the market

I'm from italy, do you know where to buy MSGEQ7 in europe? Are there alternatives to this chip?
If I'd like to try FFT, there is a good tutorial to try to achieve the same result? I have to finish everything before 12 December, so i'm actually stuck :frowning:

no, I don't
There are other similar chips besides MSGEQ7. I tried to make an visualizer on a BA3834 chip, it worked for me

You should never see a negative value. The analogRead() function returns a value in the range 0 to 1023... Aha!!! This is why:

Serial.print(level[7]);

You are reading a value from outside of the array. The indexes of your array are 0 to 6. There is no index 7. If you try to read that, you will read some random piece of memory that may be used for some other variable.

When you update the array, you correctly never update index 7

  for (int i = 0; i < 7; i++) {
    ...
    level[i] =         analogRead (outPin);

If you bought them from the same seller then if one is fake probably they are all fake.

I'm sorry guys, but for the moment I'm not following anymore this road. In the future I'll buy new chips and I'll try again

The cap (a '104', it should be a '103') and resistor to pin 5 aren't placed properly (see yellow oval).
I suspect the capacitor you've placed on pin 8 (see red arrow) isn't the proper value either. It looks like a tantalum 'teardrop' - and a much greater value (than the specified 33pF).

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.