ATtiny85 RGB led rainbow fade

Hi everyone,

For a while now I have been looking for a way to run an RGB led on an ATtiny85, in an effort to make a really small rainbow fader.

It would have been a easy task, except the ATtiny only has two PWM pins, and all softPWM programs use timerone which doesn't work on ATtiny85 (or i can't get to run).

I have looked everywhere for similar projects but have not been able to find anything that suited what i wanted, So I put together some code that does the job...
(I broke the code into subs to make it easier to read)

// attiny85 RGB led rainbow fade

const int redPin = 3;  
const int grnPin = 4;  
const int bluPin = 1; 


void setup()
{
  pinMode(redPin, OUTPUT);     
  pinMode(grnPin, OUTPUT);     
  pinMode(bluPin, OUTPUT);     
}

void loop()
{
redtoyellow();
yellowtogreen();
greentocyan();
cyantoblue();
bluetomajenta();
majenatored();
}


void redtoyellow()
{
   digitalWrite(redPin, HIGH);
   digitalWrite(bluPin, LOW);

  // fade up green
  for(byte i=1; i<100; i++) {
    byte on  = i;
    byte off = 100-on;
    for( byte a=0; a<100; a++ ) {
      digitalWrite(grnPin, HIGH);
      delayMicroseconds(on);
      digitalWrite(grnPin, LOW);
      delayMicroseconds(off);
    }
  } 
}



void yellowtogreen()
{
   digitalWrite(grnPin, HIGH);
   digitalWrite(bluPin, LOW);

  // fade down red
  for(byte i=1; i<100; i++) {
    byte on  = 100-i;
    byte off = i;
    for( byte a=0; a<100; a++ ) {
      digitalWrite(redPin, HIGH);
      delayMicroseconds(on);
      digitalWrite(redPin, LOW);
      delayMicroseconds(off);
    }
  } 
}


void greentocyan()
{
   digitalWrite(grnPin, HIGH);
   digitalWrite(redPin, LOW);

  // fade up blue
  for(byte i=1; i<100; i++) {
    byte on  = i;
    byte off = 100-on;
    for( byte a=0; a<100; a++ ) {
      digitalWrite(bluPin, HIGH);
      delayMicroseconds(on);
      digitalWrite(bluPin, LOW);
      delayMicroseconds(off);
    }
  } 
}



void cyantoblue()
{
   digitalWrite(bluPin, HIGH);
   digitalWrite(redPin, LOW);

  // fade down green
  for(byte i=1; i<100; i++) {
    byte on  = 100-i;
    byte off = i;
    for( byte a=0; a<100; a++ ) {
      digitalWrite(grnPin, HIGH);
      delayMicroseconds(on);
      digitalWrite(grnPin, LOW);
      delayMicroseconds(off);
    }
  } 
}


void bluetomajenta()
{
   digitalWrite(bluPin, HIGH);
   digitalWrite(grnPin, LOW);

  // fade up red
  for(byte i=1; i<100; i++) {
    byte on  = i;
    byte off = 100-on;
    for( byte a=0; a<100; a++ ) {
      digitalWrite(redPin, HIGH);
      delayMicroseconds(on);
      digitalWrite(redPin, LOW);
      delayMicroseconds(off);
    }
  } 
}



void majenatored()
{
   digitalWrite(redPin, HIGH);
   digitalWrite(grnPin, LOW);

  // fade down blue
  for(byte i=1; i<100; i++) {
    byte on  = 100-i;
    byte off = i;
    for( byte a=0; a<100; a++ ) {
      digitalWrite(bluPin, HIGH);
      delayMicroseconds(on);
      digitalWrite(bluPin, LOW);
      delayMicroseconds(off);
    }
  } 
}

The code provides reasonable good fade and no flicker, but i am open for suggestions on improving the code.

How 'bout this? Since each of your ColorToColor() functions are basically the
same, why not generalize them like this:

void ColorToColor(byte pinColorOn, byte pinColorOff, byte pinColorRamp)
{
   digitalWrite(pinColorOn, HIGH);
   digitalWrite(pinColorOff, LOW);

  // fade up green
  for(byte i=1; i<100; i++) {
    byte on  = i;
    byte off = 100-on;
    for( byte a=0; a<100; a++ ) {
      digitalWrite(pinColorRamp, HIGH);
      delayMicroseconds(on);
      digitalWrite(pinColorRamp, LOW);
      delayMicroseconds(off);
    }
  } 
}

No sense in replicating all that code... Oh, and change the 100 to 255, OK?

It would have been a easy task, except the ATtiny only has two PWM pins

You're using the wrong core. There are three available...
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1285218245/0
http://code.google.com/p/arduino-tiny/

Makes sense, would also need code for fade down, I try not to over think something when a simple copy/paste will do.

Thanks... that a much better core than the one I was using, why didn't I find this when I was looking.

I found that trying to set colors using RBG to be a bit trick really for some purposes. What is better is HSL. So you can cycle through the color spectrum and then have separate lightness and saturation. I used this site for the code to do it. It's puedo code sort of so you will need to put the bits in there own functions probably. But it works fine. There is a slight glitch in the hue cycle but i found if you drop the saturation to about 0.09 i think it sorts it out and maybe don't quite get to 1 on the hue just very close. I have remade it to use values from 0-255 which is easer i will post the functions later if it a help.

i should read threads more. Only 2 pwm pins? not sure if this will still work. Still it might be useful for someone.

EVP:
i should read threads more

...thoroughly ( ;))...

Only 2 pwm pins?

Three...

not sure if this will still work. Still it might be useful for someone.

It is. Thank you.

Hey guys. Any idea on how to make the color fade slower. Just doubling the amount of time it takes to cycle through the colors would be nice. Thanks