ATtiny13 – controlling LED RGB | fancy light effects

This is a simple ATtiny13 project that controls LED RGB using Software PWM. In result It gives really nice and colourful light effect. In our circuit a LED cathodes are connected to PB0, PB1 and PB2 while common anode is connected to VCC. The code is on Github, click here.

Parts Required

Circuit Diagram

rgb-led

Firmware

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

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

/* LED RBG pins */
#define    LED_RED        PB0
#define    LED_GREEN    PB1
#define    LED_BLUE    PB2

/* Rainbow settings */
#define    MAX        (512)
#define    STEP        (4)

/* Fading states */
#define    REDtoYELLOW    (0)
#define    YELLOWtoGREEN    (1)
#define    GREENtoCYAN    (2)
#define    CYANtoBLUE    (3)
#define    BLUEtoVIOLET    (4)
#define    VIOLETtoRED    (5)

/* Global variables */
uint16_t red = MAX;
uint16_t green = 0;
uint16_t blue = 0;
uint16_t state = 0;

void
rainbow(int n)
{

    switch (state) {
    case REDtoYELLOW: green += n; break;
    case YELLOWtoGREEN: red -= n; break;
    case GREENtoCYAN: blue += n; break;
    case CYANtoBLUE: green -= n; break;
    case BLUEtoVIOLET: red += n; break;
    case VIOLETtoRED: blue -= n; break;
    default: break;
    }

    if (red >= MAX || green >= MAX || blue >= MAX || red <= 0 || green <= 0 || blue <= 0) {
        state = (state + 1) % 6; // Finished fading a color so move on to the next
    }
}


int
main(void)
{
    uint16_t i = 0;

    /* --- setup --- */
    
    DDRB = 0b00000111;
    PORTB = 0b00000111;

    /* --- loop --- */

        while (1) {

        /* Rainbow algorithm */

        if (i < red) {
            PORTB &= ~(1 << LED_RED);
        } else {
             PORTB |= 1 << LED_RED;
        }

        if (i < green) {
            PORTB &= ~(1 << LED_GREEN);
        } else {
             PORTB |= 1 << LED_GREEN;
        }

        if (i < blue) {
            PORTB &= ~(1 << LED_BLUE);
        } else {
             PORTB |= 1 << LED_BLUE;
        }

        if (i >= MAX) {
            rainbow(STEP);
            i = 0;
        }

        i++;
    }

    return (0);
}

19 thoughts on “ATtiny13 – controlling LED RGB | fancy light effects

  1. Łukasz ,
    I like your code! So straight! Good job! I made a Rainbow for my 6 year old daughter out of it, she drawed the picture and in the center of the rainbow there ist the RGB LED.
    Greetings
    Josi

  2. Hi
    Could you explain this:
    state = (state + 1) % 6;
    Because statement is true every six states so how does it prevent compiler to go above values which you defined in /*fading states*/?

  3. Well I tried it anyway….connecting the a common cathode RGB LED (instead of a common anode RGB LED). Works fine as well!

  4. Hi there, been a while!

    Am revisiting this wonderful project of yours. However this time I got a lot of common cathode RGB LEDs given by a friend.
    What do I need to edit to make your code adaptable to common cathode RGB LEDs?
    Hope to receive from you soon

  5. Hi, really want to try this project. I see 2 includes at the top of your code – where are they from? Other code snippets? And AVRDUDESS is wanting fuse settings. Any advice on these and clock settings?

  6. Can it changed to be a random cycle of random colours? I’ve tried modifying but not with much success. Thanks for all of your work though – I’ve switched to the atiiny13 and learned a lot through your code – keep it up!

    • It require redesign of the algorithm, probably. What do you mean by random colours and what light effect you would like to get ?

      Thanks for visiting my website. I’m glad you can find useful info here. Due to busy days at work I have not much time for creating news posts but I have several ATtiny13 projects to go. Hope to publish it soon!

      • Hi Łukasz. I am trying to get a smooth random transition of colours – so that the colour varies randomly in the amount of time it is “on” and also a random intensity. So far I have made this ball (https://goo.gl/ouLpd9) with this code (https://goo.gl/BskbM8) which results in this video (https://goo.gl/wGNpkW).

        I’m happy so far with the result except:
        1. It’s not very smooth (colours jump a bit – which is not such a big problem)
        2. I’d like to have less cpu time (less intense calculations)
        3. I want to lower the clock speed for improved battery life (ideally 1.2MHz).

        That’s the plan! Any help/hints would be really useful.

  7. Hello. Thanks for the great tutorial. Tried replicating this and it works! However I’ve been out of my wits trying to modify the rate of change between colors. Tried changing osc. freq, putting delays on the loop, to no avail. Hope you can point me to the right direction…. Thanks again

      • Hi, thanks for your advise. Tried setting #define STEP (1) to 2 (or even 4), it made the rate of change faster. I wanted the rate of change to get slower. Sorry for not pointing it out in my original post. Setting #define STEP to 0.5 was not good either… (actually it was bad, no rate of change). Maybe there is another way…perhaps? Thanks again!

        • Hi, to make a rate of change faster or slower change the STEP or MAX value:

          • faster – increase STEP value, i.e. 1, 2, 4..
          • slower – increase MAX value, i.e. 512, 1024, 4096..

          Have a good prototyping!

  8. Handsomely! You can make a compilation – hex file? And, ideally, it would be desirable option program for overall cathode.

    • Hi! I really prefer to not share a hex files on a blog posts but I can send it via email if you want. Good hint. Next version of this project could handle two types of LED RBG (w/ common cathode and /w common anode). Thanks!

Leave a Comment