I'm new to this forum, as well as Arduino and electronics in general.
I suspect this may be a simple question, but despite endless google searches, I haven't found anything that directly addresses it.
I wanted to create an array of fading LEDs, ideally at different rates. I don't plan on creating a matrix . . . rather, I wanted to run several separate LEDs off long strings of hookup wire. I wanted to run out as many as possible without requiring additional hardware (although I should mention that I have an Adafruit PCA9685 at my disposal, as well as a Teensy 3.0).
togethernessnyc:
I wanted to create an array of fading LEDs, ideally at different rates. I don't plan on creating a matrix . . . rather, I wanted to run several separate LEDs off long strings of hookup wire. I wanted to run out as many as possible without requiring additional hardware (although I should mention that I have an Adafruit PCA9685 at my disposal, as well as a Teensy 3.0).
For several LEDs on long strings of wire the WS2801 or WS2811 chips make things easy to connect. You can get strings of LEDs with built-in chips, eg. these: http://www.ebay.com/itm/160896346789
You can literally snip individual LEDs off those strips with scissors and hook them up using just three wires between each LED. The LEDs even have solder pads on them to make it easy. Each string of LEDs needs just one Arduino pin to control it.
A couple of years ago I wrote a routine that did something similar to what you're wanting to do, but it was rather slow at first and by the time I figured out what I did wrong and how to fix it, I had already moved on to other projects and didn't bother. But basically I kept arrays that held a speed value, last changed, LED current value, and whether the LED is fading on or off. They all faded the same amount of steps (5), but they each faded at a different speed. Using millis(), I would check the last changed array with every loop and see if the difference between current time and last changed time was equal or larger than the speed. If so, I would make whatever change to the LED, whether fading up (+5) or down (-5) and update the last changed array. So essentially, if speed=2, the LED would fade up/down rather fast, whereas speed=10 would be slower.
And to really mess with one's visual perception, after an LED faded down completely, I would change the speed to a random number again. So no one LED would be fading on/off at the same speed that it just did its previous cycle.
My issue was that I was updating the string with every LED change as opposed to every cycle. It made for a very slow update. Pulling the string update outside of the LEDs update would've sped things up nicely.
Granted, this isn't the most optimized way to do it. I'm sure there are way better ways to do this but at the time I wrote it, I was just getting into individually addressable LED strings and was scratching my head quite a bit ...
@KirAsh, thanks for the FastSPI rec, will look into it ASAP.
Your older project sounds fantastic! Do you have any documentation? Would love to see. Also if you have any code you have to share, just as a reference . . .
Unfortunately, I no longer have that code, at least it's not easily accessible. It's sitting on a back-up drive somewhere ... kinda my purgatory for stuff never used and on their way to getting their electrons recycled. It's not that hard to write though. I won't have time to do anything till Sunday so if you can't come up with anything, I'll see what i can do then.
Just an update, in the meantime, I've also been considering other means of approaching this, including an analog method.
The first is Grumpy Mike's suggestion above:
The second is something else I found right here on the Arduino Forum:
The third is my analog solution, which would be to use a 555 Timer to control a shift register. I don't have a link for this one . . . any schematic suggestions are welcome!
A fourth final (and least attractive) solution is something I was considering with an Adafruit breakout board:
As a bonus, there is a method I've considered with my Teensy, but the comments I've gotten, although well-intentioned, have left me somewhat perplexed.
This is something I'm still actively working on, so I welcome input on all of the above (as well as anything I may not have thought of)!
One more. I didn't write this, but I do use this code by Osamu Iwasaki. He wired a single LED to each pin on a LilyPad (I've done it with a regular Uno as well) and his code will fade them randomly. You will need MsTimer2 for this to work. Video can be seen here:
// Fade all IO by Osamu Iwasaki
// November 10, 2010
#include <MsTimer2.h>
#define OUT_MIN 0 // first pin with LED
#define OUT_MAX 19 // last pin with LED - code will use everything between MIN and MAX
byte luminance[20];
byte lumi[20] = {};
void setup()
{
int i;
for(i = OUT_MIN; i <= OUT_MAX; i++){
pinMode(i, OUTPUT);
digitalWrite(i,LOW);
}
for(i = OUT_MIN; i <= OUT_MAX; i++){
digitalWrite(i,HIGH);
delay(150);
}
for(i = OUT_MIN; i <= OUT_MAX; i++){
digitalWrite(i,LOW);
//delay(50);
}
delay(1000);
MsTimer2::set(1, int_pwm);
MsTimer2::start();
}
void int_pwm() {
static int f_wait[20];
static int f_max_time[20];
static int f_speed[20];
static int f_ct[20];
static long f_interval[20];
static int ch;
for(ch = OUT_MIN; ch <= OUT_MAX; ch++){
if(f_wait[ch] == 0){
f_wait[ch] = f_speed[ch] + 1;
if( (f_ct[ch] < 255) )
if(luminance[ch] != 255)
luminance[ch] ++;
if(f_ct[ch] == 255){
if(f_max_time[ch] == 0)
f_max_time[ch] = 0; // On Max Time
else
f_max_time[ch] --;
}
if( (f_ct[ch] > 255) && (f_ct[ch] < 511) && (f_max_time[ch] == 0))
if(luminance[ch] != 0)
luminance[ch] --;
if(f_ct[ch] >= 511){
if(f_interval[ch] == 0){
f_interval[ch] = 10 * random(100); // fading seed
f_speed[ch] = random(1); // fading speed
f_ct[ch] = 0;
}
else
f_interval[ch] --;
}
else
f_ct[ch] ++;
}
f_wait[ch] --;
}
}
void fading(){
static byte counter = 0;
static boolean prev_off[20];
int i;
for(i = OUT_MIN; i <= OUT_MAX; i++){
if(lumi[i] == 0){
if(prev_off[i] == HIGH){
digitalWrite(i,LOW);
prev_off[i] = LOW;
}
}
else
lumi[i] --;
}
counter --;
if(counter == 0){
for(i = OUT_MIN; i <= OUT_MAX; i++){
if(luminance[i]){
digitalWrite(i,HIGH);
prev_off[i] = HIGH;
}
lumi[i] = luminance[i];
}
}
}
void loop(){
fading();
}