ShiftBrite Shield – A color mixer for Arduino

8 07 2010

LEDs… The beauty of electronics, the soul of a project. What can I say, I love LEDs!! Each time I see a project involving RGB LEDs, several ideas come to my mind and I’ve always wondered I had a good hardware platform to mess around with them!

So, after some days surfing through datasheets, online shops and tech documents, I reached one conclusion: Controlling several High-intensity RGB LEDs IS DIFFICULT. You need to supply the correct voltage to each one of the LEDs (without using resistors: when you are dealing with a 3A current, each tiny resistor can dissipate more energy in heat that your LED does, what is not very efficient…), you need a very good heatsink and an amplifier stage to control them using your Arduino. Dealing with these handicaps can be very though, or it can be just expensive. Guess which is the option that I chose…

MegaBrite, from Macetech Industries

This tiny piece of hardware simplifies a LOT your life if you want to make some microcontroller-driven illumination project. It is composed by three high-intensity LEDs (Actually inside each one of the encapsulations there are 5 small dyes, totalling 15 x 20mA LEDs = 300mA of pure colour in each MegaBrite). But the cool thing about this component is that each MegaBrite has an Allegro A6281 chip that does all the hard work in your project if you want to light a huge strip of RGB LEDs. You can find more about ShiftBrites and MegaBrites at Macetech, but roughly they work like this: Your microcontroller passes an binary word containing the values you want for each R, G and B LED to the first MegaBrite. Then, toggling one pin you can shift this information to the next MegaBrite of your strip, and so on, setting each one of the LEDs the colour you want. Easy enough for me!!

I ordered 5 MegaBrites from the Macetech online store for 10$ each one (yes, this hobby is expensive, and more if you are a beginner in electronics like me…) and then I was ready to start the interesting thing.

Making them to work with Arduino was as easy as looking for the libraries at Macetech, and after modifying some examples, I was confident enough to start doing some maths. The problem that appears when using any RGB space (yes, the color space is an R³ space, like points in space) is that it is not human-friendly: If you want to change frome a bright blue (ie R86 G30 B229) to a darker one (R50 G14 B140) you have to change all RGB coordinates, what is not very intuitive. In order to solve this problem, some decades ago the HSV space was developed. In it, the RGB coordinates are transformed into a kind of distorted polar coordinates, where you can determine a colour by its Hue (tone), Saturation (more or less colourful) and Value (brightness). This is quiiite more human-friendly, and it is widely used in colour pickers for computer graphic programs as GIMP.

Which is the next step? Of course, creating a real-world color mixer for interfacing ShiftBrite LEDs with Arduino in an easy way!

So, as I really avoid as far as possible using the protoboard (wires messing around, false contacts, noise, fragility…), soon I was designing a PCB in Eagle (I have to say that I have installed Kicad, an open-source alternative for creating PCBs, but I’m too lazy to learn how to use it now, although sooner or later I will try to use it).

I decided to create this board without going to the electronic components shop, using only recycled components that I’ve savaged from different sources. This means that I had to create my own library for Eagle, what is really easy following the Sparkfun’s tutorial.

At the end, this is what I achieved:

· Schematic

· Board

And the Arduino code:

#define clockpin 13 // CI
#define enablepin 10 // EI
#define latchpin 9 // LI
#define datapin 11 // DI

#define NumLEDs 1

void hsv2rgb(float h, float s, float v, int &R, int &G, int &B);
void SB_SendPacket();
void WriteLEDArray();

int LEDChannels[NumLEDs][3] = {
  0};
int SB_CommandMode;
int SB_RedCommand;
int SB_GreenCommand;
int SB_BlueCommand;
float hue, sat, val;
int R, G, B;

void setup() {

  pinMode(datapin, OUTPUT);
  pinMode(latchpin, OUTPUT);
  pinMode(enablepin, OUTPUT);
  pinMode(clockpin, OUTPUT);
  SPCR = (1<<<<digitalWrite(latchpin, LOW);
  digitalWrite(enablepin, LOW);
  Serial.begin(9600);
}

void loop() {

  hue = (analogRead(0)/1024.0);
  sat = (analogRead(1)/1024.0);
  val = (1-analogRead(2)/1024.0);

  //sat = 1 - (0.58198*(exp(sat*sat)-1));    // This transformation intends to make saturation more linear, although it doesn't seem to really work

  Serial.println(sat);

  hsv2rgb(hue, sat, val, R, G, B);

  R = R*4;
  G = G*4;
  B = B*4;

  LEDChannels[0][0] = R;
  LEDChannels[0][1] = G;
  LEDChannels[0][2] = B;

  WriteLEDArray();
  //delay(100);

}

void SB_SendPacket() {

  if (SB_CommandMode == B01) {
    SB_RedCommand = 120;
    SB_GreenCommand = 100;
    SB_BlueCommand = 100;
  }

  SPDR = SB_CommandMode << 6 | SB_BlueCommand>>4;
  while(!(SPSR & (1<>6;
  while(!(SPSR & (1<>8;
  while(!(SPSR & (1<while(!(SPSR & (1<void WriteLEDArray() {

  SB_CommandMode = B00; // Write to PWM control registers
  for (int h = 0;hdelayMicroseconds(15);
  digitalWrite(latchpin,HIGH); // latch data into registers
  delayMicroseconds(15);
  digitalWrite(latchpin,LOW);

  SB_CommandMode = B01; // Write to current control registers
  for (int z = 0; z < NumLEDs; z++) SB_SendPacket();
  delayMicroseconds(15);
  digitalWrite(latchpin,HIGH); // latch data into registers
  delayMicroseconds(15);
  digitalWrite(latchpin,LOW);

}

void hsv2rgb(float H, float V, float S, int& R, int& G, int& B) {

  int var_i;
  float var_1, var_2, var_3, var_h, var_r, var_g, var_b;

  /*if ( S == 0 )                       //HSV values = 0 ÷ 1
    {
     R = V * 255;
     G = V * 255;
     B = V * 255;
     }
     */

{
  var_h = H * 6;
  if ( var_h == 6 ) var_h = 0;      //H must be < 1
  var_i = int( var_h ) ;            //Or ... var_i = floor( var_h )
  var_1 = V * ( 1 - S );
  var_2 = V * ( 1 - S * ( var_h - var_i ) );
  var_3 = V * ( 1 - S * ( 1 - ( var_h - var_i ) ) );

  if      ( var_i == 0 ) {
    var_r = V     ;
    var_g = var_3 ;
    var_b = var_1 ;
  }
  else if ( var_i == 1 ) {
    var_r = var_2 ;
    var_g = V     ;
    var_b = var_1 ;
  }
  else if ( var_i == 2 ) {
    var_r = var_1 ;
    var_g = V     ;
    var_b = var_3 ;
  }
  else if ( var_i == 3 ) {
    var_r = var_1 ;
    var_g = var_2 ;
    var_b = V     ;
  }
  else if ( var_i == 4 ) {
    var_r = var_3 ;
    var_g = var_1 ;
    var_b = V     ;
  }
  else                   {
    var_r = V     ;
    var_g = var_1 ;
    var_b = var_2 ;
  }

  R = (1-var_r) * 255;                  //RGB results = 0 ÷ 255
  G = (1-var_g) * 255;
  B = (1-var_b) * 255;
}
}

Videos soon!!!
(Here I don’t have enough 3G signal to upload them!)

LAST HOUR!!!!
I’ve been published in PCB Heaven!! Thanks very much for your attention!

Advertisement

Acciones

Información

3 respuestas

9 07 2010
Juan

Muy interesante. Yo ando trasteando con shiftbrites y arduinos también, y tarde o temprano haré algo para controlar manualmente el rgb. Puedes verlo en http://www.neuronasmuertas.com/proyectos/britable/ Por cierto, el tío de macetech ha tuiteado tú proyecto, así te he encontrado. Un saludo.

9 07 2010
vilxes91

Jaja, gracias Juan, ya decía yo que había demasiadas visitas al blog, no sabía lo del twitter!!
A ver si me animo a hacer un vídeo en condiciones y a subirlo a Youtube.
Actualizo ahora que he visto tu página:
Madre mía, un proyecto muuuy currado, que se acerca bastante a arte… Muy muy interesante, creo que sacaré bastantes ideas de él, que estoy falto de algoritmos de control de LEDs. Gracias!

9 07 2010
Juan

Pues nada, píllate el codigo – busca britable en Google code – y si le puedes sacar partido, o se te ocurre alguna mejora, pues estupendo.

Deja un comentario

Fill in your details below or click an icon to log in:

Logo de WordPress.com

You are commenting using your WordPress.com account. Log Out / Cambiar )

Twitter picture

You are commenting using your Twitter account. Log Out / Cambiar )

Facebook photo

You are commenting using your Facebook account. Log Out / Cambiar )

Connecting to %s




Seguir

Get every new post delivered to your Inbox.