Texas
Offline
Jr. Member
Karma: 0
Posts: 69
Lost in SPI FADE land
|
 |
« Reply #30 on: August 31, 2011, 01:35:05 pm » |
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? 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?
|
|
|
|
« Last Edit: August 31, 2011, 04:15:23 pm by ibourdon »
|
Logged
|
|
|
|
|
Manchester (England England)
Offline
Brattain Member
Karma: 299
Posts: 26031
Solder is electric glue
|
 |
« Reply #31 on: August 31, 2011, 02:16:47 pm » |
Well that's a bit hard to follow. This bit:- 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. 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.
|
|
|
|
|
Logged
|
|
|
|
|
Texas
Offline
Jr. Member
Karma: 0
Posts: 69
Lost in SPI FADE land
|
 |
« Reply #32 on: August 31, 2011, 04:13:54 pm » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Manchester (England England)
Offline
Brattain Member
Karma: 299
Posts: 26031
Solder is electric glue
|
 |
« Reply #33 on: August 31, 2011, 04:33:55 pm » |
Here is something I wrote earlier:- // 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.
|
|
|
|
|
Logged
|
|
|
|
|
Texas
Offline
Jr. Member
Karma: 0
Posts: 69
Lost in SPI FADE land
|
 |
« Reply #34 on: September 01, 2011, 09:51:27 am » |
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.  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? 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); } } }
|
|
|
|
|
Logged
|
|
|
|
|
Manchester (England England)
Offline
Brattain Member
Karma: 299
Posts: 26031
Solder is electric glue
|
 |
« Reply #35 on: September 01, 2011, 12:57:15 pm » |
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.  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. :-)
|
|
|
|
|
Logged
|
|
|
|
|
Manchester (England England)
Offline
Brattain Member
Karma: 299
Posts: 26031
Solder is electric glue
|
 |
« Reply #36 on: September 01, 2011, 01:36:49 pm » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Texas
Offline
Jr. Member
Karma: 0
Posts: 69
Lost in SPI FADE land
|
 |
« Reply #37 on: September 01, 2011, 03:04:04 pm » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Manchester (England England)
Offline
Brattain Member
Karma: 299
Posts: 26031
Solder is electric glue
|
 |
« Reply #38 on: September 01, 2011, 03:07:38 pm » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Texas
Offline
Jr. Member
Karma: 0
Posts: 69
Lost in SPI FADE land
|
 |
« Reply #39 on: September 01, 2011, 03:49:54 pm » |
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.movThat code is as follows, without everything above the void loop() cause its all the same. 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); } } }
|
|
|
|
« Last Edit: September 01, 2011, 04:00:36 pm by ibourdon »
|
Logged
|
|
|
|
|
SF Bay Area
Offline
Edison Member
Karma: 6
Posts: 1215
Arduino Ninja
|
 |
« Reply #40 on: September 02, 2011, 02:05:31 am » |
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)
|
|
|
|
|
Logged
|
|
|
|
|
Texas
Offline
Jr. Member
Karma: 0
Posts: 69
Lost in SPI FADE land
|
 |
« Reply #41 on: September 02, 2011, 07:51:17 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
SF Bay Area
Offline
Edison Member
Karma: 6
Posts: 1215
Arduino Ninja
|
 |
« Reply #42 on: September 02, 2011, 03:47:57 pm » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Texas
Offline
Jr. Member
Karma: 0
Posts: 69
Lost in SPI FADE land
|
 |
« Reply #43 on: September 08, 2011, 12:55:53 pm » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
|