Simple VU meter multiplex issue

Circuit is 9 RGB LED’s (see below). This is the start of my code, and I wanted to make sure this is an acceptable method to multiplex. I, also, would love advice on how to add the VU meter effect ( fade between changes). You don’t have to write the code, just give me some tips on how to incorporate the VU effect.

I will be adding 2 analog reads that are measuring music volume at 2 frequencies
(music → LPF/HPF-> op amp → envelop detector)
I think my biggest problem will be finding a running min/max from the analog read so my VU meter will utilize all LEDs?

int redPin = 8;     //pwm analog out for all red LEDs
int bluePin = 9;    //pwm analog out for all blue LEDs
int greenPin = 10;  //pwm analog out for all green LEDs
int ledCount = 9;   //# of RGB commone cathode LEDs

int groundPin[ledCount] = {0,1,2,3,4,5,6,7,8}; //digital grounds

struct RGB {
  byte r;
  byte g;
  byte b;
};

RGB ledArray[] = {{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}};

  	 
void setup() 	 
{ 	 
  	
	pinMode(redPin, OUTPUT); 
	pinMode(greenPin, OUTPUT);
	pinMode(bluePin, OUTPUT);

	//sets all LED colors 
	updateLedArray(255, 255, 255, ledCount, "all"); //sets all 9 LEDs to full color to start

	//declare grounds and debug all LEDs
	for(int i=0; i<ledCount; i++)
	{ 

		pinMode(groundPin[i],OUTPUT); //cycle each ground pin mode 
		digitalWrite(groundPin[i],LOW);
	}

	
} 	 
  	 
void loop() 
{ 	 

	updateLedArray(255, 0, 150, 9, "all");

	//multiplex the ledArray values through each LED 
	for(int i=0; i<ledCount; i++){

		if(ledArray[i].r>10 || ledArray[i].g>10 || ledArray[i].b>10){
		 //ground LED if it has pwm going to it
			
			analogWrite(redPin, ledArray[i].r);
			analogWrite(greenPin, ledArray[i].g);
			analogWrite(bluePin, ledArray[i].b);
			digitalWrite(groundPin[i], LOW);
			delay(1);
			digitalWrite(groundPin[i], HIGH);
		}
	}
		
} 	 

//the function that changes the LED array depending on the methd that you want

void updateLedArray(byte sred, byte sgreen , byte sblue, byte ledn, char methd) 
{ 
	 
 

  	if(methd == "all"){		//Change all colors in ledArray 
		for(int i=0 ; i<= ledCount ; i++)
	 	{
			ledArray[i].r = sred;
			ledArray[i].g = sgreen;
			ledArray[i].b = sblue;
	 	}
	}
}

I think my biggest problem will be finding a running min/max from the analog read so my VU meter will utilize all LEDs?

Not sure I understand this question, but finding min/max usually the easiest part.

I, also, would love advice on how to add the VU meter effect ( fade between changes).

Create a fade effect is also shouldn't be a problem, can you put more details how 2 measurements LPF/HPF would affect color of lighting? Have you compile your code, there is a line attract my attention: methd == "all", if methd is char, you can't compare it to a string "all".

Min/Max

I will have to establish a running min/max that will effectively adjust my range in order to ensure that all LEDs will be used... we will see how easy that is... (I am using a speaker output from a stereo for my audio input... sooo range tends to change{I use variable gain / potentiometer for this})

methd == "all", if methd is char, you can't compare it to a string "all".

Damn... any alternative for using logic on characters?

can you put more details how 2 measurements LPF/HPF would affect color of lighting?

Analog input from LPF/HPF & peak detector will be used in selectable methods. for example:

  • LP signal (0-1024) peak detector signal will be used to change the level of the VU meter (Which LED is lit)
  • HP signal peak detector signal will be used to change the color of the VU meter
  • Visa Versa

Be careful to connect speaker output to arduino, we have a discussion in other topic: http://arduino.cc/forum/index.php/topic,69045.msg510588.html#msg510588 Map function will do the job with "floating" maximum, I did using this approach in my project: http://fftarduino.blogspot.com/2011/02/color-organ-spectrum-analyzer-on.html I borrowed pieces of code from BarGraph in arduino IDE examples.

methd == 'a'

should be o'k, but if you want full words you have to define a string, which IMHO just not necessary.

Great advice

Well after a night of testing im going to lose my mind! The multiplexing works great, but making a sounds filter without an oscilloscope SUCKS!

I will not use the speaker wire as input, and I will use an electret… Let see if i can figure that out this weekend

Well, there are some options: - use computer audio card, as oscilloscope ; - use audio card as signal generator and DMM to track output of the filter; - you can even turn arduino into oscilloscope!

You can find free software on the net which compatible with your OS, that can do both function generator/oscilloscope, and SA on some occasions (RTA).

If I Multiplex through all 9 LED's, they are dim with a 1ms or 2ms delay

GRRRRRRR

Is it because 1ms is too fast for pwm to brighten 1 LED? If i slow it down, they are much brighter. Is is an issue with using the Digital out pin HIGH on the other LED's causing voltage to flow through the cathode of the RGB LED??? Help

Do you have a resistors on pin 9-11? And you have to select only one pin 0-8 at a time, I'm not sure what do you mean 1 or 2 ms? PWM usualy define as integer/char 0 - 255.

Do you have a resistors on pin 9-11?

nope. nothing changes much when I put a small resistor. ( less than 100 ohm)

And you have to select only one pin 0-8 at a time, I'm not sure what do you mean 1 or 2 ms?

1 or 2 ms is the time I leave each LED on before switching. So R G and B will be lit for 1ms before switching to the next LED. only one pin (0-8 Digital out) are LOW at any time. They are usually OFF, or digital HIGH; since i'm using my digital pins to ground the beast.

Is is an issue with using the Digital out pin HIGH on the other LED's causing voltage to flow through the cathode of the RGB LED???

If other pins HIGH, and PWM pins LOW , LED would be in reverse voltage - not conducting, nothing to worry. I'm still perplexed with your code, how you generate 40 Hz (default PWM 490 Hz, so each cycle PWM take only ~ 1 ms). Are you using delay ?

1st off - thanks for all your help. I can’t tell you how demoralized I am with this problem…

Here is a dumbed down version of how I am multiplexing… I don’t understand what you are taking about when you bring up the 40 Hz or 490Hz? So, PWM at “255” will pulse 5V at a freq of 490 Hz? 5V every ~2ms (490Hz) doesn’t seem right?

int redPin = 8;     //pwm analog out for all red LEDs
int bluePin = 9;    //pwm analog out for all blue LEDs
int greenPin = 10;  //pwm analog out for all green LEDs
int ledCount = 9;   //# of RGB commone cathode LEDs

int groundPin[ledCount] = {0,1,2,3,4,5,6,7,8}; //digital grounds

struct RGB {
  byte r;
  byte g;
  byte b;
};

RGB ledArray[] = {{255,0,0},{255,0,0},{255,0,0},{255,0,0},{255,0,0},{255,0,0},{255,0,0},{255,0,0},{255,0,0}};

  	 
void setup() 	 
{ 	 
  	
	pinMode(redPin, OUTPUT); 
	pinMode(greenPin, OUTPUT);
	pinMode(bluePin, OUTPUT);

	//declare grounds and debug all LEDs
	for(int i=0; i<ledCount; i++)
	{ 

		pinMode(groundPin[i],OUTPUT); //cycle each ground pin mode 
		digitalWrite(groundPin[i],LOW);
	}

	
} 	 
  	 
void loop() 
{ 	 


	//multiplex the ledArray values through each LED 
	for(int i=0; i<ledCount; i++){

		if(ledArray[i].r>0 || ledArray[i].g>0 || ledArray[i].b>0){
		 //ground LED if it has pwm going to it
			
			analogWrite(redPin, ledArray[i].r); //red pin pwm set for specific LED color
			analogWrite(greenPin, ledArray[i].g); 
			analogWrite(bluePin, ledArray[i].b);
			digitalWrite(groundPin[i], LOW); //ground the corresponding LED ground so it lights up
			delay(1);  //multiplex delay that bitch 
			digitalWrite(groundPin[i], HIGH); //un-ground the LED and go to the next one up
		}
	}
		
}

I don’t know where you get picture for post #1, but it’s written 40 Hz above each pwm pin.
First,

//declare grounds and debug all LEDs
	for(int i=0; i<ledCount; i++)
	{ 

		pinMode(groundPin[i],OUTPUT); //cycle each ground pin mode 
		digitalWrite(groundPin[i],LOW);   <<<<<<<<----  set it HIGH / off
	}

Second, I’m not sure this method of multiplexing is gonna to work, as default PWM frequency looks low for 9 led: in order to get update freq. 40 - 50 Hz for all bar, or 20 ms, you have to spend only 20/9 = 2.2 ms for each led. As there is no synchronization between PWM and your loop, results gonna to be unpredictable. Solution could be tweak analogWrite to make it faster.

Ignore 40 Hz freq. This is just part of the program I was using. SEE NEW PIC

I am onto something... I think that the 1ms pulse of 255 PWM is the problem. I believe a piranha rgb can take 100ma if it is pulsed. Anddddd the arduino only puts out 40mA?? Transistor?

ORRR PWM only works with a duty cycle of ~450Hz. Soooo. If I pulse at 1ms i am cutting the PWM signal in half... Shucks

Sex

Bump: See new pic. multiplexing LEDs = to dim

I couldn't understand, why do you need to change timing, 1 ms or 2 ms? In you code brightness each led define in the array, and you should just methodically scan throw all of them one by one. Scan speed should be at least 25 Hz, so blinking would not be visible. 25 Hz = 40 msec, or 40/9 = 4.1 msec for each led. What I mention earlier, there is potential problem with PWM driving frequency, as your loop and PWM are not synchronize, and could be observe "beating" problem - slow variation in brightness when in must be steady. The solution: search for code "fast PWM", there is some topic/project that solve this issue with multiplexing-PWM.

I couldn't fix the dimming issue, which I figure was an inherent problem with multiplexing 9 LEDs on/off.

For all that read this later, I am now using a tlc5490 which allows PWM with up to 16 LEDs. I multiplex through each color (RGB), but all LED's are grounded all the time. This is much brighter and easier.