4x4x4 LED Matrix Cube

MSP430 Lunchpad 4X4X4 LED matrix Cube

Complete layout of my setup for this project, note the photo's are high resolution.

You can download and zoom to look how they are soldered together.

project layout

Completed Matrix solders to round breadboard with solder pads from Radio Shack.

Board with holes I used to to align the LED's per layer.

LED Matric with drilled board

Photo of the LED's in the drilled holes of the board.

Can zoom in to see more detail.

How I used the drilled board to align

Construction was done by layer, the cathode lead was bent over 90 degrees just above the LED's and the Anode is left standing up.

LED's place in holes to hold their position while soldering.

Then a wire was soldered across the row of cathodes for electrical connection and for mechanical support of the structure.

The cathode leads that where bent are used to connect to the next row of LED's, then repeated until the rows are completed.

Once I made the four rows, I attached the Anodes in parallel down from the top to bottom. The Anode lead is used to support the structure and distance between rows.

Then the Row's Cathode grid is connected by a single wire going down from each row to the breadboard.

I used a 2N3904 NPN transistor to drive each row.

Schematic in Eagle and PDF format download from bottom of page.

MSP430 code for linux gcc

Note: reused code from other projects, needs to be cleaned up. Some of the routines could be clean out of the code.

//  MSP430G2231  4X4X4 Matrix Cube code
// uses three 74hc595 shift registers
#include  <msp430x20x2.h>
#include <io.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
void Initializeports(void);
static void __inline__delay(register unsigned int n);
int binary2bcd16( unsigned char *bcd, int t );  // 16bit
int display_led(int t, int display);
void display_refresh( void );
// Time function varibles
volatile unsigned char days = 0, hours = 0, minutes = 0, seconds = 0, e_hours = 0, e_minutes = 0, e_seconds = 0;
volatile unsigned int milliseconds = 0, milliseconds_t = 0;
// Display buffer/control
volatile int display_buffer[8];
volatile int display_ctl[8];
volatile int display_blink = 0;
volatile int display_blink_rate;
volatile int display_position;
// Switch, mode control
char d_mode = 0, e_mode = 0, d_mode_digit = 0, switch1, switch2;
unsigned int switch1_dt, switch2_dt;
char scroll[48] = {"MSP430 Launchpad....--->Hello Yuri...Alex<--...."};
void main(void)
{
  int i, t, l;
  unsigned char  digit[5], alt_digit = 0;
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
//1Mhz
  BCSCTL1 = CALBC1_1MHZ;                    // Set range
  DCOCTL = CALDCO_1MHZ;                     // Set DCO step + modulation */
 
  CCTL0 = CCIE;                             // CCR0 interrupt enabled
  CCR0 = 1000;
  TACTL = TASSEL_2 + MC_2;                  // SMCLK, contmode
  
  Initializeports();
 
 _EINT();
 
  /* Main Application Loop */
  while(1)
  {
 display_buffer[0] = 0x0000;
 display_buffer[1] = 0xffff;
 display_buffer[2] = 0xffff;
 display_buffer[3] = 0xffff;
 for(t=0; t<80; t++)
   {
 l = display_buffer[3];
 display_buffer[3] = display_buffer[2];
 display_buffer[2] = display_buffer[1];      
 display_buffer[1] = display_buffer[0];
 display_buffer[0] = l;
for(i=0;i<600;i++) __inline__delay(25);
}
  
for(t=0; t<20; t++)
    {
 display_buffer[0] = 0x0000;
 display_buffer[1] = 0x0000;
 display_buffer[2] = 0x0000;
 display_buffer[3] = 0x0000;
 for(i=0;i<1200;i++) __inline__delay(100);          
 display_buffer[0] = 0xffff;
 display_buffer[1] = 0x0000;
 display_buffer[2] = 0x0000;
 display_buffer[3] = 0x0000;
  for(i=0;i<1200;i++) __inline__delay(100);
 display_buffer[0] = 0xffff;
 display_buffer[1] = 0xffff;
 display_buffer[2] = 0x0000;
 display_buffer[3] = 0x0000;
 for(i=0;i<1200;i++) __inline__delay(100);
 display_buffer[0] = 0xffff;
 display_buffer[1] = 0xffff;
 display_buffer[2] = 0xffff;
 display_buffer[3] = 0x0000;
 for(i=0;i<1200;i++) __inline__delay(100);
 display_buffer[0] = 0xffff;
 display_buffer[1] = 0xffff;
 display_buffer[2] = 0xffff;
 display_buffer[3] = 0xffff;
 for(i=0;i<1200;i++) __inline__delay(100);
   }  
  
  
 for(l=0;l<20;l++)
   {
 
   display_buffer[t] = 0x000f;
 for(i=0;i<4;i++)
    {
 display_buffer[0] = (display_buffer[0]<<4) | 0x00f;
 display_buffer[1] = display_buffer[0];
 display_buffer[2] = display_buffer[0];
 display_buffer[3] = display_buffer[0];
    __inline__delay(20000);
    }
 
    for(t=0;t<4;t++)
   {
    for(i=0;i<17;i++)
    {
 display_buffer[t] = (display_buffer[t]<<1) & 0xfff7;
    __inline__delay(5000);
    }
   
   }
}
  }
}
int binary2bcd16( unsigned char *bcd, int t )  // 16bit to BCD conversion
{
int i;
while( i < 5)
 {
 bcd[i] = 0;
 i++;
}
     if ( t > 9999 ) bcd[4] = t / 10000;
     if ( t > 999  ) bcd[3] = t  / 1000 - bcd[4] * 10;
     if ( t > 99 ) bcd[2] = t / 100 - (bcd[3] * 10 + bcd[4] * 100);
     if ( t > 9 ) bcd[1] = t / 10 - (bcd[2] * 10 + bcd[3] * 100 + bcd[4] * 1000);
     bcd[0] = t - (bcd[1] * 10 + bcd[2] * 100 + bcd[3] * 1000 + bcd[4] * 10000);     
 
}
// Display
void display_refresh( void )
{
int d;
if ( (display_ctl[display_position] == 0x01) && (display_blink == 0x01))
    {
   d = 16;
   }else{
    d = display_buffer[display_position];
   }
display_led( d, display_position);
display_position++;
if (display_position > 3) display_position = 0;
}
// Serial out of LED data to 74HC595
int display_led(int t, int display)
{
int j, i, mask;
mask = (0x1000<<display) & 0xff00;
j = t;
P1OUT &= ~BIT2;
for(i=0; i < 4; i++)
   {   
   P1OUT &= ~BIT1;
   if  (mask & 0x8000)
      {
      P1OUT |= BIT0;
      }else{
      P1OUT &= ~BIT0;
      }
P1OUT |= BIT1;
   mask = mask<<1;
   }
for(i=0; i < 16; i++)
   {   
   P1OUT &= ~BIT1;
   if  (j & 0x8000)
      {
      P1OUT |= BIT0;
      }else{
      P1OUT &= ~BIT0;
      }
P1OUT |= BIT1;
   j = j<<1;
   }
P1OUT |= BIT2;
}
// setup ports
void Initializeports(void)
{
int i = 0;
P1DIR |= 0x07;    
P1SEL = 0x00;
P1OUT = 0x18;                             // P1.4 set, else reset
P1REN |= 0x18;
while( i < 8 )
  {
  display_buffer[i] = 0;
  display_ctl[i] = 0;
  i++;
  }
}   
   
// Delay Routine from mspgcc help file
static void __inline__delay(register unsigned int n)
{
  __asm__ __volatile__ (
  "1: \n"
  " dec %[n] \n"
  " jne 1b \n"
        : [n] "+r"(n));
}
// Time keeping routine
interrupt(TIMERA0_VECTOR) Timer_A (void)
{
milliseconds++;
milliseconds_t++;
if (milliseconds > 999)
   {
   seconds++;
   milliseconds = 0;
   }
if (milliseconds_t > 59999)
   {
   milliseconds_t = 0;
   }
if ( 0x10 & ~P1IN)
   {
   switch1_dt++;
  }else{
  switch1_dt = 0;
  }
    
if ( 0x08 & ~P1IN)
   {
   switch2_dt++;
  }else{
  switch2_dt = 0;
  }
if (seconds > 59)
   {
   minutes++;
   seconds = 0;
   }   
if (minutes > 59 )
   {
    hours++;
    minutes = 0;
   }
if (hours > 23)
    {
    hours = 0;
    days++;
    }
  
display_blink_rate++; 
if  (display_blink_rate > 250)  // LED Blink rate
    {
    display_blink = (~display_blink) & 0x01;  
    display_blink_rate = 0;
    }
display_refresh( );
CCR0 += 999;
}