And I want to make different programs run at the same time.
At the moment I have for loops for each strip and they run one after the other. I'd like if they run at the same time. All strips have different number of pixels.
Is it possible somehow?
I have 3 different strips with different lengths.
strip1 - 113 pixels on pins 2 and 3
strip2 - 46 pixels on pins 4 and 5
strip3 - 88 pixels on pins 6 and 7
If I want to use colorWipe function, I have to make 3 of them. Maybe I can use arrays of strips somehow?
It also uses delay and I have no idea how to get rid of it.
Some example code
#include "SPI.h"
#include "WS2801.h"
WS2801 strip1 = WS2801(113, 2, 3);
WS2801 strip2 = WS2801(46, 4, 5);
WS2801 strip3 = WS2801(88, 6, 7);
void setup() {
strip.begin();
strip.show();
}
void loop() {
colorWipe1(Color(255, 0, 0), 50);
colorWipe2(Color(0, 255, 0), 50);
colorWipe3(Color(0, 0, 255), 50);
}
void colorWipe1(uint32_t c, uint8_t wait) {
int i;
for (i=0; i < strip1.numPixels(); i++) {
strip1.setPixelColor(i, c);
strip1.show();
delay(wait);
}
}
void colorWipe2(uint32_t c, uint8_t wait) {
int i;
for (i=0; i < strip2.numPixels(); i++) {
strip2.setPixelColor(i, c);
strip2.show();
delay(wait);
}
}
void colorWipe3(uint32_t c, uint8_t wait) {
int i;
for (i=0; i < strip3.numPixels(); i++) {
strip3.setPixelColor(i, c);
strip3.show();
delay(wait);
}
}
uint32_t Color(byte r, byte g, byte b)
{
uint32_t c;
c = r;
c <<= 8;
c |= g;
c <<= 8;
c |= b;
return c;
}
If I want to use colorWipe function, I have to make 3 of them. Maybe I can use arrays of strips somehow?
It also uses delay and I have no idea how to get rid of it.
Clearly, you need to not want to use the colorWipe function, then.
Look at what that function is doing. For each instance of the WS2801 class, it determines how many pixels there are, sets one of them, shows the result, and waits.
If you want to light up each strip, end to end, in the same amount of time, you need to determine the maximum number of pixels, and loop that number of times. For each strip then, you determine if it is necessary, on this pass through the loop, to set and show a pixel in that strip. If so, do it. Then, at the end of the loop, wait for as long as you want.
I want to use colorWipe-like function but without delay. I want to light up all strips beginning from one end and filling up to the other.
I want to use one function, that takes each instance of the class from array maybe. What aray should I use and is it possible to put strip1, strip2 and strip3 in an array?
I'd also like, if it takes same amount of time with 100 pixels and with 25 pixels. 100 pixel strip must run 4 times faster.
I also want to be able to change speed, color. And make more cool functions if I can figure out something.
What aray should I use and is it possible to put strip1, strip2 and strip3 in an array?
The type of the array needs to match the type of the elements in the array. A char array holds chars. An int array holds ints. A WS2801 array holds WS2801s.
You need to be careful initializing the elements of the array.
I want to light up all strips beginning from one end and filling up to the other.
So, light up each pixel in strip1, then light up each pixel in strip 2? That's what the code you posted does, isn't it?
I'd also like, if it takes same amount of time with 100 pixels and with 25 pixels. 100 pixel strip must run 4 times faster.
Then you need different wait values for each strip.
Not sure you can quite get there as you intend.
Read the WS2801 data sheet. To make the outputs change, you send out a long string of data - and when the WS2801 sees that you have stopped sending data for some amount of time (500 or 600uS) it updates its outputs.
If you want all three to change at once, you need to send the data out for all three as one long string - device 1 passes to device 2, device 2 passes to device 3, then all three see data stop flowing together and update their outputs together.
I have different strips on different pins. It's not one long strip.
I send 3 long strings of data, not one.
I could send all update commands at the same time.
Or I could also use some chip, that takes 1 SPI input and splits it to multiple outputs that I could configure.
Let's say I have 300 pixels.
1-300 goes to input.
1-100 data goes to output 1
101-200 data goes to output 2
210-300 data goes to output 3
If you have three strips, using three separate pairs of pins, then why can't you send the data out to all of them (one after the other) and then send the clock signal to all of them (one after the other) which will update all of them within a few ms of each other. Hardly noticeable.
If you want the shorter string to update faster than the longer string, then just clock it sooner. It all depends on the clock delay. If you don't clock them, they do nothing. You have to update the clock for each string for them to actually update.
I have 3 strips with different lengths. I want to use same color run for all of them. I want all strips start and finish at the same time. But if they are different length, they need to have different speeds. And without delay.
All strips must start from the beginning and go pixel after pixel next colour.
Like the first run in this video.
As I said, you control the clock signal, so you control when each individual strip updates. Put another way, they will not update until YOU pulse the clock line. So let's say you have one strip with 100 pixels, and one with 25 pixels. And you want both to start at pixel 0 and reach the end of the strip at the same time. That means that for the 100 pixel strip, you are clocking it 4 times faster than the 25 pixel one (because 25 x 4 is magically 100).
So in your code, simply loop through your sequences and clock each individual strip when they need to be. Basically that means that the 100 pixel strip will see 4 updates before the 25 pixel strip sees one. In terms of lighting each pixel individually, that means the longer strip will see 4 pixels light up before the shorter string sees it's first one.
Again, you control the clock line, you control when you want each strip to update.
In the above example, one very simple method is to use a counter, or the modulo method. Basically you update the shorter strip based on what pixel you are at on the longer one, in this case, every 4th one:
PSEUDO CODE:
int cnt = 0;
if (cnt > 3) {
// update short string
cnt = 0;
}
// update long string
cnt++;
Or:
PSEUDO CODE:
cnt = 0;
if (!(cnt % 4)) {
// update short string
}
// update long string
cnt++;
I did it with counter that increase every loop cycle and then used modulo to decide, when I should move to next step. Then I came here and You suggested the same thing. I think I somehow subconsciously read this thread.
Program without delay works with 1 strip. Actually I can't say it's without delay, because I use one delay in the end of loop. Otherwise my counter would increase too fast and I must use bigger numbers with modulo.
Now I should probably make WS2801 array and try to calculate functions for them.