attiny13 RGB LED demo

Hello :slight_smile:
Below is a working code to test RGB LED with an attiny13(or vice versa);

Few notes:

  • Smeezekitty‚Äôs attiny13 core was used to make code work with Arduino IDE
  • Battery source is 2x CR2032
  • each pin of attiny13 PB0,PB1,BP2 is connected to 180ohm reistor before the RGB anodes of the RGB LED (common Cathode to ground)
  • Software based PWM is used using TIMER 0
  • Just change the value of COLOR_FUSE_DELAY to modify the color change speed
#include              "avr/interrupt.h"
#include              "inttypes.h"
#include              "avr/io.h"
#include              "util/delay.h"
  
#define                CHMAX 3          //default 3; up to 6 pins for attiny13

#define                COLOR_FUSE_DELAY 9000 

#define                RED              PORTB2
#define                GREEN            PORTB0
#define                BLUE             PORTB1

#define                LED_PORT         PORTB
#define                RGB_LED_DDR      DDRB
#define                PORTB_MASK       (1 << RED)|(1 << GREEN)|(1 << BLUE) 
#define                set(x)           |= (1<<x) 
 
#define                RED_CLEAR        (pinlevelB &= ~(1 << RED))     // map RED
#define                GREEN_CLEAR      (pinlevelB &= ~(1 << GREEN))   // map GREEN
#define                BLUE_CLEAR       (pinlevelB &= ~(1 << BLUE))    // map BLUE

unsigned char          compare[CHMAX];
volatile unsigned char compbuff[CHMAX];

int                    redValue         = 0x00;
int                    greenValue       = 0x55;
int                    blueValue        = 0xAA;
int                    redOffset        = 1;
int                    greenOffset      = 3;
int                    blueOffset       = 4;

int main() {
  init();
  while(1){

    if (redValue > 254 - 1) {
      redOffset = -1;
    }
    if (redValue < 1 + 1) {
      redOffset = 1;
    }
 
    if (greenValue > 254 - 3) {
      greenOffset = -2;
    }
    if (greenValue < 1 + 3) {
      greenOffset = 2;
    }
 
    if (blueValue > 254 - 4) {
      blueOffset = -4;
    }
    if (blueValue < 1 + 4) {
      blueOffset = 4;
    }
    
    redValue   += redOffset;
    greenValue += greenOffset;
    blueValue  += blueOffset;
 
    compbuff[0] = redValue;
    compbuff[1] = greenValue;
    compbuff[2] = blueValue;

    _delay_ms(COLOR_FUSE_DELAY);

  }//while
}//int main

void setRGB(unsigned char redValue,unsigned char greenValue, unsigned char blueValue){
    compbuff[0] = redValue;
    compbuff[1] = greenValue;
    compbuff[2] = blueValue;
}//void  
 
void init(void) {
  
  RGB_LED_DDR |= (1<<RED);            // set pin to output mode
  RGB_LED_DDR |= (1<<GREEN);          // set pin to output mode
  RGB_LED_DDR |= (1<<BLUE);           // set pin to output mode
 
  CLKPR = (1 << CLKPCE);              // enable clock prescaler update
  CLKPR = 0;                          // set clock to maximum (= crystal)

  for(int i=0,pwm = 0; i<CHMAX ; i++) {
    compare[i] = pwm;                 // set default PWM values
    compbuff[i] = pwm;                // set default PWM values
  }//for
 
  TIFR0  = (1 << TOV0);               // clear interrupt flag
  TIMSK0 = (1 << TOIE0);              // enable overflow interrupt
  TCCR0B = (1 << CS00);               // start timer, no prescale 
  sei();                              // set enable interrupt
}//init()
  
ISR (TIM0_OVF_vect) {
  static unsigned char pinlevelB=PORTB_MASK;
  static unsigned char softcount=0xFF;
 
  PORTB = pinlevelB;                  // update outputs  
  if(++softcount == 0){               // increment modulo 256 counter and update
                                      // the compare values only when counter = 0.
    compare[0] = compbuff[0];         // verbose code for speed
    compare[1] = compbuff[1];
    compare[2] = compbuff[2];
 
    pinlevelB = PORTB_MASK;           // set all port pins high
  }//if

  // clear port pin on compare match (executed on next interrupt)
    if(compare[0] == softcount) RED_CLEAR;
    if(compare[1] == softcount) GREEN_CLEAR;
    if(compare[2] == softcount) BLUE_CLEAR;

}//ISR()