Go Down

Topic: 8x8 RGB Matrix Fade Speed (Read 2095 times) previous topic - next topic

laxa8831

Hi,

Read though madworms awesome thread and got my matrix working straight away. Now I'm trying the modify the code...

*Original Code*
void fader_hue(void) {
 int ctr1;
 byte row;
 byte led;

 for(ctr1 = 0; ctr1 < 360; ctr1=ctr1+3) {
   set_matrix_hue((float)(ctr1));
   delay(__fade_delay);
 }
}


What I'm trying to do is have the code only run the fader_hue void, which I've done, and be able to control the speed of the fading with a pot connected to analog0. I can get it almost working by changing the for statement to read this:

void fader_hue(void) {
 int ctr1;
 byte row;
 byte led;
 Micval = analogRead(Micpin);
 Micval = map(Micval, 0, 1023, 1, 100);
 Micval = constrain(Micval, 1, 100);

 for(ctr1 = 0; ctr1 < 360; ctr1=ctr1+Micval) {
     set_matrix_hue((float)(ctr1));
 }
}

The problem is that it runs through the whole fade animation and then updates the speed. This means that if Micval is 1 then it runs through the whole fade procedure (3-4 seconds) then updates the speed if Micval has changed. As Micval gets quicker is fades quicker and updates the fade speed quicker. What I want is for it to update the fade speed immediately after a new Micval is present.
Any Ideas?
Cheers

laxa8831

Link to madworm's thread:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1215096929/0

MikMo

You need to do the analogread() of the pot inside the for loop

laxa8831

Ah great, that worked perfecly. Now I can I can alter the rate of fading with an analog value.

What I'd like to do next is control the rate of colour change based on an analog value. Say if the analog value was under 100 then the matrix would just glow blue, and if it went up to say 700 then it would glow red. And as it went up from 0 to 700 the colours would change through the spectrum, blue to cyan to green to yellow to orange to purple to red. AND have the the speed of the fade change accordingly, 100 is a slow fade and 700 a fast fade.

I was thinking of having it as two functions, one that controls the colour change and another inside that changes the fade speed. I'm not quite sure how I'd do this but was wondering if anyone had a better idea before i invest dozens of hours into something that may not work at all.

cheers

laxa8831

#4
Oct 17, 2009, 12:34 pm Last Edit: Oct 17, 2009, 12:37 pm by laxa8831 Reason: 1
The code I've gotten so far can adjust either the fade value or colour value, but not both at once. And when i change the colour value it stops fading, it's only when reset the colour change back to ctr2, ctr1, hue that fading works again.

void set_matrix_hue(int hue) {
 byte ctr1;
 byte ctr2;
 for(ctr2 = 0; ctr2 <= __max_row; ctr2++) {
   for(ctr1 = 0; ctr1 <= __max_led; ctr1++) {
     set_led_hue(ctr2,ctr1,constrain((map(analogRead(0),0,1023,1,240)),1,240));
   }
 }
}

fade speed

void fader_hue(void) {
 int ctr1;
 byte row;
 byte led;
 for(ctr1 = 0; ctr1 < 360; ctr1=ctr1+constrain((map(analogRead(1),0,1023,1,10)),1,10)) {
     set_matrix_hue((float)(ctr1));
delay(__fade_delay);
 }
}

madworm

As you've seen, the set_matrix_hue() function is instantaneous.

If I understand you right, you need to write a function that fades from color A to color B ( on the 0...360 rainbow, where 360 is the same as 0 ).

You should modify the fader_hue() function, so it remembers the last color value and if the new value ( determined by the analogRead() ) is different, then fade to the new value using a for loop and the speed setting as you've done it already.

something like (pseudo code):
Code: [Select]
int new_color = analogRead(...);

if ( new_color < old_color ) {
...
for(ctr1 = old_color; ctr1 > new_color; ctr1=ctr1-speed) {
 ...
}
...
}

if ( new_color > old_color ) {
...
for(ctr1 = old_color; ctr1 < new_color; ctr1=ctr1+speed) {
 ...
}
...
}

if ( new_color == old_color) {
...
}

laxa8831

Thanks for the tips, but I can't quite get it working. I've modified the fader parameter to fade in and out from black, and i can control the speed of that.
Code: [Select]
void fader(void) {
 byte ctr1;
 byte row;
 byte led;

 for(ctr1 = 0; ctr1 <= __max_brightness; ctr1++) {
   for(row = 0; row <= __max_row; row++) {
     for(led = 0; led <= __max_led; led++) {
set_led_rgb(row, led, ctr1, ctr1/100, ctr1/100);
     }
   }
   delay(constrain((map(analogRead(0),0,1023,10,100)),10,100));
 }
 for(ctr1 = __max_brightness; (ctr1 >= 0) & (ctr1 != 255); ctr1--) {
   for(row = 0; row <= __max_row; row++) {
     for(led = 0; led <= __max_led; led++) {
set_led_rgb(row, led, ctr1, ctr1/100, ctr1/100);
     }
   }

   delay(constrain((map(analogRead(0),0,1023,10,100)),10,100));
 }
}

In that example I can control the fade speed with analogRead(0), but not control the colour value with another ananlogread (1 for example) interger. If I don't have the ctr1 values in the set_led_rgb function then it won't fade, just sit at a constant colour.  For example I tried something like this which didn't work :(
Code: [Select]
int a = constrain((map(analogRead(1),0,1023,1,10)),1,10);
int r = 0;
int g = 0;
int b = 0;
{
if ((constrain((map(analogRead(1),0,1023,1,100)),1,100))<=50){
 r= 100 -(2*a);
 g=2*a;
 b=0;
}
if((constrain((map(analogRead(1),0,1023,1,100)),1,100))>50) {
r=0;
g=100-(2*(a-50));
b=2*(100-50);
}
}
set_led_rgb(row,led,r,g,b);

Again, hours of work and back where I started. Can fade in from black to a colour then back to black OR cycle through the rainbow but lose the fading in/out from black ability.

laxa8831

The work continues...
Re-reading through my posts, I may not have been descriptive enough about my program. What I'm after is the ability to control the colour and fade speed through two separate pots. Ie, pot 'a' would control the fade speed, from quickly fading from black to full brightness and back the black again. Pot 'b' would control the colour of the matrix, so that the colour could be changed regardless of the fade speed and vice-versa. Here's an example how what I've come up with.
Code: [Select]
void fader(void) {
 int ctr1;
 int a;
 int r;
 int g;
 int b;
 for(ctr1 = 0; ctr1 <= 15; ctr1++) {
   a = (constrain((map(analogRead(1),0,1023,1,90)),1,90));
       set_matrix_rgb(ctr1,ctr1/a,ctr1/a);
   delay(constrain((map(analogRead(0),0,1023,10,100)),10,100));
 }
 for(ctr1 = 15; ctr1 >= 0; ctr1--) {
   a = (constrain((map(analogRead(1),0,1023,1,90)),1,90));
   set_matrix_rgb(ctr1,ctr1/a,ctr1/a);
   delay(constrain((map(analogRead(0),0,1023,10,100)),10,100));
 }
}


This code allows me to change the fade speed, and adjust the colour from red directly to white. All that needs to be done is to fix the colour change parameter to allow the full spectrum.
Hope this cleared things up a bit.
Cheers.

madworm

Maybe it would be a good thing if you had a look at the set_led_hue() function.

It converts the HSV color space to RGB. I only implemented the H part of it though. If you expand from there and also implement the Saturation and Value part of it, you may find it easier to do what you want.

http://en.wikipedia.org/wiki/HSL_and_HSV

Go Up