Go Down

Topic: Similar to KITT light bar but not...I need help please (Read 4091 times) previous topic - next topic

ibourdon

#30
Aug 31, 2011, 08:35 pm Last Edit: Aug 31, 2011, 11:15 pm by ibourdon Reason: 1
With the code below I can get the LEDs to fade but can't get the last 2 to fade from red to blue at the same time ...

I commented out the code I was trying to use to just get the blue leds to fade opposite of the reds, and I can't get that to work properly, what am I doing wrong?

Code: [Select]

void loop()
{
  int count = 1024;
//  int count1 = 1024;
 while (count >= 0)
 {
   for (int i=0;i<=7;i++)
   {
//      while (count1 >= 1024)
//      {
       LEDChannels[i][0] = count;
       LEDChannels[8][2] = count;
       LEDChannels[9][2] = count;
       count--;
//        count1--;
       delayMicroseconds(2000);
}}
 WriteLEDArray();
}
}


I am trying to come up with an algorithm that will take the value of count1 and subtract 1023 (to ramp red down) then add another 1023 (to ramp blue up) all before the other 8 reds are all the way off.

What would be a simple formula or way to accomplish this?

I was thinking something like: LEDChannels{8}{2} = (count1 / 512) * 2;   //Divide by 512 which equals 2, then multiply by 2 so it ramps in steps of 2..
this obviously does not work but am I on the right track?

Grumpy_Mike

Well that's a bit hard to follow. This bit:-
Code: [Select]
for (int b=8;b<=9;b++)
Doesn't do anything for you because each time round the loop (only twice) it does exactly the same thing.
The writing out of the array seems at the wrong place.

Quote
I am trying to come up with an algorithm that will take the value of count1 and subtract 1023 (to ramp red down) then add another 1023 (to ramp blue up) all before the other 8 reds are all the way off.

The trick is to use floating point numbers and an increment (or decrement) value less than one. Then only use the integer part to write to the array. Work out the difference between the final value and the starting value. Divide this by the number of steps you want to make and that is the increment value. You can do this for all three colours or even different LEDs. Then each time round the loop just increment or decrement a floating point variable and then transfer it to the integer array that you then send out to the LEDs.

In this way say one fade value was 0.2 then the actual LED would only change values every 5 increments. In contrast another light with an increment value of 1.5 would change every time, alternately by one and then two. 

ibourdon

Sorry the "for (int b=8;b<=9;b++)" was supposed to be deleted.

Not really following you on the floating point algorithm. I know floating point is used for decimals and your saying just take the integer (rounded decimal to whole number) from the floating point equation but other than that I have no idea.

Would you be able to give me an example of what your talking about? Does not necessarily have to be related to my code, just something clear to look at to wrap my head around it.

Grumpy_Mike

Here is something I wrote earlier:-

Code: [Select]
// set up these global variables before the setup()
int currentRed = 0, currentGreen = 0, currentBlue = 0;  // this is the current colour that will be used as the start colour

void fadeTo(int R, int G, int B, int fadeSteps) {  // fade from the current colour to the one passed to the function
  float deltaR, deltaG, deltaB;
  float tempR, tempG, tempB;
// set up the temp values to the current LED state
  tempR = currentRed;
  tempG = currentGreen;
  tempB = currentBlue;

// calculate the distance between each colour as it is now, and the target colour
  deltaR = ( float(R - currentRed)) / fadeSteps;
  deltaG = ( float(G - currentGreen)) / fadeSteps;
  deltaB = ( float(B - currentBlue)) / fadeSteps;

  // fade to new colour
  for (int i = 0; i < fadeSteps; i++) {
// calculate new intermediate colour
   tempR += deltaR;
   tempG += deltaG;
   tempB += deltaB;

  // set these LEDs to the new intermediate colour
    analogWrite(REDPIN, int(tempR));
    analogWrite(GREENPIN, int(tempG));
    analogWrite(BLUEPIN, int(tempB));

    delay(FADESPEED);
  } // end of for loop

// keep the global colour up to date
  currentRed = tempR;
  currentGreen = tempG;
  currentBlue = tempB;

}


It is not for your hardware but it contains the same idea for one LED. It has PWM control for each of the colour components.

ibourdon

Thank you for that. It helps sometimes to see examples when it comes to something new to me.

Could you point me in a direction where I can get a good read and solid understanding of what "delta" is and how it works when programming in scenarios such as this?

Seems like there is a lot of trigonometry & calculus math needed to get really good flexibility and accomplish most anything. My algebra classes need to hurry up so I can get into some higher level math to make this easier. But I need to start with the basics to get this down pat so no hurry really.  :D

Here is a bit somewhat similar to what you posted but I don't have a fade function. Maybe that is why this code is not working?

Code: [Select]

const int clockpin = 13; // DI
const int enablepin = 10; // LI
const int latchpin = 9; // EI
const int datapin = 11; // CI

const int NumLED = 10; // Number of LEDs in chain
const int colorStep = 10;   // Stepsize for Red - Blue shift
const int fadeRate = 90;  // Divide by 100 for multiplier.  Done to eliminate float math

boolean effectDone = false;

int LEDChannels[NumLED][3] = {0};
int SB_CommandMode;
int SB_RedCommand;
int SB_GreenCommand;
int SB_BlueCommand;

void setup() {
  pinMode(datapin, OUTPUT);
  pinMode(latchpin, OUTPUT);
  pinMode(enablepin, OUTPUT);
  pinMode(clockpin, OUTPUT);
  SPCR = (1<<SPE)|(1<<MSTR)|(0<<SPR1)|(0<<SPR0);
  digitalWrite(latchpin, LOW);
  digitalWrite(enablepin, LOW);
}

void SB_SendPacket() {
   if (SB_CommandMode == B01) {
    SB_RedCommand = 120;
    SB_GreenCommand = 100;
    SB_BlueCommand = 100;
   }

   SPDR = SB_CommandMode << 6 | SB_BlueCommand>>4;
   while(!(SPSR & (1<<SPIF)));
   SPDR = SB_BlueCommand<<4 | SB_RedCommand>>6;
   while(!(SPSR & (1<<SPIF)));
   SPDR = SB_RedCommand << 2 | SB_GreenCommand>>8;
   while(!(SPSR & (1<<SPIF)));
   SPDR = SB_GreenCommand;
   while(!(SPSR & (1<<SPIF)));
}

void WriteLEDArray() {
   SB_CommandMode = B00; // Write to PWM control registers
   for (int h = 0;h<NumLED;h++) {
         SB_RedCommand = LEDChannels[h][0];
         SB_GreenCommand = LEDChannels[h][1];
         SB_BlueCommand = LEDChannels[h][2];
         SB_SendPacket();
   }

   delayMicroseconds(15);
   digitalWrite(latchpin,HIGH); // latch data into registers
   delayMicroseconds(15);
   digitalWrite(latchpin,LOW);

   SB_CommandMode = B01; // Write to current control registers
   for (int z = 0; z < NumLED; z++) SB_SendPacket();
   delayMicroseconds(15);
   digitalWrite(latchpin,HIGH); // latch data into registers
   delayMicroseconds(15);
   digitalWrite(latchpin,LOW);
}

void loop() {
 
  for (int i=0; i<NumLED; i++) { // Reinitialize red
    LEDChannels[i][0] = 1023;
    LEDChannels[i][2] = 0;
  }
  WriteLEDArray();
  delay(500);
 
 
  while(effectDone){                      //loop during animation
    for (int i=0; i<NumLED; i++) {        //loop between RGB writes
   
      if(LEDChannels[i][0] < colorStep){  //color shift from red - blue
        LEDChannels[i][0] = 0;
      }
      LEDChannels[i][0] -= colorStep;
      LEDChannels[i][2] += colorStep;
     
      if(i<(NumLED - 2)){                  //fade to off
        LEDChannels[i][0] = LEDChannels[i][2] * (i*fadeRate) / ((NumLED-2)*100);
        LEDChannels[i][2] = LEDChannels[i][2] * (i*fadeRate) / ((NumLED-2)*100);
      }
    }
    WriteLEDArray();
    delay(10);
   
    if(LEDChannels[NumLED-2][2] = 0){
        effectDone = true;
        delay(500);
    }
  }
}

Grumpy_Mike

Quote
solid understanding of what "delta" is

It is simply the word used for DIFFERENCE.
So if you have a value of 6 and then it becomes 10 the delta is 10 - 6 = 4

It is used in a lot of electronics for example delta modulation in audio is when you don't send the current value but the difference between the last value and the current value The point being that this has a much smaller dynamic range that the value itself and so can be encoded more economical. But this paragraph is just waffle you don't need to know, but that's what I did my PhD in the 70's so I know a bit about it.  :)

Quote
Seems like there is a lot of trigonometry & calculus math needed to get really good flexibility and accomplish most anything.

Well trig but no calculus. This is because you are dealing with a quantity of colour. This has three components or dimensions, red, green and blue. So a simply way to handle it is to think that a colour occupies a point in a space given by three coordinates, this is much the same as three dimensional space and so the maths to describe it is the same. So to go from one colour to another is just like drawing a line from one point in space to another. Fading between these colours is just going along that line a small step at a time.
Being called for my tea now back soon. :-)

Grumpy_Mike

Looking at that code you need to put your write array function each time you set the values in your arrays. It is only when you do this function that anything appears on the LEDs, this should always be followed by the delay so that the new value is visible for some time before changing it.

This is something you have done wrong in the last few codes you have posted so maybe you need to look at when to do this function.


ibourdon

Ah, nothing works like I want it to. =(

You explanation of delta is easier to understand than anything else I could ask for. Thank you for that, and the "waffle".
Thank you very much for your help with all my questions, I know it probably gets a little tiring when this stuff is easy for you and I just can't grasp it after all your help.

I have moved the WriteArray and it did help, I now have my red fading down like it needs to be but can't seem to get the last two in the line to fade how they need to.




Grumpy_Mike

Quote
can't seem to get the last two in the line to fade how they need to.

What do they actually do?
Is it nothing? If so then you are probably not addressing them. Remember an index in an array starts at zero although we tend to call this the first element.

ibourdon

#39
Sep 01, 2011, 10:49 pm Last Edit: Sep 01, 2011, 11:00 pm by ibourdon Reason: 1
Here is a link to what it currently does, I took off the diffuser I had over it and realized the upper LEDs are staying lit very dimly and blue when they should have nothing to do with blue.
They bottom 2 are supposed to go from red to blue, with only a dark blue lit at the end.

http://dl.dropbox.com/u/39860181/Video1.mov

That code is as follows, without everything above the void loop() cause its all the same.

Code: [Select]

void loop() {
 
 for (int i=0; i<NumLEDs; i++) { // Reinitialize red
   LEDChannels[i][0] = 1023;
   LEDChannels[i][2] = 1;
 }
 WriteLEDArray();
 effectOn = true;
//  delay(500);
 
 
 while(effectOn){                      //loop during animation
   for (int i=0; i<NumLEDs;i++) {        //loop between RGB writes
   
     if(LEDChannels[i][0] < colorStep){  //color shift from red - blue
       LEDChannels[i][0] = 0;
     }
     else{
     LEDChannels[i-2][0] -= colorStep;
     }  

     if(LEDChannels[i][2] > (1023 - colorStep)){  //color shift from red - blue
       LEDChannels[i][2] = 1023;
     }
     else{
//      LEDChannels[i][2] += colorStep;
     LEDChannels[NumLEDs-2][2] += colorStep;
     LEDChannels[NumLEDs-1][2] += colorStep;
     WriteLEDArray();

           }
   
    }

   if(LEDChannels[NumLEDs-3][0] == 0){    
       effectOn = false;
       delay(500);
     }
   }
 }

macegr

So, I know you want to solve this by yourself, but thought I would provide a little encouragement. I finally had a little spare time tonight and spent a few minutes putting a little demo together. Actually I started coding around 11:35, and right now (12:03) I have a video published and am writing this post...but I do have the advantage of writing this exact type of code many times before. It might encourage you to know the function rendering the effect is only 23 lines...

Anyway, was the effect you wanted something like this? (LEDs dimmed to 10% so they don't wash out the camera)

http://www.youtube.com/watch?v=6YsRJtW_JjY
Unique RGB LED Modules and Arduino shields: http://www.macetech.com/store

ibourdon

Yes sir, that is the effect. Fade from red down to blue.
23 lines huh? I have more than that in just the loop.
Am I even close with what I have now or still a ways off. I'm about to the point where I'm ready to see some code.

macegr

You are getting there, I guess...it's a completely different approach though. Your code is going to be single-purpose, I just made a function that takes a floating point value between 0 and 1, scales it to any number of LEDs, picks a fade color between any two starting RGB colors, lets you define the number of LEDs remaining at the end, and aliases the LEDs to intermediate values instead of just turning them on and off to simulate the plunger. It also doesn't have hardcoded increments to count up and down for the fades...you just call the function with the position you want to display, which you calculate by incrementing one value or doing math etc.
Unique RGB LED Modules and Arduino shields: http://www.macetech.com/store

ibourdon

Ok, I have to take a break on this one... giving me a headache. Getting a little frustrated not being able to get it to do what I want.

I'm going to work on another project involving 5940s for a bit then come back to this and try to figure it out using an approach closer to yalls (mike & mace) approach with a call to a function to fade instead of trying to do it in the loop. Maybe that will simplify things a bit...
Thanks for all your help  fellas and I'm sure I will be asking more questions in the near future on this project and others.

Go Up