please help with WS2811 led IC

Ah, I missed that part ... Hrm, maybe the newer AT32UC3 MCUs?

I experianced it a lot like you said, using one wire, without the clock.
it just doesn't work. it could be the clock speed as I tried different pauses.
any other idea for Arduino implementation with this 2811 ?
can you send me simple sample code, based on the HIGH/LOW needed, maybe I do something wrong as I'm not expert.

I knew I shouldn't trust the guy selling me 2811 saying it's same as 2801, now I have 600 useless leds...

Thanks for your help

it just doesn't work.

Yes that is what I said.
The signals it requires are too fast to do with an arduino, at least not in a way I can think of.
It requires signals with a resolution of 100nS, that is an accuracy of 10MHz, as the Arduino has a clock of only 16MHz then you can't do it.
The best I could think of is if you made some sort of shift register / counter arrangement with a 10MHz clock and some handshaking inputs. Even then you would have to run the whole thing from machine code with the interrupts off.
Another point, there is a line on that chip that puts it into double speed mode. If that is set on your strip then you are in even more trouble.

Negative feedback is probably your only course of action.

ha ha, he was fine, very good service, even sent me the Datasheet before.
I just trusted him too much... my fault.

how about using my computer with the usb or something like that ?
I know VB programming if it can help.

Dror

No that won't help, you need to generate two signals, one is high for 0.5uS and low for 2uS and the other is high for 1.2uS and low for 1.3uS. These represent your zeros and ones.
Then you need to stream them out in a package of 24 bits per LED in your strip, that is not so much of problem.

You can't generate signals of that sort without either a fast processor that is not wrapped up in an operating system or some external hardware like a fist full of logic gates or better still a small FPGA. This is probably what is used on the controllers they sell for this product.

I will contact supplier and get 2801. it will be much easier.
after your answer, i did an experiment with some direct port coding, it seems to have some resaults.
something like:
PORTD = B00000100;
for (int i = 0 ; i < t ; i++ ) {
asm("nop\n\t");
}
PORTD = B00000000;
where t is the pause cycles, so far 0 is the best break.
what do you think ? good direction ?

The problem is that at 16MHz each clock pulse of the mico takes 62.5nS and you are trying to make a signal that has a resolution of 100nS. So you have to do the whole thing in machine code, that includes the for / next bit. You will notice also that 62.5nS is not a multiple of 100nS so it is not going to be a precise signal. If you had a 20MHz processor then things divide a bit better allowing you two clock cycles per resolution. This is still not going to be easy to code but you might stand more of a fighting chance.

Not all machine code instructions take one clock cycle many take more so I don't see how you have the time to generate this sort of signal. You might be better off trying this with a propeller chip in machine code.

Since some of the Atmel chips claim 'up to 20MHz', what if he builds a standalone unit with a 20MHz crystal?

Since some of the Atmel chips claim

No it is all the chips. Yes you could do that, I have built a 644 system to run my reprap, but it is only 20MHz so it is not a great advantage. A propeller on the other hand can run up to 80MHz.

as I said I'm not a pro but let me see if I get it right:
the most important thing is not the time of sending high and low, it can be slower and have few cycles
AS LONG AS you don't trigger the Return commend! but to trigger this, you need above 50 microsecends break.
so, all the IF, LOOP ect will not take that long and not trigger the return as long as you keep sending HIGH/LOW data,
I can trigger high low fast enough with the PORTD command and also have a tolerance of ±150ns for each bit HIGH/LOW.
am I right with this direction?

Grumpy_Mike:
No it is all the chips. Yes you could do that, I have built a 644 system to run my reprap, but it is only 20MHz so it is not a great advantage. A propeller on the other hand can run up to 80MHz.

Then grab one of the new UC3 Atmels ... 66MHz. Or their ARM series ...

Is there support yet for the UC3 series, for Arduino that is. Anyone know if cores have been developed yet?

Just to sum things up here for future searches:
you were right, even with lots of tries, my way may work with 1-5 leds, but as soon as I go to 20-50, it just doesn't.
I get a lot of inconsistency.
I gave it up, and 600 leds went down the drain...
I bought new 100 leds with 2801 today. hope this should work smoothly.
Thank you all for your great help. you saved me a lot of time on keep tring forever to get the 2811 to work.

Thanks

:slight_smile:

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.

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.

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:

are using this library?

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?

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.

#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!

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

Grumpy_Mike:
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. :grin: