Go Down

Topic: 112 RGB LED Coffee Table (Read 18 times) previous topic - next topic

joe912

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
http://www.youtube.com/watch?v=lgTjJe9hcU4

















Code: [Select]

// 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.




Khao

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

How long did it take you to build it?

joe912

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

nphillips

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?

joe912

#4
Feb 17, 2010, 03:37 am Last Edit: Feb 17, 2010, 03:38 am by joe912 Reason: 1
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


Go Up