sonyhome / FAB_LED

Fast Arduino Bitbang LED library supports programmable LEDs (WS2812B, APA102...), color palettes for Arduino AVR
GNU General Public License v2.0
125 stars 17 forks source link

Combining a WS2812 strip in series with a SK6812 strip #2

Closed lukony closed 8 years ago

lukony commented 8 years ago

Hello. I modified your example a bit. Here it is. To be honest, I'm mostly lost so far.

My setup is following: 12x WS2812b + 30x SK6812 in series.

Modified test do following: All 12pixels of WS2812b light up by RED color, together with first 12pixels of SK6812 which lights WHITE and little, little bit of BLUE. Wait one sec, Clean.

May be that after some good sleep I will understand more, but so far I'm stacked with NUMPIXELS. Basically, both kind of strips have to be identical length, otherwise I'm not able to control them.

What I miss is simple declaration like this: "light up pixel no.10, type WS2812b, color RGB 255,0,0" "light up pixel no.12, type SK6812, color RGBW 0,0,10,255"

I didn't study your library much. All my current project used Adafruit library so far, so please apologize my silly questions.

B.R. Lukas

sonyhome commented 8 years ago

Your issue is you need to adjust the size of the LED arrays passed:

You have 12+30 pixels so this is good:

define NUM_PIXELS 42

There was at least one error here so use this correction: myWs2812.sendPixels(12, rgbwPixels); mySk6812.sendPixels(30,&rgbwPixels[12]); It says:

It could be also that you need to reverse both lines depending on your wiring: mySk6812.sendPixels(30, rgbwPixels); myWs2812.sendPixels(12, &rgbwPixels[30]);

Try both and see if it works... On success all LEDs will be red.

Once you have that, you have a draw routine, and you can delete all the rest. Then you just put any colors on any LED you want, and use the same drawing routine to show it.

lukony commented 8 years ago

Hey, your code work as charm. :-) After proposed modification I got all 12+30 pixels working. :-)

My project use addressing of particular pixels without modifying value of other pixels in the strip. Is that possible? Probably yes, if I define array for full strip length, then modify particular data in array and update whole strip by sending array values?

Now its time to setup some colors.

While using setup like this, I'm getting 12x blue and 30x bluish white void setup() { for (int i=0; i < NUM_PIXELS; i++) { // Initialize rgb array to show as red strip rgbPixels[i].r = 16 + 16 * (i%2); // Initialise grb array to show as green grbPixels[i].g = 16 + 16 * (i%2); // Initialize rgbw array to show as blue rgbwPixels[i].b = 16 + 16 * (i%2); rgbwPixels[i].w = 16 + 16 * (i%2); } While using this setup, Im getting 12x red and 30x white with little dose of red.

void setup() { for (int i=0; i < NUM_PIXELS; i++) { // Initialize rgb array to show as red strip rgbPixels[i].r = 16 + 16 * (i%2); // Initialise grb array to show as green grbPixels[i].g = 16 + 16 * (i%2); // Initialize rgbw array to show as blue rgbwPixels[i].r = 16 + 16 * (i%2); rgbwPixels[i].w = 16 + 16 * (i%2); }

So it seems like WS2812b color has very gentle influence on SK6812 color.

Can you please advice me how I define for example orange or pink color?

sonyhome commented 8 years ago

You need to delete all the functions but Lukas, setup and loop. Then delete all arrays except rgbwPixels.

So you understand, in the setup, the 16+16 * i%2 is just a way to not have all pixels the same color, some will be slightly brighter. It's for cosmetics...

All you have to do now is set the colors in the rgbwPixels array to what you want.

Orange and pink I suggest you use a color picker online for like web pages, and use that to get hex values: You will often be given something like a 0x0e3fbc code, which means Red=0x0E Green=0x3F and Blue=0xBC (this is hex notation). So set your pixels to that color and turn them on.

Pink is red + white so put the same value in G and B to brighten the red to a pink. Orange I think is red and green, so brighten green until it works...

Your Lukas() function is what will draw your LEDs now, you're set on that part. Just figure out how to write the colors you want in your pixel array.

You need to write a loop that sets the colors in the array and pass it to that function.

Go to Arduino.cc there's a coding help forum if you need entry level coding help.

If you can "star" this tool here and promote it I'll appreciate it so it gets some notice. :)

MEanwhile I will close this issue since I believe I solved your main request, and will mark you down as one of the folks who's tested the sk6812 LEDs.

All the best with your project :)

sonyhome commented 8 years ago

BTW,

If you can share and allow me to use a photo or video of your LED strips working and how they are connected to each other it would be great.

lukony commented 8 years ago

Hello. Of course, I will gladly share some video when I have full control above strips :-) I just have to rebuild all my code from Adafruit library to your lib. Small example vid.

Now I get the point! :-))

for (int i=0; i < NUM_PIXELS; i++) {

// Initialize rgb array for WS2812b strip
rgbPixels[i].r = 80;  // lights up RED pixel on positon [i] by specified value 0-255
rgbPixels[i].g = 50; // lights up GREEN pixel on positon [i] by specified value 0-255
rgbPixels[i].b = 0;   // lights up BLUE pixel on positon [i] by specified value 0-255

// Initialize rgbw array for SK6812 strip
rgbwPixels[i].r = 50; // green (there is SWAP with green)
rgbwPixels[i].g = 80; // red (there is SWAP with red)
rgbwPixels[i].b = 0;  // blue with little bit of white
rgbwPixels[i].w = 5; // white

}

I noticed SWAP between red and green for rgbw strip, but its just minor issue. May be that its just matter of my particular SK6812 strip. I ordered just 60pixels and don't have any reference to other brands or sellers.

Can your library support more "Adafruit like" working with array, so instead of three rows .r, .g, .b I can use single row? rgbStrip1.setPixelColor(i, rgbStrip1.Color(80,50,0)) // sounds quite understandable to me.

lukony commented 8 years ago

I modified your example code. Now it works like this. https://youtu.be/hlfaLeGNjjM

sonyhome commented 8 years ago

There may be a bug:

Can you run test A, and verify that both LED strips light up R, G, B, off in that order? If the SK lights up G, R, B, off then I have a bug in the code.

Again,

Let's say you have 12 + 30 pixels, you only have to manage ONE array:

for (int i=0; i < NUM_PIXELS; i++) {
  rgbwPixels[i].r = 50; // green (there is SWAP with green)
  rgbwPixels[i].g = 80; // red (there is SWAP with red)
  rgbwPixels[i].b = 0;  // blue with little bit of white
  rgbwPixels[i].w = 5; // white
}
// Display the pixels
mySk6812.sendPixels(30, rgbwPixels);
myWs2812.sendPixels(12, &rgbwPixels[30]);

Adafruit syntax: rgbStrip1.setPixelColor(i, rgbStrip1.Color(80,50,0)) Is the same as: rgbwPixels[i].r = 50; // green (there is SWAP with green) rgbwPixels[i].g = 80; // red (there is SWAP with red)

If you really want to go into RAW mode with my library, you could go like this:

uint32_t rawPixels[42];
for (int i=0; i < NUM_PIXELS; i++) {
  rawPixel[i] = 0x50320000; // GRBW, decimal-to-hexadecimal: 50=0x32 and 80=0x50
}
// Display the pixels
mySk6812.sendPixels(30, rawPixel);
myWs2812.sendPixels(12, &rawPixel[30]);

I could probably add a command if you want the color() function, it could look something like...

 color<rgbw>(rgbwPixels[i], 50, 80, 0, 0);
 rgbwPixels[i].color(50, 80, 0, 0);
 rgbwPixels[i] = color(50, 80, 0, 0);

depending on how I code it.

lukony commented 8 years ago

Hello. Red and Green is really swapped when driving SK2812. I tested SK2812 strip directly connected. But its not an issue and I have no assurance that other SK2812 from different Chinese manufacturer will act the same way.

I'm workarounding like this: rgbwPixels[i].g = r; rgbwPixels[i].r = g; rgbwPixels[i].b = b; rgbwPixels[i].w = w;

Actually I used to your syntax and its working fine. No need for strictly Adafruit one :-)

Hey, one question. I noticed those small Chinese paper lanterns in your avatar picture. Is code for that party lights public or private? I'm thinking about creating something colorful and hang it in my garden :-)

sonyhome commented 8 years ago

https://github.com/sonyhome/FAB_LED/tree/grbw

I added sk6812b to solve your issue (GRBW sk6812 LED strip), and updated example A, in particular Lucas function matches your hardware setup now and should light up RGBW in that order.

For the chinese lanterns, I'd have to look for the code... It might take a while to find it.

lukony commented 8 years ago

Hello. Sorry for one day delay. I deleted old library for sure, downloaded new one and tested.

May be I overlooked something in my code. Please check. https://www.dropbox.com/sh/mungf3i32cckr6d/AAABCUqaJJdnqViwYaIyLDoTa?dl=0

LightUpFootwell(10,0,0,0,numleds,del); might light up 15 LEDs by moderate Green color. Actually its Red instead, but Im not sure whether my code is correct.

B.R. Lukas

sonyhome commented 8 years ago

I went a bit too fast and coded APA102 support and ARM support, but now the code is broken. So you know. I will need to test which change I did that broke everything, and fix it.

I can look at your code later, if it's just red instead of green just change the class you're using: For sk6812, I have two, sk6812 nd sk6812b (one is RGB one is GRB, so use the other one). For ws2812b, I have 3, apa104, ws2812b, ws2812, and mostly they are different timings, all GRB.

lukony commented 8 years ago

Hello. You are right. sk6812b do the trick. So most probably I have grbw strip instead of rgbw one as I thought initially :-)

Thanks for great support. Have a nice weekend there :-)

DaxInvader commented 7 years ago

Hello sonyhome, I came across this thread as I am building a similar project. I am mixing WS2812 with SK6812RGBW simply because I didn't have enough 2812.. Basically, I am doing the same thing as Lukas, but I am doing 52 WS2812 and the rest SK6812 for a total of 132 LEDS. Right now, I have 52(WS) +8 (SK) and I am having issues with the updated lukas code. Red and green show random colors for the sk and blue and white seems to work fine.

here is my code:

`//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /// Fast Adressable Bitbang LED Library /// Copyright (c)2015, 2016 Dan Truong /// /// This is an example use of the FAB_LED library using the predefined pixel /// structures rgb, grb, bgr, rgbw. It is a good first test to validate the /// library works with your LED strip, and if needed to figure out what type /// of LED strip you actually have. /// On success the LEDs will cycle red, green, blue, pause. /// /// This example works for an Arduino Uno board connected to your PC via the /// USB port to the Arduino IDE (integrated development environment used to /// compile and load an arduino sketch program to your arduino board). For /// other boards, you may have to change the port you are using. /// /// Wiring: /// /// The LED strip DI (data input) line should be on port D6 (Digital pin 6 on /// Arduino Uno). If you need to change the port, change all declarations below /// from, for example from "ws2812b<D,6> myWs2812" to "ws2812b<C,7> myWs2812" /// if you wanted to use port C7. /// The LED power (GND) and (+5V) should be connected on the Arduino Uno's GND /// and +5V. /// /// LED strip type: By default WS2812B LED code is uncommented in loop(). If /// your LED strip is another type, comment that and uncomment the function /// name that matches your LED strip. /// /// Visual results: /// /// If you use the proper LED type, your LED strip will light up in sequence /// red, green, blue then white before turning off. /// If you picked the wrong one, the order will be different, or may be /// jumbled random colors. If so try another. /// /// Details of this test: /// /// This test is going to send each type of pixel array to your LED strip. /// If the array format is the same as the LED strip (native order), the array /// is send as-is and will display correctly. /// If the array format is not the same as the LED strip, the library will /// convert the array data to be sent in the right order (it send each color /// separately for each pixel). This is slower to do, and in some cases the LED /// strip display might become buggy, if the time it takes to do the conversion /// takes too long for the LED strip. This should not happen but it could! /// In other words, even in this case the array will display correctly. :) //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

include

//////////////////////////////////////////////////////////////////////////////// /// @brief This parameter says how many LEDs will be lit up in your strip. /// If you power t

///he LED strip through your Arduino USB power supply, and not /// through a separate power supply, make sure to not turn on too many LEDs at /// once. Maybe no more than 8 at full power (max is 60mA at 5V is 0.3Watt/LED).

define NUM_PIXELS 132

//////////////////////////////////////////////////////////////////////////////// // Classes to write to a GRB WS2812B LED strip and a RGBW SK6812 LED strip. // All are controlling port D6 by default, so attach your LED strip data line // to pin 6 on an Arduino Uno. It may be another pin on other boards. ws2812b<D,6> myWs2812; sk6812<D,6> mySk6812; sk6812b<D,6> mySk6812b;

//////////////////////////////////////////////////////////////////////////////// // We define 3 arrays as example, each storing pixels in a different order. // The rgbw order is native to sk6812 // The grbw order is native to sk6812b // The grb is native to ws2812b // the rgb is native to apa106 // Whichever array we use, should on any LED strip display a single solid // color as defined in setup. This is because the library will convert the pixel // on display if it is not native (that is slower to run so avoid it if you can). // If there's a bug, some of the displays will be random colors. rgbw rgbwPixels[NUM_PIXELS] = {}; grbw grbwPixels[NUM_PIXELS] = {}; rgb rgbPixels[NUM_PIXELS] = {}; grb grbPixels[NUM_PIXELS] = {};

// Demo display on WS2812B LED strip void showWs2812b(void) { // Show rgb array (red) myWs2812.sendPixels(NUM_PIXELS,rgbPixels); // Wait to have display lit for a while delay(1000);

// Show grb array (green) myWs2812.sendPixels(NUM_PIXELS,grbPixels); delay(1000);

// Show rgbw array (blue) myWs2812.sendPixels(NUM_PIXELS,rgbwPixels); delay(1000);

// Show grbw array (white) myWs2812.sendPixels(NUM_PIXELS,grbwPixels); delay(1000); }

// Demo display on RGB SK6812 LED strip void showSk6812(void) { // Show rgb array (red) mySk6812.sendPixels(NUM_PIXELS,rgbPixels); // Wait to have display lit for a while delay(1000);

// Show grb array (green) mySk6812.sendPixels(NUM_PIXELS,grbPixels); delay(1000);

// Show rgbw array (blue) mySk6812.sendPixels(NUM_PIXELS,rgbwPixels); delay(1000);

// Show grbw array (blue) mySk6812.sendPixels(NUM_PIXELS,grbwPixels); delay(1000); }

// Demo display on GRB SK6812 LED strip void showSk6812b(void) { // Show rgb array (red) mySk6812b.sendPixels(NUM_PIXELS,rgbPixels); // Wait to have display lit for a while delay(1000);

// Show grb array (green) mySk6812b.sendPixels(NUM_PIXELS,grbPixels); delay(1000);

// Show rgbw array (blue) mySk6812b.sendPixels(NUM_PIXELS,rgbwPixels); delay(1000);

// Show grbw array (blue) mySk6812b.sendPixels(NUM_PIXELS,grbwPixels); delay(1000); }

// This method shows that all pixel types work seamlessly // for all LED strip types. It is better to use the pixel // type that matches your LED strip as it will be faster // and more compact code, but otherwise, it should not // change the outcome of your display. template void showSequence(void) { myStripClass myStrip;

// Show rgb array (red) myStrip.sendPixels(NUM_PIXELS,rgbPixels); // Wait to have display lit for a while delay(1000);

// Show grb array (green) myStrip.sendPixels(NUM_PIXELS,grbPixels); delay(1000);

// Show rgbw array (blue) myStrip.sendPixels(NUM_PIXELS,rgbwPixels); delay(1000);

// Show grbw array (blue) myStrip.sendPixels(NUM_PIXELS,grbwPixels); delay(1000); }

// This is for Lukas who wants to mix LED strips // with different display formats: // Demo display of one WS2812B LED strip soldered // before a SK6812 LED strip, both displaying the // same colors, so the end result should be to // see R then G then B then W. For fun, ws2812b // LED white is done with R=G=B=16, and white on // sk6812 with R=G=B=0 and W=48. // There will be pixCut WS2812B pixels (52) and // NUM_PIXELS - pixCut (80) Sk6812 pixels. // If the LED configuration does not match the code, // the pixels will have multiple colors and more or // fewer LEDs will light up. This is because one // LED strip uses 3 bytes per pixels, and the other // uses 4 bytes per pixel. void lukas(void) { const uint16_t pixCut = 52;

// Test rgb array // Disable interupts const uint8_t oldSREG = SREG; cli(); // Draw the pixels, sk strip is after ws strip hence pushed first. myWs2812.sendPixels(pixCut, rgbPixels); mySk6812b.sendPixels(NUM_PIXELS - pixCut, &rgbPixels[pixCut]); // Enable interupts SREG = oldSREG; // Wait to have display lit for a while delay(1000);

// Test grb array cli(); myWs2812.sendPixels(pixCut, grbPixels); mySk6812b.sendPixels(NUM_PIXELS - pixCut, &grbPixels[pixCut]); SREG = oldSREG; delay(1000);

// Test rgbw array cli(); myWs2812.sendPixels(pixCut, &rgbwPixels[0]); mySk6812b.sendPixels(NUM_PIXELS - pixCut, &rgbwPixels[pixCut]); SREG = oldSREG; delay(1000);

// Test grbw array for (int i= pixCut; i < NUM_PIXELS; i++) { grbwPixels[i].r = 0; grbwPixels[i].g = 0; grbwPixels[i].b = 0; grbwPixels[i].w = 16*3; } cli(); myWs2812.sendPixels(pixCut, &grbwPixels[0]); mySk6812b.sendPixels(NUM_PIXELS - pixCut, &grbwPixels[pixCut]); SREG = oldSREG; delay(1000); }

//////////////////////////////////////////////////////////////////////////////// /// @brief This method is automatically called once when the board boots. //////////////////////////////////////////////////////////////////////////////// void setup() { for (int i=0; i < NUM_PIXELS; i++) { // Initialize rgb array to show as red strip rgbPixels[i].r = 16; // Initialise grb array to show as green grbPixels[i].g = 16; // Initialize grbw array to show as blue rgbwPixels[i].b = 16; // Initialize rgbw array to show as white grbwPixels[i].r = 16; grbwPixels[i].g = 16; grbwPixels[i].b = 16; } }

//////////////////////////////////////////////////////////////////////////////// /// @brief This method is automatically called repeatedly after setup() has run. /// It is the main loop, and it calls all the other demo methods declared below. //////////////////////////////////////////////////////////////////////////////// void loop() { // Init the LEDs, all off, up to 1000 LEDs. mySk6812.clear(1000); delay(500);

// Comment all function calls here EXCEPT for the one that matches your LED // strip if you want to see the right color sequence of red, green, blue: //showWs2812b(); // showApa104(); // showApa106(); // showSk6812(); // showSk6812b(); // showSequence< sk6812b<D,6> >(); lukas(); // mBlade(); } `

if you need I can attach a short video of what they do

DaxInvader commented 7 years ago

Here is a short video of the LEDs : https://www.youtube.com/watch?v=q5dBfX8aL8M How they are connected : http://imgur.com/zKr22Th

sonyhome commented 7 years ago

Yes,

It looks like you did not define properly the SK6812, which use 4 bytes hence the data gets skewed.

I suggest you use only one pixel array like the GRB, and delete the rest of the code. Then set colors in it and go from there. You should set the pixel counts and pixCut to your LED strip configuration. Looks like 8 SK6812 and 52, so:

NUM_PIXELS =60 and pixCut=52. Of course, if you reversed the strip, it would be 8 and 60.

On Wed, Dec 14, 2016 at 12:38 PM, DaxInvader notifications@github.com wrote:

Here is a short video of the LEDs : https://www.youtube.com/watch? v=q5dBfX8aL8M How they are connected : http://imgur.com/zKr22Th

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/sonyhome/FAB_LED/issues/2#issuecomment-267149522, or mute the thread https://github.com/notifications/unsubscribe-auth/AMmQgY-b7T3TzIRhfc5gSM5nc_axVQeHks5rIFOqgaJpZM4IIpuk .

sonyhome commented 7 years ago

Oh: I suggest lighting up first only the WS2812 to make sure you got the count right, then one SK LED

grbw grbwPixels[52+8] = {}; int red = 16; loop() { // Test grbw array for (int i= 0; i < 52+8; i++) { grbwPixels[i].r = red; grbwPixels[i].g = 0; grbwPixels[i].b = 0; grbwPixels[i].w = 0; } red++; if (red >= 255) red = 0;

cli(); myWs2812.sendPixels(52, grbwPixels); mySk6812b.sendPixels(8, grbwPixels); SREG = oldSREG; delay(100); }

On Wed, Dec 14, 2016 at 4:29 PM, Dan Truong dan.truong@gmail.com wrote:

Yes,

It looks like you did not define properly the SK6812, which use 4 bytes hence the data gets skewed.

I suggest you use only one pixel array like the GRB, and delete the rest of the code. Then set colors in it and go from there. You should set the pixel counts and pixCut to your LED strip configuration. Looks like 8 SK6812 and 52, so:

NUM_PIXELS =60 and pixCut=52. Of course, if you reversed the strip, it would be 8 and 60.

On Wed, Dec 14, 2016 at 12:38 PM, DaxInvader notifications@github.com wrote:

Here is a short video of the LEDs : https://www.youtube.com/watch? v=q5dBfX8aL8M How they are connected : http://imgur.com/zKr22Th

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/sonyhome/FAB_LED/issues/2#issuecomment-267149522, or mute the thread https://github.com/notifications/unsubscribe-auth/AMmQgY-b7T3TzIRhfc5gSM5nc_axVQeHks5rIFOqgaJpZM4IIpuk .

DaxInvader commented 7 years ago

You are a life saver! I am building a word clock for my girlfriend this christmas! You helped a lot! I am taking pictures every step of the way and do an instructables for it after. You will be credited! now if only I could add your library to my eclipse IDE... hehe

Thanks!!! and Happy holidays!

sonyhome commented 7 years ago

The library has ties to the arduino libraries because of register definitions, so it's not too easy to port out of AVR / Arduino onto other chips.

On Wed, Dec 14, 2016 at 5:56 PM, DaxInvader notifications@github.com wrote:

You are a life saver! I am building a word clock for my girlfriend this christmas! You helped a lot! I am taking pictures every step of the way and do an instructables for it after. You will be credited! now if only I could add your library to my eclipse IDE... hehe

Thanks!!! and Happy holidays!

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/sonyhome/FAB_LED/issues/2#issuecomment-267214709, or mute the thread https://github.com/notifications/unsubscribe-auth/AMmQgXNYW8j9tRROLRCxWsatSSr7TZhnks5rIJ5rgaJpZM4IIpuk .