Pages: [1] 2   Go Down
Author Topic: WS2811 and ATTiny85?  (Read 4557 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi there,

I wanted to start using the WS2811 Modules to control RGB Leds
( http://www.ebay.de/itm/20-Stuck-WS2811-Platine-3-Kanal-RGB-LED-Treiber-Pixel-Controller-KSQ-PWM-/370729241262?pt=Bauteile&hash=item56512f4aae#ht_1429wt_950
Handbook: http://kt-elektronic.de/wawi11/artikeldaten/pcb-ws2811smd-rita/ws2811.pdf ))

I already used the arduino-tiny ( https://code.google.com/p/arduino-tiny/ ) library to program the ATTiny85 with an simple LED Blink Program via an Arduino Uno.

Could someone help me out with using the WS2811 module correctly with an Arduino or even an ATTiny85, i.e. how to correctly change colors with this thing or control the LEDs? That would be awesome. Thanks a lot!

And - if someone knows - is it possible to control the WS2811 via the ATTiny85 and -  at the same time, add an RFM12B (http://www.hoperf.com/rf/fsk/21.htm) Transciever to control multiple combinations of this RGB Leds via an central controller unit?

Greetings,

Nico
Logged

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 144
Posts: 5350
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi there,

I wanted to start using the WS2811 Modules to control RGB Leds

Good idea!

(I'm doing the same thing right now...)

Could someone help me out with using the WS2811 module correctly with an Arduino or even an ATTiny85, i.e. how to correctly change colors with this thing or control the LEDs? That would be awesome. Thanks a lot!

Here's a snippet of the code I'm using on an 8MHz Tiny85 (nb. it won't work at other clock frequencies - WS2811 is all about timing):

Code:
// Where the WS2811 is attached (pin B4)
#define LED_BIT (1<<4)
#define LED_DDR DDRB
#define LED_PORT PORTB
#define LED_PIN PINB
#define NOP __asm__("nop\n\t")

class WS2811 {
public:
  static void init() {
    LED_PORT &= ~LED_BIT;
    LED_DDR |= LED_BIT;
  }
};
WS2811 ws2811;


// A single LED in the string
class LED {
  byte r_,g_,b_;
  static void sendByte(byte b) {
    byte mask = 0x80;
    while (mask!=0) {
      if ((b&mask)==0) {
        // Send a '0'
        LED_PIN = LED_BIT;  // Hi (start)
        NOP;                // Hi
        LED_PIN = LED_BIT;  // Lo (250ns)
        NOP;                // Lo
        NOP;                // Lo (500ns)
        NOP;                // Lo (data bit here!)
        NOP;                // Lo (750ns)
        NOP;                // Lo (875ns)
      }
      else {
        // Send a '1'
        LED_PIN = LED_BIT;  // Hi (start)
        NOP;                // Hi
        NOP;                // Hi (250ns)
        NOP;                // Hi
        NOP;                // Hi (500ns)
        NOP;                // Hi (data bit here!)
        NOP;                // Hi (750ns)
        LED_PIN = LED_BIT;  // Lo (875ns)
      }
      mask >>= 1;           // Lo (1000ns)
    }
  }
public:
  // Set my color
  LED& setColor(byte r, byte g, byte b) {
    r_ = r;
    g_ = g;
    b_ = b;
  }
  // Send me to the LED
  void send() const {
    cli();   // Interrupts have to be off while we do this as they cause timing glitches
    sendByte(g_);
    sendByte(b_);
    sendByte(r_);
    sei();
  }
};

LED led;

void setup()
{
  ws2811.init();
}

void loop()
{
  byte b = 128;
  led.setColor(b,0,b);
  led.send();
  delay(300);
  led.setColor(0,b,0);
  led.send();
  delay(300);
}

The only thing you have to watch out for is not to delay for too long between sending of each LED. The WS2811 interprets transmission delays of 50us or more as a signal that you've finished sending (in that code it's the 'delay(300)' that sets the LED color).

8MHz is the minimum CPU speed you need. If you want 16MHz you'll have to put more NOPs in.

There's a bunch of info on the WS2811 here: https://www.insomnialighting.com/products/rgbpxws2811.html

And - if someone knows - is it possible to control the WS2811 via the ATTiny85 and -  at the same time, add an RFM12B (http://www.hoperf.com/rf/fsk/21.htm) Transciever to control multiple combinations of this RGB Leds via an central controller unit?

It's possible, yes... smiley

« Last Edit: February 17, 2013, 10:48:11 pm by fungus » Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

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

(I'm doing the same thing right now...)

Awesome! smiley
Now I don't feel that alone anymore!

Code:
// Where the WS2811 is attached (pin B4)
#define LED_BIT (1<<4)
#define LED_DDR DDRB
#define LED_PORT PORTB
#define LED_PIN PINB
#define NOP __asm__("nop\n\t")

Is the  LED_BIT (1<<4) saying that the WS2811 is attached to PIN4?
So I could change it to Port 5 or so? (If not used for i.e. GND, RESET or Power?)

The WS2811 interprets transmission delays of 50us or more as a signal that you've finished sending (in that code it's the 'delay(300)' that sets the LED color).

So if I would change this code to:
Code:
void loop()
{
  byte b = 128;
  led.setColor(0,b,b);
  led.send();
  led.setColor(b,0,b);
  led.send();
  led.setColor(b,b,0);
  led.send();
  delay(300);
}
Could I "feed" 3 WS2811, attached after each other with their own color information?
I.e. set the first to one color, the second to another and the third to the last?
( is the 128 the max in one colour? )

Thanks, I hope to get my WS2811 module soldered soon, so that I could actually get to grips with it - testing on an live system is always more helpful than kicking dead theory smiley-wink!

And - if someone knows - is it possible to control the WS2811 via the ATTiny85 and -  at the same time, add an RFM12B (http://www.hoperf.com/rf/fsk/21.htm) Transciever to control multiple combinations of this RGB Leds via an central controller unit?

It's possible, yes... smiley

Awesome, do you have any information on that as well?

I would love to make multiple of these ATTiny85, WS2811, RFM12B combination for an art project, to remote control the colour of the leds.
Any ideas? Or should I open an new topic for that...


Thanks a lot for your help already, that really should get me started as soon as I got the stuff soldered smiley!
« Last Edit: February 18, 2013, 11:21:22 am by Nico Maas » Logged

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 144
Posts: 5350
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Is the  LED_BIT (1<<4) saying that the WS2811 is attached to PIN4?

Yes.

So I could change it to Port 5 or so? (If not used for i.e. GND, RESET or Power?)

You can change it, yes, but there's no "pin 5" on a Tiny85. smiley

(Well, there is, but you can't normally use it)

If I would change this code to:
Code:
void loop()
{
  byte b = 128;
  led.setColor(0,b,b);
  led.send();
  led.setColor(b,0,b);
  led.send();
  led.setColor(b,b,0);
  led.send();
  delay(300);
}
Could I "feed" 3 WS2811, attached after each other with their own color information?

Yes.


( is the 128 the max in one colour? )

No, brightness is 0..255


And - if someone knows - is it possible to control the WS2811 via the ATTiny85 and -  at the same time, add an RFM12B (http://www.hoperf.com/rf/fsk/21.htm) Transciever to control multiple combinations of this RGB Leds via an central controller unit?

It's possible, yes... smiley

Awesome, do you have any information on that as well?
[/quote]

Nope.

But basically you can do whatever you want where the "delay(300)" is. The LEDs will look after themselves.


I'm making one of these:
http://www.instructables.com/id/IR-Remote-Controlled-Color-Changing-Cloud-Arduino/

(nb. His circuit is terrible, don't copy it if you care about your Arduino's health...)

I'm using a Tiny85 with one pin driving the LEDs, one pin for the IR remote control, one for sound effects...and I still have two pins left over for other things!

I snipped the LEDs off a light string like this one: http://www.ebay.com/itm/160907739909 . The LEDs have built-in WS2811s and they work out at about 50 cents each, which is pretty cheap when you consider the amount of work/wires they save.

Last week I found a guy who sells the WS2811 in 8-pin DIP package. I'm planning another gadget with big 12mm RGB LEDs so I'm going to use them in that. I guess I've become a WS2811 fan lately... smiley Any project where the LEDs are spread out randomly is really easy to build using them.

« Last Edit: February 18, 2013, 11:33:27 am by fungus » Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

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

I'm making one of these:
http://www.instructables.com/id/IR-Remote-Controlled-Color-Changing-Cloud-Arduino/
(nb. His circuit is terrible, don't copy it if you care about your Arduino's health...)

I'm using a Tiny85 with one pin driving the LEDs, one pin for the IR remote control, one for sound effects...and I still two pins left over for other things!

I snipped the LEDs off a light string like this one: http://www.ebay.com/itm/160907739909 . The LEDs have built-in WS2811s and they work out at about 50 cents each, which is pretty cheap when you consider the amount of work/wires they save.

Last week I found a guy who sells the WS2811 in 8-pin DIP package. I'm planning another gadget with big 12mm RGB LEDs so I'm going to use them in that. I guess I've become a WS2811 fan lately... smiley Any project where the LEDs are spread out randomly is really easy to build using them.

Wow, that really looks awesome!
Thank you very much for your answers, I really can't wait to start with this stuff... But I think I need to wait a bit..
I will report back as soon as I got to work on it smiley!
And good luck with your project, seems to me as a lot of fun and success beeing ahead of you smiley-wink!
Logged

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

Ok, I tried to wire it up - and failed terribly.


I used these controllers as said http://www.ebay.de/itm/20-Stuck-WS2811-Platine-3-Kanal-RGB-LED-Treiber-Pixel-Controller-KSQ-PWM-/350714431689?pt=Bauteile&hash=item51a83588c9&_uhb=1#ht_1366wt_950
and wired them up as following:
GND to GND,
VCC / VDD with 5V,
DI / (Pin 6) to the )Analog Input 2) / PIN 4 | 3 (as seen on the picture above).

I flashed my Arduino Uno with the ISP Programmer Image,
and flashed your snippet with the Board Type Tiny 85 @8Mhz, internal osc., BOD disabled, and the Arduino ISP
(which worked flawlessly for my Blink Test thing)

But after that, nothing happend, the LED stayed dark.
I only used one of these modules to just verify "it works" before moving further....

Could you help me out?

Thanks a lot!
Logged

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 144
Posts: 5350
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Hey, those are cool! Good price, too.

and wired them up as following:
GND to GND,
VCC / VDD with 5V,
DI / (Pin 6) to the )Analog Input 2) / PIN 4 | 3 (as seen on the picture above).

Yep.

I flashed my Arduino Uno with the ISP Programmer Image,
and flashed your snippet with the Board Type Tiny 85 @8Mhz, internal osc., BOD disabled, and the Arduino ISP
(which worked flawlessly for my Blink Test thing)

I know the code works, I just copy-pasted it from above and ran it.

The only obvious thing I can think of is you're not running at 8MHz. Did you do a 'burn bootloader'?
Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

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

I know the code works, I just copy-pasted it from above and ran it.

The only obvious thing I can think of is you're not running at 8MHz. Did you do a 'burn bootloader'?

To be truthful: No, I forgot about that, and tried it.
But sadly, the LED did not light a bit... :/..

Update: IT DID! It does work, I did had a problem with the polarity of the LED.
Yeah, that is really an dumb error - but now it does seem to work for one LED - I will try to work from that...
Thanks a lot!!
« Last Edit: February 20, 2013, 03:44:11 pm by Nico Maas » Logged

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 144
Posts: 5350
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Can you measure the voltage on pin 7 of the WS2811 on your board?

According to the datasheet that pin sets the clock speed, if it's been pulled high the data timing changes.
Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

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

Can you measure the voltage on pin 7 of the WS2811 on your board?

According to the datasheet that pin sets the clock speed, if it's been pulled high the data timing changes.


Yeah, I read that too, but - sorry, I think I really missed that out, that baby is now glowing smiley!
I think the leason learned here would be:
a) Burn the bootloader to get it to 8 MHz. Do it two times if you're unsure
b) Watch out for the polarity of your LEDs. It is quite easy in dark rooms to mess with the "thought-to-be-longest" pin (it was bend, and therefore I missed the correct one... I'm so damn stupid ~.~!)

Thank you for your time, I think it should work out from here smiley!
You were an awesome help!
Logged

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 144
Posts: 5350
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, now you need some of these... smiley

http://arduino.cc/forum/index.php/topic,148155.0.html

Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

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

thanks a lot! this saved my butt!

Adafruit's neoPixel code suggests an attiny85 running at 16.5Mhz... but it didn't work for me after a few hours of learning about boards.txt...

ws2811
Logged

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

I did have to use the Burn Bootloader under the Tools Menu for whatever reason when programming with the Arduino as ISP.
Logged

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

I was testing with 2 LEDS and found the flashing of the first LED.  I moved the cli / sei... Example..
// Where the WS2811 is attached (pin B4)
#define LED_BIT (1<<4)
#define LED_DDR DDRB
#define LED_PORT PORTB
#define LED_PIN PINB
#define NOP __asm__("nop\n\t")
int maxColorArr = 256;
int maxColorValue = 255;

class WS2811 {
public:
  static void init() {
    LED_PORT &= ~LED_BIT;
    LED_DDR |= LED_BIT;
  }
};
WS2811 ws2811;


// A single LED in the string
class LED {
  byte r_,g_,b_;
  static void sendByte(byte b) {
    byte mask = 0x80;
    while (mask!=0) {
      if ((b&mask)==0) {
        // Send a '0'
        LED_PIN = LED_BIT;  // Hi (start)
        NOP;                // Hi
        LED_PIN = LED_BIT;  // Lo (250ns)
        NOP;                // Lo
        NOP;                // Lo (500ns)
        NOP;                // Lo (data bit here!)
        NOP;                // Lo (750ns)
        NOP;                // Lo (875ns)
      }
      else {
        // Send a '1'
        LED_PIN = LED_BIT;  // Hi (start)
        NOP;                // Hi
        NOP;                // Hi (250ns)
        NOP;                // Hi
        NOP;                // Hi (500ns)
        NOP;                // Hi (data bit here!)
        NOP;                // Hi (750ns)
        LED_PIN = LED_BIT;  // Lo (875ns)
      }
      mask >>= 1;           // Lo (1000ns)
    }
  }
public:
  // Set my color
  LED& setColor(byte r, byte g, byte b) {
    r_ = r;
    g_ = g;
    b_ = b;
  }
  // Send me to the LED
  void send() const {
    sendByte(g_);
    sendByte(b_);
    sendByte(r_);
  }
};

LED led1;
LED led2;

void setup()
{
  ws2811.init();
}

void getRGBFromIndex(byte colorIndex,byte *ValueR,byte *ValueG,byte *ValueB)
{
  if (colorIndex < 43)
    *ValueR = 255;
  else
  if (colorIndex < 86)
    *ValueR = 255-(colorIndex * 6);
  else
  if (colorIndex < 171)
    *ValueR = 0;
  else
  if (colorIndex < 214)
    *ValueR = colorIndex * 6;
  else
    *ValueR = 255;

  if (colorIndex < 43)
    *ValueG = colorIndex * 6;
  else
  if (colorIndex < 129)
    *ValueG = 255;
  else
  if (colorIndex < 171)
    *ValueG = 255-(colorIndex * 6);
  else
    *ValueG = 0;

  if (colorIndex < 86)
    *ValueB = 0;
  else
  if (colorIndex < 128)
    *ValueB = colorIndex * 6;
  else
  if (colorIndex < 214)
    *ValueB = 255;
  else
    *ValueB = 255-(colorIndex * 6);
}

byte AutoColorIndex1 = 0;
byte AutoColorIndex2 = 128;
  // The current RGB color values for mode 3 fade
  static byte ValueR1;
  static byte ValueG1;
  static byte ValueB1;
  static byte ValueR2;
  static byte ValueG2;
  static byte ValueB2;

void loop()
{
 
    getRGBFromIndex(AutoColorIndex1,&ValueR1,&ValueG1,&ValueB1);
    AutoColorIndex1++;
    if (AutoColorIndex1 == maxColorArr)
      AutoColorIndex1 = 0;

    getRGBFromIndex(AutoColorIndex2,&ValueR2,&ValueG2,&ValueB2);
    AutoColorIndex2++;
    if (AutoColorIndex2 == maxColorArr)
      AutoColorIndex2 = 0;

  led1.setColor(ValueR1,ValueG1,ValueB1);
  led2.setColor(ValueR2,ValueG2,ValueB2);

        LED_PIN = 0;  // Hi (start)

    cli();   // Interrupts have to be off while we do this as they cause timing glitches
  led1.send();
  led2.send();
    sei();

  delay(100);



  /*
  byte b = 128;
  led.setColor(b,0,b);
  led.send();
  led.setColor(0,b,0);
  led.send();
  delay(500);

  led.setColor(0,b,0);
  led.send();
  led.setColor(b,0,b);
  led.send();
  delay(500);
  */
 
}
Logged

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 144
Posts: 5350
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I was testing with 2 LEDS and found the flashing of the first LED.  I moved the cli / sei... Example..

Yes. Since I wrote that I found out it's best to disable interrupts for the entire send.
Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Pages: [1] 2   Go Up
Jump to: