MSGEQ7 Ground Interference from External Power Supply???

Hello,
I have been working on an awesome LED controller and hope to use it for a light show this Christmas!
I am getting better and better at filtering out the data and getting values exactly where I want them but I keep running into issues with my audio data circuit which utilizes the MSGEQ7 to send analog data back to the arduino for analysis.

On its own, the MSGEQ7 should produce some noise, that's just how it works, usually a filter value of 60-100 will resolve this nicely(default values range from 0 to 1023). However, when I plug my external psu into the LEDs(I use N-Channel MOSFETS - the logic level IRL540s to be exact), that filter no longer filters the data sufficiently.

The values require a way more extensive filter, ranging from 400 to 500 to even get close to the values without an external psu plugged in.

So the things I have done to help resolve the data issues:

Added a dimming curve - helps reduce flickering
Added filter values per frequency band - individually filtering each band to get the desired result
Added amplifying values - amplify each frequency band individually, this is added to the value AFTER the filter has been applied and only if that frequency band reaches the minimum required value
Added minimum value for amplifying values to be added - per frequency band minimum value AFTER filtering in order for amplification to take effect

These options and additions have considerably improved the accuracy and condition of the synchronization with music, however the grounding issue still poses many issues as this results in missed beats, ques and lyric synchronization. It's mostly the top 2-3 frequency bands that are affected, bands 2 through 7 are affected but the top 2 to 3 bands seem to have the most interference.

I have uploaded my source code to pastebin for those that wish to use it, and I have posted a fritzing screenshot of my circuit(pretty much follows skoba's wiring for the MSGEQ7).

Pending solutions:

A 12v to 5v stepdown module to power the MSGEQ7 vs the arduino 5v power from the USB connection(measuring 4.89v via multimeter) - Currently on order, waiting for delivery from amazon

A second arduino to feed the MSGEQ7 data into the arduino mega's second serial port?

Does anyone have any other pointers for getting this resolved?

Circuit diagram: Screenshot - 2a04a632bcefe09e736d015a26424284 - Gyazo

Arduino Code: Arduino LED Controller - Pastebin.com
NOTE: The analog data can be found in the function updateMusics() in the Controller class(Lines 234 to 262).

How much noise are you getting? i.e. What are the readings with no signal? You might have to write a test program to activate the LEDs with no signal to see how much noise is caused by switching the LEDs.

as this results in missed beats, ques and lyric synchronization.

Music is complex and highly variable. You can't expect perfection. If you want perfection, you have to write & save a routine/pattern for each song. (Lighting for live shows is usually a combination of pre-programming and real-time human operation, maybe with some sound activation.) Or if your music is MIDI, you can do MIDI-to-DMX and control the lighting with MIDI.

So the things I have done to help resolve the data issues:

Added a dimming curve - helps reduce flickering
Added filter values per frequency band - individually filtering each band to get the desired result
Added amplifying values - amplify each frequency band individually, this is added to the value AFTER the filter has been applied and only if that frequency band reaches the minimum required value
Added minimum value for amplifying values to be added - per frequency band minimum value AFTER filtering in order for amplification to take effect

I don't know if this will help you at all because I don't know what you're doing (and I've never used an MSSGEQ7) but for my sound activated lighting, I use "auto calibration" or "automatic sensitivity control". I keep a 20 second moving average of the "loudness" (one reading per second) Then depending on the particular effect I'll use the average or the peak from that moving-average array as a reference or threshold.

In your case, you might want an overall average reference level, or you might want a separate reference for each frequency-band.

Hello, first off, thank you for responding to my post! I really appreciate it!

Here are some answers that should help clarify things:

How much noise am I getting?

The range for each frequency band that can be returned as an integer in arduino is 0 to 1023. 0 being no sound or no data, 1023 being maxed out. The amount of noise coming from the data with no sound playing, but with the cable plugged in can be found below(each value represents the corresponding frequency band 0 to 6(I did write an auto config/noise removal function for this):

388 389 543 665 699 736 733

The lower bands have about 1/3 of the data filtered while the rest of them have over 50% of the data filtered in just noise alone. I also tested the line going to the circuit with a pair of headphones and it was fine.

The auto calibration runs for 2 minutes consisting of 2 stages: Initial read and verification.

The initial read runs 60 seconds and measures the noise on the line and adjusts the filter values based on noise.

The second stage or verification, ensures that all the values are within minimum range(typically 0 to 10) and if they aren't, adjusts the filters accordingly.

Here is the code for auto-calibration:

		Serial.println("Starting auto config...");
		unsigned long startTime = millis();
		while (millis() <= startTime + 60000)
		{
			digitalWrite(MSGEQ7_RESET, HIGH);
			digitalWrite(MSGEQ7_RESET, LOW);

			for (int i = 0; i < 7;i++)
			{

				digitalWrite(MSGEQ7_STROBE, LOW);

				delayMicroseconds(30);

				Controller::MSGEQ7Values[i] = analogRead(MSGEQ7_DATA);
				Controller::MSGEQ7Values[i] = constrain(Controller::MSGEQ7Values[i], MSGEQ7_FILTER[i], 1023);
				Controller::MSGEQ7Values[i] = map(Controller::MSGEQ7Values[i], MSGEQ7_FILTER[i], 1023, 0, 255);
				
				if (Controller::MSGEQ7Values[i] > maxValues[i])
					maxValues[i] = MSGEQ7Values[i];


				Controller::MSGEQ7Values[i] = constrain(Controller::MSGEQ7Values[i], 0, 255);

				if (Controller::MSGEQ7Values[i] > MSGEQ7_MIN[i])
					MSGEQ7_FILTER[i] += Controller::MSGEQ7Values[i]-MSGEQ7_MIN[i];

				digitalWrite(MSGEQ7_STROBE, HIGH);
			}
			

		}
		Serial.println("Auto config completed.");

		Serial.println("Data Configured:");
		Serial.print(MSGEQ7_FILTER[0]);
		Serial.print(" ");
		Serial.print(MSGEQ7_FILTER[1]);
		Serial.print(" ");
		Serial.print(MSGEQ7_FILTER[2]);
		Serial.print(" ");
		Serial.print(MSGEQ7_FILTER[3]);
		Serial.print(" ");
		Serial.print(MSGEQ7_FILTER[4]);
		Serial.print(" ");
		Serial.print(MSGEQ7_FILTER[5]);
		Serial.print(" ");
		Serial.print(MSGEQ7_FILTER[6]);
		Serial.println();

		Serial.println("Verifying data...");

		startTime = millis();
		while (millis() <= startTime + 60000)
		{
			digitalWrite(MSGEQ7_RESET, HIGH);
			digitalWrite(MSGEQ7_RESET, LOW);

			for (int i = 0; i < 7;i++)
			{

				digitalWrite(MSGEQ7_STROBE, LOW);

				delayMicroseconds(30);

				Controller::MSGEQ7Values[i] = analogRead(MSGEQ7_DATA);
				Controller::MSGEQ7Values[i] = constrain(Controller::MSGEQ7Values[i], MSGEQ7_FILTER[i], 1023);
				Controller::MSGEQ7Values[i] = map(Controller::MSGEQ7Values[i], MSGEQ7_FILTER[i], 1023, 0, 255);

				if (Controller::MSGEQ7Values[i] > maxValues[i])
					maxValues[i] = MSGEQ7Values[i];


				Controller::MSGEQ7Values[i] = constrain(Controller::MSGEQ7Values[i], 0, 255);

				if (Controller::MSGEQ7Values[i] > MSGEQ7_MIN[i])
					MSGEQ7_FILTER[i] += Controller::MSGEQ7Values[i] - MSGEQ7_MIN[i];

				digitalWrite(MSGEQ7_STROBE, HIGH);
			}


		}

		Serial.println("Auto config completed.");

		Serial.println("Data Configured:");
		Serial.print(MSGEQ7_FILTER[0]);
		Serial.print(" ");
		Serial.print(MSGEQ7_FILTER[1]);
		Serial.print(" ");
		Serial.print(MSGEQ7_FILTER[2]);
		Serial.print(" ");
		Serial.print(MSGEQ7_FILTER[3]);
		Serial.print(" ");
		Serial.print(MSGEQ7_FILTER[4]);
		Serial.print(" ");
		Serial.print(MSGEQ7_FILTER[5]);
		Serial.print(" ");
		Serial.print(MSGEQ7_FILTER[6]);
		Serial.print(" ");

I've been trying to use the MSGEQ7 also and having less than wonderful results.

...that filter no longer filters the data sufficiently

Is your "60 - 100" filter just ignoring values less than 60 or 100?
As I recall, using PC USB power, was getting about 280mV of noise on each of the outputs. THat should translate to an analogRead of about 60. Sounds like what you were seeing originally. Using an external 5V regulated supply (a cell phone charger) I get pretty much the same background noise levels.

My main issue is a "jumpiness" of the readings, mostly the top two bands, of about a few hunderd mV that I haven't been able to fix. Also using just one delay (50us) after the STROBE LOW step. WHen I follow the part spec , the extra delays give even more (unusable) jumpiness of the readings.

Is the ground for the "external psu" tied solidly to the uC ground and do both the uC and psu V+ have any extra filtering capacitors to ground?