Go Down

Topic: WS2803 versus WS2801 (Read 17732 times) previous topic - next topic

KirAsh4

Can someone explain to me how using the Adafruit library written for the WS2801 can work for the WS2803 as this person claims it does.

The data being sent isn't the same for them, the WS2801 is send 24 clock cycles while the WS2803 needs 144.  So are they modifying the library?  Since there is no contact info on that page, I can't ask them directly.

marklar

I would try to hook it up and let it fly, it should work.  I ran through the code and see nothing that would need to be changed in reference to the 144 clock cycles.  I put one of those on a breadboard and used on of my WS2801 controllers, unmodified, and it faded up and down a white LED.  That tells me that any code that talks to a WS2801 - should work for the WS2803 as well.  I do not have the time right now to download and that specific library .. but I'd give it a 90% chance of working unmodified. 

KirAsh4

#2
Jan 27, 2012, 08:38 pm Last Edit: Jan 27, 2012, 08:58 pm by KirAsh4 Reason: 1
That's the thing, it's doing diddly squat for me ...  However, I have a feeling it's not the library, it's me.  I tried Adafruit's library, I tried FastSPI, and I tried bit banging my way through it.  No dice.  (Well, bit banging had *some* results, but not what was expected.) So yeah ... I'm pretty sure I'm screwing up somewhere.

--- some elevator music later ---
Yep, as expected.  In my infinite wisdom, I was looking at an old circuit I had made with the WS2801, and hooking up the LEDs the same way on the WS2803.  However, I neglected to notice that I reversed the polarity on the WS2801 for the type of LEDs I was using then.  So they were all reversed on the WS2803. :)  Once I flipped them, things are working now.  :)

marklar

Great - congrats on getting it going :)  Nice chip. 

KirAsh4

It works great with the Adafruit's library, either in SPI mode or bit banging mode.  With FastSPI however, not so good.  Need to figure that part out.

The one thing I noticed, using Adafruit's library.  Assume you put the ports together in groups of 3 (representing 6 RGB LEDs).  When using the SPI interface, the individual channels come up one after the other, meaning the 3 red channels will visibly come on one at a time, same for the green, and blue.  Now, if I switch it to use two arbitrary pins for SDA and SCK, the individual channels come on at the same time.  Same time delay, the only thing changing is whether I'm using SPI, or two other pins.  It seems odd.  But at the same time, it has it's potential, having the channels come on one at a time like that.

CrossRoads

The outputs change state 500uS after the data stops changing. I would guess 500uS is allowed to lapse in one situation and not the other.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

KirAsh4

I think you're right there CR.  What I'm noticing with FastSPI is when the code is first uploaded, only one group of 3 output pins will come on.  If I hit reset, the second group comes on, hit reset again and the next comes on ... so it takes hitting the reset button 6 times to get all the outputs on.    Now granted, FastSPI only has support for the WS2801 and not the WS2803 ... so I would expect some sort of oddity to happen ... like constantly hitting reset. :)

KirAsh4

The next question is trying to figure out how to address individual outputs.  With Adafruit's WS2801 library, it turns the outputs on in groups of 6.  So if I send it Color(r, g, b) with r=255, g and b=0, I get ouputs 0, 3, 6, 9, 12, and 15 turned on.  If I send r=0, g=255, and b=0, the next set of outputs come on, 1, 4, 7, 10, and 16.  And with b=255, r and g=0, the last set comes on, 2, 5, 8, 11, and 17.

I think it's possible to address each one separately, it's figuring out how to change the library to do that.

CrossRoads

You have a bunch connected in series, yes?
So if you don't want to change, I would think you'd want to send it the same data again.

So end out out chips worth of data every time, and just change the ones you want to change.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

KirAsh4

Nope, just a single one (for now.)  One WS2803 with 18 output ports.  Using the current WS2801 method to send data to it, lights up the 18 ports in groups of 6, and I figured out why.

I worked out one work around for now.  Because the WS2801 library only sends out 24 bits, and WS2803 accepts 144 bits before it starts relaying, it made sense that when the code was sending data, the IC was simply waiting till it received 144 bits and then latched the data.  I just never noticed it because there was no delay.  So, what I did was the following:
Code: [Select]
  for (int i = 0; i < 6; i++) {
    switch (i) {
      case 0:
        strip.setPixelColor(i, Color(255, 0, 0));
        break;
      case 1:
        strip.setPixelColor(i, Color(0, 255, 0));
        break;
      case 2:
        strip.setPixelColor(i, Color(0, 0, 255));
        break;
      case 3:
        strip.setPixelColor(i, Color(255, 255, 0));
        break;
      case 4:
        strip.setPixelColor(i, Color(255, 0, 255));
        break;
      case 5:
        strip.setPixelColor(i, Color(0, 255, 255));
        break;
    }
    strip.show();
    delay(250);
  }


By grouping the ports in groups of 3 (R, G, B), I can then refer to them with index numbers 0 to 5.  So when I sent Color(255, 0, 0), I was addressing the first group of 3 ports, setting out0 to 255, out1 to 0, and out2 as 0.  This effectively turned on the first of the three ports.  Sending Color(255, 0, 255) turned on ports 0 and 2 .... etc., etc.

Following the above, I'm turning on ports 0, delay, 4, delay, 8, delay, 9, 10, delay, 12, 14, delay, 16, and 17 successively.  The rest are all off.

Like I said, this is a work around.

KirAsh4

Or this piece that cycles through each port one by one, using the WS2801 Color(r, g, b) method:
Code: [Select]
  for (int p = 0; p < 6; p++) {   // 6 groups of 3
    for (int c = 0; c < 3; c++) {   // each group has 3 ports
      switch(c) {
        case 0:
          strip.setPixelColor(p, Color(255, 0, 0));
          break;
        case 1:
          strip.setPixelColor(p, Color(0, 255, 0));
          break;
        case 2:
          strip.setPixelColor(p, Color(0, 0, 255));
          break;
      }
      strip.show();
      delay(50);
    }
    strip.setPixelColor(p, Color(0, 0, 0));
  }

KirAsh4

Ultimately, it's just fine because most people will want to use RGB LEDs anyway, so with the ports being grouped it works out.

marklar

#12
Jan 28, 2012, 02:50 pm Last Edit: Jan 28, 2012, 02:56 pm by marklar Reason: 1
Quote
The next question is trying to figure out how to address individual outputs.  With Adafruit's WS2801 library, it turns the outputs on in groups of 6.  So if I send it Color(r, g, b) with r=255, g and b=0, I get ouputs 0, 3, 6, 9, 12, and 15 turned on.  If I send r=0, g=255, and b=0, the next set of outputs come on, 1, 4, 7, 10, and 16.  And with b=255, r and g=0, the last set comes on, 2, 5, 8, 11, and 17.

I think it's possible to address each one separately, it's figuring out how to change the library to do that.


Here is an updated version of the library that addresses each LED individually.  Have not tested with the WS2803 - just WS2801.

Differences from the WS2801 proper library:
The led count used when creating the object should be the individual LED count
The setPixelColor method takes only one color param due to being single LED.
The getPixelColor method returns a standard 8 bit color value
The example just lights up one after another in a loop.


This should provide an easy starting point for addressing individually.  I'll try to find time to test with WS2803 but have circuit questions.


marklar

#13
Jan 29, 2012, 04:04 pm Last Edit: Jan 30, 2012, 02:09 pm by marklar Reason: 1
The comments below are from initial testing only and are subject to change based on feedback.

Findings:
The 144 bit requirement means this chip needs to be fed in full 18 LED values.  So if you have 52 LEDs, you have to say 54 LEDs in the setup and then just turn the last two off in your code if using the old library.  I created a version of the single library that buffers the last part automatically allowing you to use 52 in your code.  

Other notes:
The data does not go into the chips the say way.  The order of the ports is normal 0 through 17 but the data is sent to each chip backwards.  So if you have three chips, the first chip data should be chip 3 and the final chip data should be chip 1.   An updated version of the library attached below - replacing the old one.

Updated Library:
Attached is the WS2803Single library:
Update 1) This version will buffer the difference if an increment of 18 LEDs is not used. Note that when you use numPixels() it will return the new LED count, not the value passed in. So if you start with 37 - it is buffered to 54 .. so numPixels() will return 54.  In your code you can simply use the same value originally instantiated .. just do not rely on the numPixels method for this unless you want to include buffered LEDs not attached in your patterns.
 
Update 2) This library sends the data in the correct order (chips backwards - ports forward).  This should make using the original library for WS2801 .. the singleWS2801 and this library work with no other change needed in the code outside the class and library names. Tested both SPI and bigbang methods.

marklar

Just a FYI - I updated the above library with changes noted as update 2 along with fixed findings.  I did not want someone reading false findings so I just cleaned up the above post and posted the updated library.  Leaving this post just in case someone had already been through the last post and/or downloaded it.

Go Up