Pages: [1] 2 3   Go Down
Author Topic: 112 RGB LED Coffee Table  (Read 13870 times)
0 Members and 2 Guests are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 39
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've been working on a LED coffee table , with 112 RGB led's underneath a frosted glass top.  This is accomplished by multiplexing the common cathode leds.  the red green and blue colors are on for roughly 2ms a piece, much faster than the human eye can perceive so it appears a solid color.  

The table has two atmega's in it one to control the tlc5940 chips, and one to interface with the user and the computer.  the two chips communicate via i2c.

the master board has a ftdi chip for serial comms with a computer and  connection to a control panel.

the computer program is written completely with processing.



Here is a video
Sorry for the poor quality


















Code:
// Coffee Table slave


#include "Wire.h"
const int column = 16;     // number of columns
const int row = 7;         // number of rows

const byte RedPin = 5;     // digital pin to control red color
const byte GreenPin =6;    // digital pin to control green color
const byte BluePin = 7;    // digital pin to control blue color


byte Current_Color = 'R';
int power = 16;            // allow changing the power

boolean checkreading =false;

struct led{
  byte red;
  byte green;
  byte blue;
};

// Array to hold the led colors
    
    led Box[][column] = {{{255,255,255},{0,16,16},    {255,255,255},{0,16,16},{255,255,255},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16}},
                         {{255,255,255},{0,16,16},    {255,255,255},{0,16,16},{0,16,16},    {0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16}},
                         {{255,255,255},{0,16,16},    {255,255,255},{0,16,16},{255,255,255},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16}},
                         {{255,255,255},{255,255,255},{255,255,255},{0,16,16},{255,255,255},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16}},
                         {{255,255,255},{0,16,16},    {255,255,255},{0,16,16},{255,255,255},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16}},
                         {{255,255,255},{0,16,16},    {255,255,255},{0,16,16},{255,255,255},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16}},
                         {{255,255,255},{0,16,16},    {255,255,255},{0,16,16},{255,255,255},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16},{0,16,16}}};


    
#include "tlc_config.h"
#include "Tlc5940.h"



void setup()
{
   // Setup pins
  pinMode(RedPin,OUTPUT);
  pinMode(GreenPin,OUTPUT);
  pinMode(BluePin,OUTPUT);
  digitalWrite(RedPin,LOW);
  digitalWrite(GreenPin,LOW);
  digitalWrite(BluePin,LOW);
  pinMode(2,OUTPUT);

   // setup wire
   Wire.begin(4);
   Wire.onReceive(receiveEvent); // register event


   // setup tlc5940
   Tlc.init(0);
   startXLATCallback();
   Tlc.update();
        
        
   // flash onboard led as well as cycling through the colors(debugging)
   digitalWrite(2,HIGH);
   setAll(255,0,0);
   delay(1000);
   digitalWrite(2,LOW);
   setAll(0,255,0);
   delay(1000);
   digitalWrite(2,HIGH);
   setAll(0,0,255);
   delay(1000);
   digitalWrite(2,LOW);
      
}



void loop()
{
  if(checkreading)
     savedata();
}

// save data to the led array
byte vals[column*row+2];
void savedata()
{

  
   if(vals[0] == 'R' && vals[column*row+1] == 'R')
   {
     for(int i =0; i<column*row ; i++)
     {
     Box[i/column][15-i%column].red = vals[i+1];
     }
   }
   else if(vals[0] == 'G' && vals[column*row+1] == 'G')
   {
     for(int i =0; i<column*row ; i++)
     {
     Box[i/column][15-i%column].green = vals[i+1];
     }
   }
   else if(vals[0] == 'B' && vals[column*row+1] == 'B')
   {
     for(int i =0; i<column*row ; i++)
     {
     Box[i/column][15-i%column].blue = vals[i+1];
     }
    
   }
  
checkreading = false;    
}


// load the vals buffer
void receiveEvent(int howMany)
{
   int index =0;
   checkreading=true;
   while(Wire.available())
      vals[index++]=Wire.receive();
}








// do something every 2 periods, so ~2048us
// TLC5940 multiplexing code
#define XLAT_PERIODS  2

volatile uint8_t timesCalled;

volatile void myXLATCallback()
{

  if (timesCalled != 0) timesCalled--;
  else
  {
   timesCalled = XLAT_PERIODS;
   Send_data();
   Tlc.update();
  }
  set_XLAT_interrupt(); // so this will continue to be called
}

void startXLATCallback() {
   timesCalled = XLAT_PERIODS - 1;
   tlc_onUpdateFinished = myXLATCallback;
   myXLATCallback();
}


// update the tlc5940 chip

void Send_data()
{
      if(Current_Color == 'R')
      {            
            for(int i=0; i < column*row ; i++)
            {
                  Tlc.set(i, Box[i/column][i%column].red*power);
            }
            Turn_off();
            Tlc.update();
            while(tlc_needXLAT);    
            Turn_on();
            Current_Color = 'G';
      }
      else if(Current_Color =='G')
      {
            for(int i=0; i <column*row ; i++)
            {
                  Tlc.set(i, Box[i/column][i%column].green*power);
            }
            Turn_off();
            Tlc.update();
                while(tlc_needXLAT);        
            Turn_on();
            Current_Color = 'B';  
      }
      else
      {
            for(int i=0; i < column*row ; i++)
            {
                  Tlc.set(i, Box[i/column][i%column].blue*power);
            }
            Turn_off();
            Tlc.update();      
                while(tlc_needXLAT);        
            Turn_on();
            Current_Color = 'R';      
      }
}


// turn on or off the respective anode transistor

void Turn_off()
{
      pinMode(RedPin,INPUT);
      pinMode(GreenPin,INPUT);
      pinMode(BluePin,INPUT);
      digitalWrite(RedPin,LOW);
      digitalWrite(GreenPin,LOW);
      digitalWrite(BluePin,LOW);  
        delayMicroseconds(10);

}

void Turn_on()
{
  //delayMicroseconds(75);
  switch(Current_Color){
    case 'R':
    pinMode(RedPin,OUTPUT);
    delayMicroseconds(10);
    digitalWrite(RedPin, HIGH);
    digitalWrite(GreenPin, LOW);
    digitalWrite(BluePin, LOW);
    break;
    
    case 'G':
    pinMode(GreenPin,OUTPUT);
    delayMicroseconds(10);
    digitalWrite(RedPin, LOW);
    digitalWrite(GreenPin, HIGH);
    digitalWrite(BluePin, LOW);
    break;
    
    case 'B':
    pinMode(BluePin,OUTPUT);
    delayMicroseconds(10);
    digitalWrite(RedPin, LOW);
    digitalWrite(GreenPin, LOW);
    digitalWrite(BluePin, HIGH);
    break;  
  }
}


// used for the initial debug
void setAll(byte sred, byte sgreen , byte sblue)
{
 for(int i=0 ; i< column ; i++)
 {
   for(int j=0 ; j< row ; j++)
   {
    Box[j][i].red = sred;
    Box[j][i].green = sgreen;
    Box[j][i].blue = sblue;
   }
 }
}



If you want any more information i can provide it.



Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 19
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It looks awesome! This is exactly the kind of stuff I'd like to build (my arduino is in the mail right now  :smiley)

How long did it take you to build it?
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 39
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

~1year since testing began. probably could be done in 2-3 months without school.
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 70
Slowly Developing
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wow. Very impressive, Joe.

Do you have any schematics? I'm curious as to how you've multiplexed the LEDs with the TLCs.

I'm assuming you have your manual controls and the processing sketch tied to the master board, which updates the slave? The master sends a rough equivalent of the Box[] array via I2C?
Logged


0
Offline Offline
Newbie
*
Karma: 0
Posts: 39
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

http://i50.tinypic.com/33nxapf.jpg
the line above the capacitor on the left is VCC at 5v
the line below is gnd


yea i send almost the box array, except to speed it up i only send red green or blue at a time

the slaves only job is to listen to i2c and update the tlc5940 array.  this was done to ensure minimal cpu time available

« Last Edit: February 16, 2010, 09:38:20 pm by joe912 » Logged

NYC
Offline Offline
Newbie
*
Karma: 0
Posts: 4
orly?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey Joe. First, that is awesome. Seriously well done.

Still a noob to this stuff, but I was wondering if you could talk a bit more about multiplexing the anode. I looked at your schematic but it's not fully clicking for me.
Logged

- the chuck.

0
Offline Offline
Newbie
*
Karma: 0
Posts: 39
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well they are common cathode led's so they have 3 positive leads and one negative.  You can control which color is lit by activating a separate transistor in my schematic. when the program begins the first red grayscale pwm information gets loaded onto the TLC5940.  then the red transistor pin is driven high by the atmega, while the two other transistors are driven low. after an amount of time has passed ~ 2 ms all of the transistors are shut off and the next information is uploaded to the tlc5940, this time its the green pwm info.  then after the upload has finished the green transistor is driven high.  this process cycles over and over...

hope this is helpful,  take a look at the send_data() function in my code
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm truely impressed. This is by far my favourite Arduino Project I've seen.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 39
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

here's a slightly better video with some voiceover

Logged

California. USA
Offline Offline
Full Member
***
Karma: 0
Posts: 130
my guitar wants to kill your mama
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

that table is so cool, i want one now
Logged

Chester, UK
Offline Offline
Sr. Member
****
Karma: 2
Posts: 489
Trying to return the love to none logic level MOSFETS
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That is in serious need of tetris!
Great work
Logged

If your system involves lethal voltages/life critical/flamable elements - you probably shouldn't need to ask.
The Arduino != PC.

Somewhere in Arizona
Offline Offline
God Member
*****
Karma: 0
Posts: 725
Arduino must be a drug, because I'm addicted!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

im hooked... i want to make one... i guess step one is getting all the leds... im making mine 18" by 42", with 3" by 3" squares... so i need 84 leds... where did you get yours?
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 39
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ebay

they probably not the best or brightest, but by far the cheapest.  to get brighter you could use three separate Red green and blue led's to get a better color spread and brightness.
Logged

Somewhere in Arizona
Offline Offline
God Member
*****
Karma: 0
Posts: 725
Arduino must be a drug, because I'm addicted!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

lol im going to go with cheap for my prototype... lol
Logged

Austria
Offline Offline
Sr. Member
****
Karma: 3
Posts: 260
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

wow, the build itself is already good, but the software takes it all  smiley
Logged


Pages: [1] 2 3   Go Up
Jump to: