Hello.
I am finally got to seriously play with Arduino boards and want to control bank of 24 LEDs. Idea at the moment is to create a single wave of light. I thought I was on the right track, but results are not what I expected.
Here is my code snippet:
float in, out;
for (in = 0; in < pi * 2; in = in + pi/500)
{
for (int i = 0; i <= 23; i = i + 1)
{
if (in > pi * 2 * i / 24 )
{
out = ((cos((in - pi) - (i*(pi*2)/24))+1)/2) *4095;
tlc.setPWM(i, out);
tlc.write();
}
}
}
There must be a simple solution for this and it just escapes me.
Any help is appreciated
I’m not following what you’re trying to do, or how the LEDs are arranged.
Are the LEDs arrayed in a line, a circle, or something else? Which LEDs do you expect to be lit at any given phase of the circle?
One thing that is unusual looking is the if block. Note that the LEDs for which
in <= pi * 2 * i / 24
Will be unchanged from whatever their previous state was. For most purposes of this type, you would have an else block to turn lights off or some such.
Edit: Also, did you really mean to have 24,000 calls to the cos() function per wave? That could take a while on an arduino.
Do you have an array that is 24 LEDs tall by some other number of LEDs wide? If so, how wide? Your current algorithm seems to be directed at filling an array 24 x 1000 LEDs. If your array is shorter (or longer) than this, you will need to change the increment of the outer loop. (Change the 500 to half of your array length.) If that doesn’t do it, I can’t help much more without seeing the details of the libraries and possibly hardware (LED array) you’re using; a link to a page about the array would probably be enough of a lead.
If you have a single long strip of 24 individually controllable LED lights (such as this), you are probably asking about a KITT light, or a Battlestar Glactica Cylon light, or (more generically) a Larson scanner, who created the effect, you can do a search for the names and get plenty of solutions. Adafruit has a nice project that explains it. Your LEDs might have different calls to address the bulbs, but the code concept is the same. This is what it sounds like you’re trying to do.
If, instead, you have an array of the LEDs, to make a sine wave, that’s different.
If this is your first time working with LED strips, look for examples on how to use that particular type and try them out, making changes to the examples to see how the code operates.
Sometimes (most of the time) if your code “doesn’t work” it is just missing one important bit, or your hardware isn’t wired correctly. Code examples that work eliminates a lot of errors.
Thank you all for helping me.
Roger, your first half of your post is most helpful. I will poke at them tonight when I get home.
What I have is Adafruit 24-Channel 12-bit PWM LED Driver - SPI Interface - TLC5947 with individual 24 simple LEDs connected.
Sin or Cos wave is not to display a wave on LED matrix, but rather control brightness of the LEDs of a row of LEDs and that where PWM controller interface come in play.
I don’t have NeoPixel strip yet. I will order NeoPixel or DotStar when I get my tax refund :). Perhaps it is easier for what i am trying to do. We’ll see.
The older LED Strips work just as well, by the by. It’s mostly density and how they are programmed. The one I pointed out just happened to be the high end $. The lower end cost ones work well with the Arduino family without added boards. With 24 you can get by with just power off the Arduino.
Just be extremely careful not to feed the LEDs with more volts than specified!
Those may be more work than I could take. You have to wire them up yourself, but you do get to put them in your own pattern, even arrays or more. (Just have to wire them serially.)
Searching around for ws2812b I found Sparkfun’s tutorial on their own WS2812 and their Breakout board, with of course code. Again, start with their libraries and their examples, and get the feel for the method before trying your own.
float in, out;
for (in = 0; in < pi * 2; in = in + pi/500)
{
for (int i = 0; i <= 23; i = i + 1)
{
if (in > pi * 2 * i / 24 )
{
out = ((cos((in - pi) - (i*(pi*2)/24))+1)/2) *4095;
tlc.setPWM(i, out);
tlc.write();
}
}
}
I don’t think this does what you think it does.
Running it thru a spreadsheet, that** if (in > pi * 2 * i / 24 )** only is true for 1 of the 24 i loops, so re-sets the LED 1/24th of the time. Good practice is setting the LED each loop, even if it is off, because the LED will keep the previous number until changed.
When it does set the LED, out is in a range from zero to the low 4000s. If these LEDs are typical, the range is zero (off) to 255 (full on). Plus if they are color, you have to set each Red-Green-Blue to a level – typically something like
tlc.setPWM( i, color( outR,outG,outB ) );
Find the command in the examples; I’m just guessing what it is.
Thank you Roger, that is useful info I didn’t have. I hope LEDs will arrive soon for me to try them.
I am getting tired of TLC5947, as it continues to produce some artifacts that are not in the code. I tried 3 simple loops, 1st 100%, 2nd 50% and 3rd 0% brightness. It all works as expected but at the end of second loop all LEDs blink.
I am still waiting for ws2812b LEDs, but after a bit of a break and then practicing on direct PWM pins, I finally cleaned up logic enough for it to do almost what I want. Here is what I got so far:
void loop() {
float in, out, temp;
int i;
for (in = -pi; in < pi * 24; in = in + pi / 50)
{
for (i = 0; i <= 23; i = i + 1)
{
temp = 2 * pi / LED_Group * i;
if (in >= -pi + temp && in <= pi + temp )
{
out = cos(in - temp) * 2048 + 2047;
tlc.setPWM(i, out);
tlc.write();
}
}
}
}
LED_Group is for controlling how many LED to include in a wave