Go Down

Topic: Ambient ceiling lighting project for Dolby 5.1 sound for PC (Read 2027 times) previous topic - next topic


Good afternoon guys,

So i found this article about the MSGEQ7 which was very helpful. However i havE a few questions.

Question 1, Since i need 6 channels i assume that these chips are mono and ill need 6 chips

Queestion 2, The reset and strobe pins across the chips, can i tie them all in together to keep tings in sync and use the outputs of that to the alanolgue inputs on the UNO?



Clearly and if I can get both channels then I only need 3.thanks..


With only 3 channels, you would loose all left/right information. I would suggest 4 chips/channels would be a good compromise. Channel 1: front left. Channel 2: front right. Channel 3: combined centre+sub. Channel 4: combined rear left+right. Or maybe add a fifth channel and keep rear left & right separate.



It seems that you cannot use more than one channel on the MSGEQ7, if you choose to do so then it will combine the channels and for this project that wont work. So i will in fact need 6 chips for processing.

I also found a very useful link for programming the chips Here


so after looking at the code for the MSGEQ7 it seems that the peak driver is what outputs the value to be processes from 0 to 1,023 which divided by 4 will allow for an input range of 0-255 for arduino and this happens 7 times per channel. Now in my case i will have to find a common frequency to look at per channel, in my case i would have to choose 160hz for the front and rear channels, and 63hz for the sub. Now that I'm looking into this more i really dont have a need for the center channel because the LED's will surround the room in a square. So there is no need for the center channel since i plan to do a chase LED from the center of each speaker location to the speaker with the active sounds.

Now my understanding is that the MSGEQ will be pulsed 7 times and those values will be logged on the alalogue pin. now in a case like that if the volume was high the 7 values trapped should be higher correct? If so then if i wanted to only keep an eye out for 160Hz then i would look at the second value of 7 for processing the two front and two rear channels. For the sub i would only need to look at the first value which corrosponds to the 63Hz range.

So logging the first and second calues i can use those numbers to determine the volume of those freaquences. This also makes me think for the sake of programming i should devide the numbers by 10.24 for processing so i get a value of 1-100 in volume values vs 0-255 thich just makes it easire to understand for volume level.

So in his code hs uses the code below to read the 7 bands and the bands are: 63Hz, 160Hz, 400Hz, 1,000Hz, 2,500Hz, 6,250Hz, 16,000Hz

Code: [Select]

for(int i=0; i <7; i++)                            // Cycle through the 7 spectrum bands

I should be able to use for the FR,FL,RR,RL channels. Can i start at 1 to remove the first value since its for the sub and i only need the second value?
Code: [Select]

for(int i=1; i <2; i++)                            // Cycle through the 7 spectrum bands

and use this for the sub since its the only value i need.
Code: [Select]

for(int i=0; i <1; i++)                            // Cycle through the 7 spectrum bands

His code

Again.. thanks for all the help guys, im no programmer but i have a basic understanding of logic and programming.



here is an idea of how i want the lights to work when sound levels from a speaker is active, in this case the FR speaker. you can ignore the colors for now, its for pure illustration reasons at the moment.

but the chaser light will consist of 9 LED's active. the first 3 will be dimmed from 15% 33% 66%, the next 3 will be full bright and the last 3 will be 66%, 33%, 15% if possible. and the color will be silver.

also there will be two of those markers per strip and they will be centered like below.

so between FR and FL speakers you will see 9 leds that are silver and illuminated as such.
15%,33%,66%,100%,100%,100%,66%,33%,15% next to 15%,33%,66%,100%,100%,100%,66%,33%,15%. centered on the strip as a base position. Now if sound is active at a specific level at speaker FR the 9 leds on the right hand side of the center will chase to that speaker. now the same thing will happen between the FR and RR speaker where the 9 leds on the left hand side of that strip will chase toward the FR speaker while the other side stays stationary.

Now for the sub channel all the other leds on the strip will change from Blue at 33% sound then Purple at 66% and red at 99% sound to immerse you in the sound.


so I've been doing some digging and came up with this so far:

Code: [Select]

// FastLed
#include "FastLED.h"

#define DATA_PIN    7
#define LED_TYPE    WS2812B
#define NUM_LEDS    400

void setup()
  FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);

//Base Control

int channelSub = 0; // Analog pin 0 = spectrum data from Sub channel
//int channelFL = 1; // Analog pin 1 = spectrum data from Front left channel
//int channelFR = 2; // Analog pin 2 = spectrum data from Front Right channel
//int channelRL = 3; // Analog pin 3 = spectrum data from Rear left channel
//int channelRR = 4; // Analog pin 4 = spectrum data from Rear Right channel

int ctrlReset = 5; // Digital pin 5 = signal to reset MSGEQ7s
int crrlStrobe = 6; // Digital pin 6 = signal to strobe (read data from) MSGEQ7s

int spectrumSub[7];                     // Array to store 7 bands of spectrum data from Front Right channel
//int spectrumFL[7];                     // Array to store 7 bands of spectrum data from Front Right channel
//int spectrumFR[7];                    // Array to store 7 bands of spectrum data from Front Left channel
//int spectrumRL[7];                     // Array to store 7 bands of spectrum data from Rear Right channel
//int spectrumRR[7];                    // Array to store 7 bands of spectrum data from Rear Left channel

void setup()
  // Read from MSGEQ7 OUT
  pinMode(analogPin, INPUT);
  // Write to MSGEQ7 STROBE and RESET
  pinMode(strobePin, OUTPUT);
  pinMode(resetPin, OUTPUT);

  // Set analogPin's reference voltage
  analogReference(DEFAULT); // 5V

  // Set startup values for pins
  digitalWrite(resetPin, LOW);
  digitalWrite(strobePin, HIGH);

  strip.show(); // Initialize all pixels to 'off'


void loop()
  // Set reset pin low to enable strobe
  digitalWrite(resetPin, HIGH);
  digitalWrite(resetPin, LOW);

//(Max noise value / 4)
MaxLevel = 20; // initialize MaxLevel as largest noise value for threshold

// Get all 7 spectrum values from the MSGEQ7
for (int i = 0; i < 7; i++)
        digitalWrite(strobePin, LOW);
        delayMicroseconds(30); // Allow output to settle

        spectrumSub[i] = analogRead(channelSub);

        // Remap the value to a number between 0 and 255
        spectrumSub[i] =>> 4; //Remap a 10bit value to 8bit

        //Compare previous with current value
        if(MaxLevel < spectrum[i])
            MaxLevel = spectrum[i] //replace with largest value

        // Remove serial stuff after debugging
        Serial.print(" ");
        digitalWrite(strobePin, HIGH);


   // Write the PWM values to the LEDs
   // I find that with three LEDs, these three spectrum values work the best

   for(uint16_t i=0; i<strip.numPixels(); i++)

//Check if max val is in the lower frequencies and if MaxLevel val is greater than noise threshold
if((spectrum[0] == MaxLevel || spectrum[1] == MaxLevel) && MaxLevel > 20) { for(uint16_t i=0; i<strip.numPixels(); i++)
strip.show(); }

from here

what I'm trying to figure out is how to integrate the code below to only look at the bass band

Code: [Select]

for(int i=0; i <1; i++)                            // Cycle through the 7 spectrum bands

I also need a way to set the colors to change from purple to blue to red with the level of base response from 33 to 66 to 99%. I was looking at the code below for that..

Code: [Select]

void loop() {

void RGBLoop(){
  for(int j = 0; j < 3; j++ ) {
    // Fade IN
    for(int k = 0; k < 256; k++) {
      switch(j) {
        case 0: setAll(k,0,0); break;
        case 1: setAll(0,k,0); break;
        case 2: setAll(0,0,k); break;
    // Fade OUT
    for(int k = 255; k >= 0; k--) {
      switch(j) {
        case 0: setAll(k,0,0); break;
        case 1: setAll(0,k,0); break;
        case 2: setAll(0,0,k); break;

From Here

I modified some of the code on the site to respect the project I'm working on for now. I don't have a way of testing at the moment because i haven't ordered all the hardware yet.  I'm going to measure the room tonight and see how many LED's i need and power requirements. Ill also look for an Arduino Mega 2560 Rev3


You need 2 digital outputs and 5 or 6 analog inputs for the msgeq7 chips, 1 digital output for the strip and you will be building your prototype on breadboard. A Mega makes no sense to me at all. But I know they are for some reason irresistibly attractive to beginners, so there is little point trying to convince you otherwise.


It's only 35 bucks that's the real reason.. But after looking I can pull it off on a uno for 19 bucks.. It has 6 inputs and I only need 5.


I would not recommend stealing one either.

Are you going to build your prototype on breadboard, at least initially? If so, I recommend an Arduino that is breadboard compatible. Uno and Mega are not. They are meant to be used with shields, not breadboards.

To recommend which "Arduino", we need to know how many ws2812b LEDs your final project will use. Ram memory can be an issue with high numbers of LEDs.


Stealing.. lol.. No.. It was a typo.. I'm getting use to my new Android Phone and different keyboards etc..

Number of Leds: 720
Controller: Arduino Uno
Led Type: WS2812B / IP65

12 Reset MSGEQ7
13 Strobe MSGEQ7

A0 FL Input
A1 FR Input
A2 RL Input
A3 RR Input
A4 Sub Input
A5 Center Input

Other Hardware:
4 X 16.4Ft WS2812B 60/Meter strips (I will have some left over but thats ok)
60A Power Supply (I've seen a strip of 300 LEDS draw 5A max so 60 is more than I need)
Digital Optical Splitter
5.1 Optical To RCA decoder (decided not to mess with HDMI to RCA because of 4K @ 60hz issues)
6 mono 3.5mm to RCA male cables (Ill make them if i cant fine them at low cost)

Room Size:
10Ft X 10Ft

The PS will power the Uno and LED's, I currently have 325 Leds on a uno now on my Ambient TV project and its holding up fine, I know this is double but the operations wont be much so i THINK the Uno should be ok.



720 LEDs will require more ram memory than the Uno has. 3 bytes are needed for each led, and the Uno has only 2000 bytes. Same with Nano, Pro Micro etc. Mega has enough ram, but I don't think you could squeeze 6 msgeq7 chips, phono/3.5mm stereo Jack sockets and all the associated components on a proto shield. What is your plan?

I've never used one, but I would be considering one of the Teensy 3.x boards, or one of the samd21 boards by AdaFruit or Sparkfun.





Well i never had intention to build in on a pronto so i wont be limited to that. I will find a way to mount it on something and make it look nice or not later on, for now I'll just hot glue things to a plastic sheet. Well I guess I'm back to the Mega again, grr.. I already ordered the UNO but the person helping me with the code is really cool so i wont return it and just but a mega and be done.

I'm learning a lot.. Which makes this amazing.. Paul are you any good with coding?


Yes, I can code. But I am already having nightmare visions of Megas hot glued to plastic sheets like a kindergarten collage made of glitter and dried pasta.



I have the variables set from the 6 msdeq7 chips and want to apply the output values to code. Ridht now I'm trying to figure out how to use variables to strove all the leds using "channelSub". Which will have to be devoted by 4 for a 0 to 255 output. Or devided by 10.24 so I get values of 0 to 100. Then I want to transition from purple at 0 to 33, blue from 34 to 66 and red from 67 to 100. I'm also using the code below to pull out only bass.

Code: [Select]

if (channelSub) {
uint8_t val = MSGEQ7.get(MSGEQ7_BASS); // Used to remove unwanted frequency's and only use Bass
channelSub[SpectrumBand] = analogRead(5);

So I want to be able to say something like

Code: [Select]

If ChannelSub = 0 < 33, SubChannelColor (255,0,255) // for purple
If ChannelSub = 34 < 66, SubChannelColor (0,0,255) // for blue
If ChannelSub = 67 < 100, SubChannelColor (255,0,0) // for red

And loop that with a delay of 500ms and fade in to each color with a 250ms delay.

I know my explanation is not actual code but it's the best way of explaining what I need. Then I'll start working on the more complex things like the 9 stationary leds which will move around depending on level of the values of the other speakers.

In addition to this I was wondering if it's possible to overlay the other leds on top so no matter where the 9 leds move on the strip.. The rest if the strip will change color according to this code.

Go Up