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

20 thoughts on “ATtiny13 – controlling LEDs WS2811/WS2812

  1. Hi
    I’v problem to with cRGB in main.c
    i’m using your program with ATtiny13

    c:\WinAVR-20100110\t13_ws2812>make
    MAKE Version 5.2 Copyright (c) 1987, 1998 Inprise Corp.
    avr-gcc -std=c99 -Wall -g -Os -mmcu=attiny13 -DF_CPU=9600000 -I. -o main.o main.c light_ws2812.cpp
    main.c:15: error: initializer element is not constant
    main.c: In function ‘setpixel’:
    main.c:118: warning: implicit declaration of function ‘ws2812_setleds’
    cc1plus.exe: warning: command line option “-std=c99” is valid for C/ObjC but not for C++

    ** error 1 ** deleting all

    c:\WinAVR-20100110\t13_ws2812>

  2. I just can’t make any of the Arduino examples fit into ATTiny13
    I’m using the arduino IDE to program the Tiny13

  3. Hello Lukash, I really liked your project of the “Rainbow on several LEDs” luminaire, I really want to repeat it, but I am very weak in electronics, can I get a circuit for two ws2812 LEDs and firmware * .hex? do i need to flash the EEPROM? I will be glad to hear from you.

  4. Hi!
    Which IDE have you used to make this project? I’m planning to use WinAVR.As I’ve very little knowledge of programming AVR.I need your suggestion.I’m using Windows 10.

  5. hello , i want to know what is the limit of ws2812 led on a strip for the library, i currently have 144 led strip
    and only 17 light up , i use this example 035_rainbow_on_several_leds_ws2812

    i tried 20 doesnt work , only 17
    this is what i edited in the main.c
    define PIXEL_NUM (144)

    thank you

    • Hi Steeve, if you want to control the LEDs separately then the 64B of RAM is your limit here.
      /L

    • 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.

  6. 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

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

  8. 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