Go Down

### Topic: RGB with two pins on ATtiny85 (Read 1 time)previous topic - next topic

#### tylernt

##### Nov 24, 2013, 04:25 amLast Edit: Nov 24, 2013, 06:15 am by tylernt Reason: 1
The ATtiny does have 3 PWM pins, but with only 5 pins total, it's easy to run short. Fortunately, you can put two LEDs on a single pin using tristate logic.

I don't think this counts as Charlieplexing, since Wikipedia says you need two I/O pins to Charlieplex two LEDs. So whatever you call it, you can save a precious pin. Can't use a common cathode or common anode tricolor though -- you need a 6-pin or 3 discrete LEDs.

Wire:
VCC -> resistor -> BLUE  -> PIN3
GND -> resistor -> GREEN -> PIN3

Code: [Select]
`//// RGB from just two pins on ATtiny85// RED LED on pin4, standard Timer1 PWM (don't want to multiplex RED because the Vf is too low and it may glow even when set to "off")// GREEN and BLUE LEDs multiplexed on pin 3 using Timer0 ISR (their cumulative Vf is > 5V)//// http://code.google.com/p/arduino-tiny/ pinouts////                  ATtiny25/45/85//                      +-\/-+//              RESET  1|    |8  VCC//   BLUE/GREEN  3/A3  2|    |7  2/A1//       RED     4/A2  3|    |6  1//                GND  4|    |5  0//                      +----+//// Wire: VCC -> resistor -> BLUE  -> PIN3//       GND -> resistor -> GREEN -> PIN3//// standard AVR macros for set bit and clear bit#define sbi(num,bitloc) (num|=(1<<bitloc))#define cbi(num,bitloc) (num&=~(1<<bitloc))// nonstandard macros for dealing with multiplexed pin 3 in a time-efficient manner#define digitalWrite3LOW  cbi(PORTB,PB3)#define digitalWrite3HIGH sbi(PORTB,PB3)#define pin3isHIGH        PORTB & 1<<PB3#define pinMode3INPUT     cbi(DDRB,PB3)#define pinMode3OUTPUT    sbi(DDRB,PB3)#define pin3isAnOUTPUT    DDRB & 1<<DDB3// provide nice human names for array index#define RED   0#define GREEN 1#define BLUE  2byte outputLED[3] = { 0, 0, 0 };// =====================================================================================================================================void RGBon(){noInterrupts();TCCR0A = (1 << WGM01); // Set Clear Timer on Compare Match (CTC) mode, clearing other bitsTCCR0B = (1 << CS00) | (1 << CS01); // clock select, clkI/O/64 from prescaler, clearing other bitsTIMSK |= (1 << OCIE0A); // Timer/Counter0 Output Compare Match A Interrupt Enable, preserving other bits so we don't break millis()OCR0A = 255;interrupts(); pinMode(4, OUTPUT);analogWrite(4, 1); // RED LED uses standard PWM}// =====================================================================================================================================ISR(TIM0_COMPA_vect){if(pin3isAnOUTPUT)  {  if(pin3isHIGH) // green -> OFF (deadtime)    {    pinMode3INPUT; // leaves pullup on    digitalWrite3LOW; // turn off pullup    OCR0A = 255 - outputLED[GREEN] - outputLED[BLUE];    }  else // blue -> green    {    digitalWrite3HIGH;    OCR0A = outputLED[GREEN];    }  }else // OFF -> blue  {  pinMode3OUTPUT; // defaults to LOW  OCR0A = outputLED[BLUE];  }}// =====================================================================================================================================// call setColor with the desired LED you wish to change, with the intensity of 0-255void setColor(const byte color, const byte value){outputLED[color] = value >> 1; // same as (value / 2), only fasterif(color == RED)  { analogWrite(4, outputLED[RED] + 1 ); }  // RED LED uses standard PWM}// =====================================================================================================================================// setting '0' values won't actually turn the LED quite all the way off; have to call this to get it completely darkvoid RGBoff(){TIMSK &= ~(1 << OCIE0A); // Timer/Counter0 Output Compare Match A Interrupt Disable, preserving other bits so we don't break millis()analogWrite(4, 0);}// =====================================================================================================================================void setup(){RGBon();}// =====================================================================================================================================void loop(){for(byte i = 0; 1; i++) // infinite demo loop  {  setColor(RED, i); // call setColor with the desired LED you wish to change, with the intensity of 0-255  setColor(BLUE, i+64);  setColor(GREEN, i+128);  delay(10);  }}`

#### macegr

#1
##### Nov 25, 2013, 09:39 am
This is a great hack to save a pin, but please note it is at the expense of about 50% brightness.
Unique RGB LED Modules and Arduino shields: http://www.macetech.com/store

#### TheKitty

#2
##### Nov 25, 2013, 06:18 pm
I think Adafruit Neopixels or similar would provide greater functionality with only one data pin used.

#### sogseal

#3
##### Feb 16, 2014, 02:10 pm
Great! even though i dont understand this fully yet, in time though ) i got a baby girl on the way so i ordered Adafruit Neopixels WG2811 and a bluetooth, maybe it will help me stopping her crying  Thanks bud

#### Paul__B

#4
##### Feb 16, 2014, 07:18 pm

i got a baby girl on the way so i ordered Adafruit Neopixels WG2811 and a bluetooth, maybe it will help me stopping her crying

I very much doubt that.

To stop (prevent) babies crying, you pick them up and nurse them.

Go Up