The green fades almost to nothing and the blue jumps on, if that helps any
kculm:
I have found another sketch but its not as nice, and I hate to just give up.
I can't see your circuit from here, unfortunately. Can you draw it?
fungus:
kculm:
I have found another sketch but its not as nice, and I hate to just give up.I can't see your circuit from here, unfortunately. Can you draw it?
If you back this down to just one RGB LED for simplicity, does it work smoothly on the ATTiny setup?
strykeroz:
If you back this down to just one RGB LED for simplicity, does it work smoothly on the ATTiny setup?
Same Effect .
Excellent. Then can you post the current version of the code here? We have to be close to sorting this now...
strykeroz:
Excellent. Then can you post the current version of the code here? We have to be close to sorting this now...
This is what I am using. Pretty Much the same. I just changed the Following.
#define MAX_RGB_VALUE 245 // no bigger than 255. (it was 255)
Works OK. just not a Rich
/*
RGB LED - Automatic Smooth Color Cycling
Marco Colli
April 2012
Uses the properties of the RGB Colour Cube
The RGB colour space can be viewed as a cube of colour. If we assume a cube of dimension 1, then the
coordinates of the vertices for the cubve will range from (0,0,0) to (1,1,1) (all black to all white).
The transitions between each vertex will be a smooth colour flow and we can exploit this by using the
path coordinates as the LED transition effect.
*/
// Output pins for PWM
#define R_PIN 4 // Red LED
#define G_PIN 0 // Green LED
#define B_PIN 1 // Blue LED
// Constants for readability are better than magic numbers
// Used to adjust the limits for the LED, especially if it has a lower ON threshold
#define MIN_RGB_VALUE 10 // no smaller than 0.
#define MAX_RGB_VALUE 245 // no bigger than 255.
// Slowing things down we need ...
#define TRANSITION_DELAY 70 // in milliseconds, between individual light changes
#define WAIT_DELAY 500 // in milliseconds, at the end of each traverse
//
// Total traversal time is ((MAX_RGB_VALUE - MIN_RGB_VALUE) * TRANSITION_DELAY) + WAIT_DELAY
// eg, ((255-0)*70)+500 = 18350ms = 18.35s
// Structure to contain a 3D coordinate
typedef struct
{
byte x, y, z;
} coord;
static coord v; // the current rgb coordinates (colour) being displayed
/*
Vertices of a cube
C+----------+G
/| / |
B+---------+F |
| | | | y
|D+-------|--+H ^ 7 z
|/ | / | /
A+---------+E +--->x
*/
const coord vertex[] =
{
//x y z name
{0, 0, 0}, // A or 0
{0, 1, 0}, // B or 1
{0, 1, 1}, // C or 2
{0, 0, 1}, // D or 3
{1, 0, 0}, // E or 4
{1, 1, 0}, // F or 5
{1, 1, 1}, // G or 6
{1, 0, 1} // H or 7
};
/*
A list of vertex numbers encoded 2 per byte.
Hex digits are used as vertices 0-7 fit nicely (3 bits 000-111) and have the same visual
representation as decimal, so bytes 0x12, 0x34 ... should be interpreted as vertex 1 to
v2 to v3 to v4 (ie, one continuous path B to C to D to E).
*/
const byte path[] =
{
0x01, 0x23, 0x76, 0x54, 0x03, 0x21, 0x56, 0x74, // trace the edges
0x13, 0x64, 0x16, 0x02, 0x75, 0x24, 0x35, 0x17, 0x25, 0x70, // do the diagonals
};
#define MAX_PATH_SIZE (sizeof(path)/sizeof(path[0])) // size of the array
void setup()
{
pinMode(R_PIN, OUTPUT); // sets the pins as output
pinMode(G_PIN, OUTPUT);
pinMode(B_PIN, OUTPUT);
}
void traverse(int dx, int dy, int dz)
// Move along the colour line from where we are to the next vertex of the cube.
// The transition is achieved by applying the 'delta' value to the coordinate.
// By definition all the coordinates will complete the transition at the same
// time as we only have one loop index.
{
if ((dx == 0) && (dy == 0) && (dz == 0)) // no point looping if we are staying in the same spot!
return;
for (int i = 0; i < MAX_RGB_VALUE-MIN_RGB_VALUE; i++, v.x += dx, v.y += dy, v.z += dz)
{
// set the colour in the LED
analogWrite(R_PIN, v.x);
analogWrite(G_PIN, v.y);
analogWrite(B_PIN, v.z);
delay(TRANSITION_DELAY); // wait fot the transition delay
}
delay(WAIT_DELAY); // give it an extra rest at the end of the traverse
}
void loop()
{
int v1, v2=0; // the new vertex and the previous one
// initialise the place we start from as the first vertex in the array
v.x = (vertex[v2].x ? MAX_RGB_VALUE : MIN_RGB_VALUE);
v.y = (vertex[v2].y ? MAX_RGB_VALUE : MIN_RGB_VALUE);
v.z = (vertex[v2].z ? MAX_RGB_VALUE : MIN_RGB_VALUE);
// Now just loop through the path, traversing from one point to the next
for (int i = 0; i < 2*MAX_PATH_SIZE; i++)
{
// !! loop index is double what the path index is as it is a nybble index !!
v1 = v2;
if (i&1) // odd number is the second element and ...
v2 = path[i>>1] & 0xf; // ... the bottom nybble (index /2) or ...
else // ... even number is the first element and ...
v2 = path[i>>1] >> 4; // ... the top nybble
traverse(vertex[v2].x-vertex[v1].x,
vertex[v2].y-vertex[v1].y,
vertex[v2].z-vertex[v1].z);
}
}
Ok, I think I see the problem.
With PNP transistors the output will be inverted, ie. The LEDs switch on when the Arduino pin is LOW. This is the opposite of when you connect it directly.
Try changing all your analogWrite(X,Y) to analogWrite(X,255-Y).
fungus:
Try changing all your analogWrite(X,Y) to analogWrite(X,255-Y).
I get a bunch of Code errors .
That shouldn't create any errors. What are you seeing?
Are these the three analogWrite I should change
analogWrite(R_PIN, v.x);
analogWrite(G_PIN, v.y)
analogWrite(B_PIN, v.z);
Yes
But the Code is v.x ,so I am not sure what to do.
There's a few easy ways to do it. You can do it in the calculations that construct the values you're outputting, you can change the values you define for the maximum and minimum (and change the direction of your traverse) or you can do it in the analogWrite() like was outlined above:
// set the colour in the LED
analogWrite(R_PIN, 255-v.x);
analogWrite(G_PIN, 255-v.y);
analogWrite(B_PIN, 255-v.z);
All compiles. Should work.
Geoff
And we have a winner. Works Great. I have to try to get it to do one more thing.
I am going to try to do it on my own. But will most likely need some help.
Will fill you in soon.
Thanks once more guys
Ok, I am down to the last piece of the puzzle.
I have now added a switch and 5 more functions.
What I am looking to make it do is ...
At power up all ls off.
Press Button : All RGB on to make white.
Press Button : only RED
Press Button : only Green
Press Button : only Blue
Press Button : Transition.
Press Button : All off.
I got it to work up until the transition.
Once it is in transition mode I cant turn it off. It also does not Loop once it is in Transition Mode
Now I know it has to do with the Delays in the code, And I looked at the blink with out Delay example to see if I could figure it out, but had no luck.
//RGB w/Tarnistion
#define RED 4
#define GREEN 0
#define BLUE 1
#define delayTime 70
int switchPin = 3;
long previousMillis = 0;
long interval = 0;
int val;
int val2;
int buttonState;
int mode = 0;
/*
RGB LED - Automatic Smooth Color Cycling
Marco Colli
April 2012
Uses the properties of the RGB Colour Cube
The RGB colour space can be viewed as a cube of colour. If we assume a cube of dimension 1, then the
coordinates of the vertices for the cubve will range from (0,0,0) to (1,1,1) (all black to all white).
The transitions between each vertex will be a smooth colour flow and we can exploit this by using the
path coordinates as the LED transition effect.
*/
// Tranistion Setup
// Constants for readability are better than magic numbers
// Used to adjust the limits for the LED, especially if it has a lower ON threshold
#define MIN_RGB_VALUE 10 // no smaller than 0.
#define MAX_RGB_VALUE 255 // no bigger than 255.
// Slowing things down we need ...
#define TRANSITION_DELAY 70 // in milliseconds, between individual light changes
#define WAIT_DELAY 500 // in milliseconds, at the end of each traverse
//
// Total traversal time is ((MAX_RGB_VALUE - MIN_RGB_VALUE) * TRANSITION_DELAY) + WAIT_DELAY
// eg, ((255-0)*70)+500 = 18350ms = 18.35s
// Structure to contain a 3D coordinate
typedef struct
{
byte x, y, z;
}
coord;
static coord v; // the current rgb coordinates (colour) being displayed
const coord vertex[] =
{
//x y z name
{
0, 0, 0 }
, // A or 0
{
0, 1, 0 }
, // B or 1
{
0, 1, 1 }
, // C or 2
{
0, 0, 1 }
, // D or 3
{
1, 0, 0 }
, // E or 4
{
1, 1, 0 }
, // F or 5
{
1, 1, 1 }
, // G or 6
{
1, 0, 1 } // H or 7
};
const byte path[] =
{
0x01, 0x23, 0x76, 0x54, 0x03, 0x21, 0x56, 0x74, // trace the edges
0x13, 0x64, 0x16, 0x02, 0x75, 0x24, 0x35, 0x17, 0x25, 0x70, // do the diagonals
};
#define MAX_PATH_SIZE (sizeof(path)/sizeof(path[0])) // size of the array
void setup() {
pinMode(switchPin, INPUT);
digitalWrite(switchPin, HIGH);
pinMode(GREEN, OUTPUT);
pinMode(BLUE, OUTPUT);
pinMode(RED, OUTPUT);
digitalWrite(GREEN, HIGH);
digitalWrite(BLUE, HIGH);
digitalWrite(RED, HIGH);
buttonState = digitalRead(switchPin);
}
void Red(){
digitalWrite(GREEN, HIGH);
digitalWrite(BLUE, HIGH);
digitalWrite(RED, LOW);
}
void Green(){
digitalWrite(GREEN, LOW);
digitalWrite(BLUE, HIGH);
digitalWrite(RED, HIGH);
}
void Blue(){
digitalWrite(GREEN, HIGH);
digitalWrite(BLUE, LOW);
digitalWrite(RED, HIGH);
}
void White(){
digitalWrite(GREEN, LOW);
digitalWrite(BLUE, LOW);
digitalWrite(RED, LOW);
}
void off(){
digitalWrite(GREEN, HIGH);
digitalWrite(BLUE, HIGH);
digitalWrite(RED, HIGH);
}
void traverse(int dx, int dy, int dz)
// Move along the colour line from where we are to the next vertex of the cube.
// The transition is achieved by applying the 'delta' value to the coordinate.
// By definition all the coordinates will complete the transition at the same
// time as we only have one loop index.
{
if ((dx == 0) && (dy == 0) && (dz == 0)) // no point looping if we are staying in the same spot!
return;
for (int i = 0; i < MAX_RGB_VALUE-MIN_RGB_VALUE; i++, v.x += dx, v.y += dy, v.z += dz)
{
// set the colour in the LED
analogWrite(RED, 255-v.x);
analogWrite(GREEN, 255-v.y);
analogWrite(BLUE, 255-v.z);
delay(TRANSITION_DELAY); // wait fot the transition delay
}
delay(WAIT_DELAY); // give it an extra rest at the end of the traverse
}
void RGB()
{
int v1, v2=0; // the new vertex and the previous one
// initialise the place we start from as the first vertex in the array
v.x = (vertex[v2].x ? MAX_RGB_VALUE : MIN_RGB_VALUE);
v.y = (vertex[v2].y ? MAX_RGB_VALUE : MIN_RGB_VALUE);
v.z = (vertex[v2].z ? MAX_RGB_VALUE : MIN_RGB_VALUE);
// Now just loop through the path, traversing from one point to the next
for (int i = 0; i < 2*MAX_PATH_SIZE; i++)
{
// !! loop index is double what the path index is as it is a nybble index !!
v1 = v2;
if (i&1) // odd number is the second element and ...
v2 = path[i>>1] & 0xf; // ... the bottom nybble (index /2) or ...
else // ... even number is the first element and ...
v2 = path[i>>1] >> 4; // ... the top nybble
traverse(vertex[v2].x-vertex[v1].x,
vertex[v2].y-vertex[v1].y,
vertex[v2].z-vertex[v1].z);
}
}
void loop(){
val = digitalRead(switchPin); // read input value and store it in val
delay(10); // 10 milliseconds
val2 = digitalRead(switchPin);
if (val == val2){
if (val != buttonState){
if (val == LOW){
if (mode == 0){
White ();
mode = 1;
}
else if (mode == 1){
Red();
mode = 2;
}
else if (mode == 2){
Green();
mode = 3;
}
else if (mode == 3){
Blue();
mode = 4;
}
else if (mode == 4){
RGB ();
mode = 5;
}
else if (mode == 5){
off();
mode = 0;
}
}
buttonState = val;
}
}
}
Hi
Let's see if I can tell you this in a way that makes sense. Apologies if I fail first time
The problem isn't the delay, the problem is the for loop that's in the RGB function. What happens with all the other states is you test the switch and do something then immediately return to loop(). With RGB though, there's that for loop which traverses from one colour to the other. While the code is in that loop, you're not testing the state of the switch so it gets ignored. When the traverse is complete it will come back to loop() to start testing the switch again. There may be more wrong with this logic, but that's the first that hits me.
One solution would be to check for the button state each time around that for loop, but that's not the way I'd do it. Rather than duplicating the switch testing code, make RGB not complete the entire loop before returning, but just complete one more step in the traverse. That way your logic will return to loop() to test your switch value and exit from the traverse if needed in between each step.
Hope that makes sense, Geoff
Geoff,
Thanks for the reply, I now understand why its not working. But because I am still learning I have no clue how to fix it.
So far in this little project I have learned a lot. I now know more about running LED's In parallel, in series and in series/parallel. I have learned about PNP and NPN transistors. I have played with the code to do a few different things. But because I did not wright the code I really don't fully understand it. That all being said I have no clue how to fix it.
I am thinking once I get this project done and see how it all works it will help me with future projects.
I have just spent a grand on a laser engraver and upgrades to is. I have planes to incorporate the Laser and the wood working that I do with some of the lighting I have been playing with using the Arduino.
I know I am asking a lot, but if someone is willing to not only show me how to fix it but explain to it me so I can learn. I would be willing to make it worth their time
Thanks
Hi,
I took a quick look at your code and noticed that your "traverse" process uses a nested for-loop structure. Currently, there are no conditions in place to "break out" of these loops when the buttons are pressed.
Since you've already declared your button state variables globally, I would suggest making a new function that you can call that checks the states of those buttons. Creating this function would make it re-usable and accessible by other parts of your program. I would call this new function at the top of the loop()-(replace the button checking code already there). Then you can also call this new function from within those for-loops to check if the buttons have been pressed, and "break;" out of the loop as needed. Keep in mind you would want to break out of both loops on a single button press so you may want to create new variable to manage this cascading breaking so that it completes before the button is released.
Skorn
I really appreciate your input but I have no clue on what I am doing. Like I said I did not write the code that transition the colors.
On a side note, Anyone know of any clubs in the West Palm area of Florida. I have gotten a few books and have been reading all I can online. But I learn better by seeing it done and then trying to do it.