Pages: 1 [2] 3 4   Go Down
Author Topic: please help with WS2811 led IC  (Read 23353 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't think I would give up on those 600 LED's quite yet. I don't think this is an impossible task by any stretch. First let me give the caveat that I'm not any good at AVR assembly so I might be off base here.

The english data sheet varies from the chinese one google finds for the values of T1H and T1L (1.2u/1.3u versus 2.0u/0.5u). In either case it's a total of 2.5u for each bit. This works out to exactly 40 clock cycles (2500ns / 62.5ns) on the Arduino. The +/-150ns tolerance means that you can be over two clock cycles early or late for each transition. I don't think you can expect to write the loop in C++ and have the timing work out. But I think if somebody was reasonably proficient at assembly they could write a loop to manage this. The actual work to be done per bit is just two OUT instructions at 1 cycle each. That leaves 38 cycles for managing the loop itself. That should be plenty. You could unroll the inner loop over individual bits and inline that if you wanted. That gives you something on the order of 304 clock cycles to manage your loop over the bytes of data you want to output. That's tons of time. You can use SBRC/SBRS instructions to control the falling clock timing. Those instructions are nice because the timing is identical whether the condition matches or not.

The 2801's are very easy to work with though. I've got 350 of them up on my house right now as christmas lights.  Let me know if you have any problems controlling them. I've got a hacked up version of shiftOut which is significantly faster than the stock one. You could also try the FastSPI library if you want to use SPI to drive them. The last batch I bought didn't work with FastSPI though and I didn't take the time to figure out why. I'm driving mine as four separate strands, so a single SPI line wasn't going to work for me anyway.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 2
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The fastspi library has code for the TM1809 LED driver which uses a clockless data line as well. Two clock cycles is well within the precision possible on an arduino or PIC if you disable interrupts for the duration of the write. The fastspi library simply defines two specific counts of nop instructions to insert into each loop to make the data sending work out right.
Logged

Offline Offline
Sr. Member
****
Karma: 7
Posts: 282
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

As stated several times a higher MHz processor may do the trick. Running at 80MHz a Uono32 could work and is likely less expensive than tossing the LED strips:

http://digilentinc.com/Products/Detail.cfm?NavPath=2,892,893&Prod=CHIPKIT-UNO32
Logged


Offline Offline
Full Member
***
Karma: 0
Posts: 133
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


are using this library?

https://github.com/adafruit/Adafruit-WS2801-Library
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 626
Posts: 34152
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Two clock cycles is well within the precision possible on an arduino or PIC
No it is not. Write the code and see.

Yes you can output something in 1 clock cycle, then you have to fetch the next byte, check if you have outputted all the data and loop back if not all in the next clock cycle?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry to dig up this oldish thread, but I too have a bunch of ws8211's, and I am determined to get them to work (preferably with the Pro Mini/Nano's as I have many of those too).

This thread is very puzzling as people are mostly saying that the SPI side is not possible, however, it works great with the FastSPI library.  As long as my code is in the chip I can do anything I want with the lights, fairly fast if you ask me (a 5fps adalight would work fine for me).  The problem is handling the serial port.  I'm obviously having overruns there, and get very different results at different baud rates and all.  I slowed it down to 2400baud, but it still doesn't work right.  My super-simple well-commented code is below...  the Startup Test works perfect, but Boblight (or even uploading a custom-made binary file through a terminal) is random and broken even at 2400baud upload, and all the delay(x)'s I could think of to try.

Code:
#include <FastSPI_LED.h>

//------------------------------------------------------
// Config
//------------------------------------------------------

//LED communication-pin
#define PIN 4

//Number of LEDs
#define NUM 50

//Key byte to syncronize begining of frame with BobLight (prefix)
#define KEY 0x69

//Change order of RGB below for some LED pixel brands.
struct CRGB { unsigned char r; unsigned char g; unsigned char b; };
struct CRGB *leds;


//------------------------------------------------------
// Setup - Main Code
//------------------------------------------------------
void setup()
 {
  //Baud Rate
  Serial.begin(2400);

  //FastSPI Setup (choose correct Chipset)
  FastSPI_LED.setLeds(NUM);
  FastSPI_LED.setChipset(CFastSPI_LED::SPI_TM1809);
  FastSPI_LED.setPin(PIN);
  FastSPI_LED.init();
  FastSPI_LED.start();
  leds = (struct CRGB*)FastSPI_LED.getRGBData();
  memset(leds, 0, NUM * 3);
  FastSPI_LED.show();

  //Startup Test
  for(int i=0; i<128; i++)
   {for(int j=0; j<NUM; j++)
     {leds[j].r = i;
      leds[j].g = i;
      leds[j].b = i;}
    FastSPI_LED.show();
    delay(20);}
  memset(leds, 0, NUM * 3);
  FastSPI_LED.show();
  delay(500);

  //Send "Ada" for auto port-detection by BobLight
  Serial.print("Ada\n");

  //Show colors while waiting for first serial frame
  for(int k=0; k<NUM; k++)
   {leds[k].r = 250-(5*k);
    leds[k].g = 0;
    leds[k].b = 5*k;}
  FastSPI_LED.show();


  //MainLoop
  for(;;)
   {if(Serial.available())
     {if(Serial.read()==KEY)
       {
        //Skip 2 after KEY
        if (!Serial.available()) {}
        Serial.read();
        delay(10);
        if (!Serial.available()) {}
        Serial.read();
        delay(10);

        //Now Load All Bytes
        for (int pixel=0; pixel<NUM; pixel++)
         {
          if (!Serial.available()) {}
          leds[pixel].r = Serial.read();
          delay(10);
          if (!Serial.available()) {}
          leds[pixel].b = Serial.read();
          delay(10);
          if (!Serial.available()) {}
          leds[pixel].g = Serial.read();
          delay(2);
         }
        FastSPI_LED.show();
 } } } }

//------------------------------------------------------
// End
//------------------------------------------------------

void loop()
 {
  // loop() is avoided as even that small bit of function overhead
  // has a measurable impact on this code's overall throughput.
 }


Can someone point me to some code for getting a SP interrupt working so it can fill a circular buffer that way an I can just pass the values to FastSPI?  I tried searching everywhere and tried to reverse engineer LEDstream, but I feel a bit lost.

...or is this really not possible without a faster micro?  I'd think since the LEDs work fine, it would have to be possible to pass serial bytes to them, even if I have to send, wait, send, wait one 153-byte frame at a time, at even 0.5FPS...  it has to be possible!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well I guess I proved all the nay-sayers wrong.  My 50-channels of WS2811 bulbs are now working with an Arduino Nano at 30fps under Win7 Aero by using the FastSPI library.

See pics at the bottom of the first page of this thread:  http://arduino.cc/forum/index.php/topic,122810.0.html
Logged

Show Your Work
Offline Offline
Edison Member
*
Karma: 14
Posts: 1098
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't think you can do it. If you look at the timing you have to be accurate to 100nS and there simply isn't enough time in a 16MHz processor to do that, it turns out to be about two clock cycles. Even in machine code the overhead of reading data and producing those two diffrent waveforms times is too tight.
I think you will have to have a diffrent processor, one that runs faster. Or a very fancy piece of hardware.

Why not have the Arduino write it into a RAM and then use a discrete circuit with a trigger and a precision timer to read the RAM when triggered and bitbang it out all purely using hardware?  The biggest, bestest serial to parallel shift register evah.  Sure, this is nasty overkill but at least it will prove you can make a nice little bespoke circuit.  smiley-mr-green
« Last Edit: September 21, 2012, 01:20:21 pm by JoeN » Logged

I have only come here seeking knowledge. Things they would not teach me of in college.

Humboldt, CA
Offline Offline
Full Member
***
Karma: 2
Posts: 223
Arduino BBB
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Just as a note, the MSP430G2553 (available as part of the $4.30 Launchpad bundle) can run at least 60 of these things, despite being a 16MHz part.
There's even a library for Energia (Arduino IDE ported to MSP430), here: http://forum.43oh.com/topic/2882-energia-library-ws2811driver-led-controller-class/#entry24208
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 55
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well I guess I proved all the nay-sayers wrong.  My 50-channels of WS2811 bulbs are now working with an Arduino Nano at 30fps under Win7 Aero by using the FastSPI library.

See pics at the bottom of the first page of this thread:  http://arduino.cc/forum/index.php/topic,122810.0.html

Hi,
I am trying to get the ws2811 strips working but getting few flickers/errors.
Can you please help me with timing to send 1's and 0's ?
Following timing I'm using...

http://i50.tinypic.com/eaij43.jpg

Also I'm using 50uSec delay in between two frames!
Currently sending data for 1 pixel (24 bit: 1byte R, 1byte G, 1byte B).

http://i50.tinypic.com/27y1iu1.jpg

Is there anything else to be considered to remove the flickering?

P.S. I'm not using SPI or Fast SPI
Timing for "0" = 250nS HIGH and 1uS LOW
Timing for "1" = 1uS HIGH and 250nS LOW
« Last Edit: November 18, 2012, 01:38:58 am by DirtyBits » Logged

Anaheim CA.
Offline Offline
Faraday Member
**
Karma: 47
Posts: 2892
...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The MSP link requires a log on.

Bob
Logged

--> WA7EMS <--
“The solution of every problem is another problem.” -Johann Wolfgang von Goethe
I do answer technical questions PM'd to me with whatever is in my clipboard

Offline Offline
Jr. Member
**
Karma: 0
Posts: 55
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The MSP link requires a log on.

Bob

Timing for "0" = 250nS HIGH and 1uS LOW
Timing for "1" = 1uS HIGH and 250nS LOW
Img Link;
http://i50.tinypic.com/eaij43.jpg
http://i50.tinypic.com/27y1iu1.jpg
Logged

Humboldt, CA
Offline Offline
Full Member
***
Karma: 2
Posts: 223
Arduino BBB
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The MSP link requires a log on.

Bob

Odd, it's in the Libraries section, didn't think that would take a logon.
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 626
Posts: 34152
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Well I guess I proved all the nay-sayers wrong.
No you didn't, you proved that the chip responds to signal timing outside the quoted values, that's all.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It is possible to get the exact 250nsec/1000nsec timings that are required by the WS2811 out of a 16MHz AVR, with no timing jitter anywhere.  It's just not particularly easy, you need to do it in assembler. I've written it up, along with code, at http://bleaklow.com/2012/12/02/driving_the_ws2811_at_800khz_with_a_16mhz_avr.html.  Note this code is for pixels wired up in (G,R,B) order rather than (R,G,B).

And another note: there seems to be an assumption in earlier posts on this thread that if you use the FastSPI library to drive the WS2811 you are using SPI and therefore the WS2811 is a SPI device. That's wrong - when driving the WS2811 FastSPI uses bit-banging. Oh, and the timings aren't correct, which may be the issue if it doesn't work for you - see the blog post linked to above for details.
« Last Edit: December 15, 2012, 09:04:28 am by Alan Burlison » Logged

Pages: 1 [2] 3 4   Go Up
Jump to: