ATtiny13 – controlling LEDs WS2811/WS2812

There was a time when controlling RGB LEDs was not always an easy task. I this article I would like to show how to make it without difficulty using one ATtiny13 and LEDs based on WS2811/WS2811 driver.

The addressable LEDs are using protocol similiar to OneWire (very time-depended protocol) and can be connected together to create a strip of LEDs. The brightness of each LED color can be adjusted using pulse-width modulation to one of 256 different levels. That means there are 16,777,216 (2563) possible combinations of colors. We can produce any color from white (all colors on) to pseudo-black (all colors off).

There are a few existing libraries that can help us to do that on ATtiny13 – i.e. light_ws2812 (tested with v2.4) or pololu-led-strip-avr. In my projects I decided to use light_ws2812 because it occured to be more stable and predictible for this small chip. Due to ATtiny13 limitations we can’t controll huge number of addressable LEDs but it’s far enough to manage up to eight LEDs. I’ve created several demo examples which are presented bellow. Have fun!

Parts List

Circuit Diagram

Examples

Classic Rainbow

Software for “Rainbow on single LED”

This code is written in C and can be compiled using the avr-gcc. More details on how compile this project is here. Complete code is on GitHub.

#include <avr/io.h>
#include <util/delay.h>
#include "light_ws2812.h"

struct pixel {
	uint8_t g;
	uint8_t r;
	uint8_t b;
};

int
main(void)
{
	struct pixel p = {255, 0, 0};

	/* loop */
	while (1) {
		if (p.r > 0 && p.b == 0) {
			p.r--;
			p.g++;
		}
		if (p.g > 0 && p.r == 0) {
			p.g--;
			p.b++;
		}
		if (p.b > 0 && p.g == 0) {
			p.r++;
			p.b--;
		}
		ws2812_setleds((struct cRGB *)&p, 1);
		_delay_ms(10);
	}
}

Software for “Rainbow on several LEDs”

This code is written in C and can be compiled using the avr-gcc. More details on how compile this project is here. Complete code is on GitHub.

#include <avr/io.h>
#include <util/delay.h>
#include "light_ws2812.h"

#define	PIXEL_NUM	(7)

struct pixel {
	uint8_t g;
	uint8_t r;
	uint8_t b;
} pixels[PIXEL_NUM];

int
main(void)
{
	uint8_t i;
	struct pixel p = {255, 0, 0};

	/* loop */
	while (1) {
		if (p.r > 0 && p.b == 0) {
			p.r--;
			p.g++;
		}
		if (p.g > 0 && p.r == 0) {
			p.g--;
			p.b++;
		}
		if (p.b > 0 && p.g == 0) {
			p.r++;
			p.b--;
		}
		for (i = 0; i < PIXEL_NUM; ++i) {
			pixels[i] = p;
		}
		ws2812_setleds((struct cRGB *)pixels, PIXEL_NUM);
		_delay_ms(10);
	}
}

Circular LED chaser

This code is written in C and can be compiled using the avr-gcc. More details on how compile this project is here. Complete code is on GitHub.

#include <avr/io.h>
#include <util/delay.h>
#include "light_ws2812.h"

#define	PIXEL_NUM	(8)
#define	DELAY		(60)

struct pixel {
	uint8_t g;
	uint8_t r;
	uint8_t b;
} pixels[PIXEL_NUM];

static void setpixel(uint8_t id, struct pixel *p);

int
main(void)
{
	uint8_t i, k = 0, r = 255, g = 0, b = 0;
	struct pixel p = {0, 0, 0};

	/* loop */
	while (1) {

		/* set the color */
		p = (struct pixel){g, r, b};
		for (i = k; i < (PIXEL_NUM + k); ++i) {
			setpixel(i % PIXEL_NUM, &p);
			_delay_ms(DELAY);
		}

		/* clear the color */
		p = (struct pixel){0, 0, 0};
		for (i = k; i < (PIXEL_NUM + k); ++i) {
                        setpixel(i % PIXEL_NUM, &p);
			_delay_ms(DELAY);
                }

		/* choose next color */
		if (r == 255) {
			g = 255;
			r = 0;
		} else if (g == 255) {
			g = 0;
			b = 255;
		} else { // b == 255
			b = 0;
			r = 255;
		}

		/* set pixel shift */
		k = ++k % PIXEL_NUM;
	}
}

void
setpixel(uint8_t id, struct pixel *p)
{

	pixels[id] = *p;
	ws2812_setleds((struct cRGB *)pixels, PIXEL_NUM);
}

References

9 thoughts on “ATtiny13 – controlling LEDs WS2811/WS2812

    • If the fuse bits are set correctly then it should go fine. You can try with simple blinky program with 500ms delay and see whether it’s falshing once per second or not. It will prove that fuse bits and F_CPU=9.6MHz are ok.

  1. Yes of course. I also tried 4.8 (<= 1.2 I see an error message) Also, in the file ws2812_config I put #define ws2812_resettime 50

  2. Hi, Friend! I’m try to use your library (example “034_rainbow_on_single_led_ws2812”) with my attiny13a and have problem. My ws2812 led always white light. What is problem? PB0->DI, 5V power is common to tiny and led. Thanks!

  3. 1 this library does not work at all
    2 why do you define pixel struct while there is already a cRGB struct available ?

    • Ad.1 This library works well on ATtiny13. It has been verified on several projects. What exactly the problem is?
      Ad.2 This trick helps to redefine color field names for other LED drivers (RGB, GRB) and can be removed if not needed.

Leave a Comment