Introduction: Expandable LED Cube 4x4x4 Using 8051 With Program Example

The led cube is amazing. Let me try creating one. My version of course :D (as I may not have all components listed from other’s instructables).

Step 1: The Plan and Result

I have less than 100 red led right now but will have more later so I plan to make an expandable cube, i.e. start from 4x4x4, make 8x4x4 or 16x4x4 when more led are available.

I google then got some understanding about how to make a led cube. I drafted the circuit as below. That fits my needs that I can expand to 16x4x4 or even 16x16x16.

I was too eager to solder the led. After two days, with some painful mistakes like wrong polarity, short circuits, damaged led, finally come with the successful product.


The design needs 24 (16 + 8 ) npn transistors and 4x100ohms resistors (may be another 8 for as pull up transistors for y and z).

Basically three transistors together determine the on or off of a led. When all three transistors have high signal, i.e, x=1, y=1 and z=1, the led will be turned on.

At a single moment, only one led is turn on. To show a shape like a line, a rectangle or a cube, turn on the led that link as the shape one by one, then repeat for several times. E.g. a straight line needs to link four led on one edge, switch on each led one at a time then repeat the cycle for 100 times, you will see the straight line. That is the effect of POV.

To make expandable, I split the product as three modules: 1) led matrix; 2) drivers (the transistors) to turn on the led matrix; 3) a MCU to program the sequence of led on and off.

Step 2: Re-design

Before start I found I don’t have enough transistors. Luckily I have one 4-to-16 decoder IC called 74HC154N. That fits well to replace most transistors.

The 4x4x4 led cube can be considered as 4x16 led matrix. By applying program logic, (x,y,z) can be converted as (d, z) where the d is 16 columns of led, the z is 4 layers / level of led.

The new circuit is as below. One 74HC154N replaces 20 transistors and reduces 8 control lines to 4 control lines. To expand to 4x4x8, use one more 74HC154N so you are controlling 4x32 led.

As the 74HC154N will output low as active, all 16 pins Y0 to Y15 will connect to negative lead of led. So the positive lead of led will connect to the Emitter of npn transistors.

I keep four transistors as the z axis input, then use the four A0-A3 input of 74HC154N as x and y axis input. Program logic is needed. You could the code afterwards.

The conversion formula is simple as: x + y x 4. E.g. coordinate (2,1) = 2 + 1 x 4 = 6 that is the output pin Y5 of 74HC154N.

And to turn on Y5, first convert decimal 6 (6th pin) as binary 0110. As the A3-A0 inputs are low active, the 0110 inverts to 1001. i.e. putting A0-A3 as 1001 will trigger Y5 as low and keep other Y as high.

Step 3: Module 1 the Led Matrix

This is the most difficult parts. I made several mistakes and take one whole day to finish.

Get 4x4x4 = 64 led and test them all one by one. Then bend the negative led as captured.

Solder 4 led as one set. Then solder 4 sets as one plane.

Connect the positive leads of all 4 sets level by level. E.g. level 1 of plane 1 connect to level 1 of other planes, and level 2 of plane 1 connect to level 2 of other planes.

Put the matrix on a breadboard and test to see if all led can be turned.

Step 4: Module 2 the Driver

As 74HC154N is used, this becomes simple (after some mistakes of course).

Positive lead of led will link to emitter of four transistors. Yes. Emitter of transistors. i.e. 4 outputs.

Then negative lead of led will connect to Y pins of the 74HC154N. i.e. 16 outputs. See the connectin of the back.

The E0 and E1 pins are connected to ground permanently. The A0 to A3 pins are control pins for (x,y). The four green and white wires in the middel. The base of four transistors are the control pins of z. That are the four short brown wires on right hand size. i.e. 8 inputs in total.

Step 5: Module 3 the MCU Controller

This module controls the 8 input pins of the driver base on required display logic. I used a Chinese 8 bits MCU called STC12C4052AD that is compatible with 8051.

The connection is simple. Only need to connect crystal and capacitors plus linked the P1.0 to P1.3 to the four transistors base and P1.4 to P1.7 to the four input pins of the 74HC154N.

Step 6: Final Assembly Result

Captured is the whole assembly.

Step 7: Coding Sample

Programing the 8051 compatible for led sequence is not complicate. You only need to understand the POV effect and the simple looping then you can do.

First segment is pin configuration:

#include <AT89X52.H>
//to transistors for switching on off layers
sbit px0 = P1^0;
sbit px1 = P1^1;
sbit px2 = P1^2;
sbit px3 = P1^3;
//to 74hc154n for turnning on led. low active, low output
sbit pd0 = P1^4; //decode pin 0
sbit pd1 = P1^5; //decode pin 1
sbit pd2 = P1^6; //decode pin 2
sbit pd3 = P1^7; //decode pin 3
sbit pe1 = P3^7; //enable sw. low active

Second segment is the led sequence.
First number is duration between points. Second number is no. of times repeated. A three digits represents xyz of a led. “999” ends the draw.
“zz” repeats “Z” shape 100 times. Delay 1ms between each led so you will a flashing effect.
“cube” repeats a cube 800 times but no delay between each led so you will see a static cube. No flashing.
“rain1” to “rain5” are five different frames. Each one is a static shape. Five shapes together shows a dynamic movement.

unsigned int code zz[] = {1, 100,
0, 1, 2, 3, 13, 23, 33, 0 ,111,222,333, 332,331,330, 230,130,30,
999};
unsigned int code cube[] = {0, 800,
0,1,2,3, 30,31,32,33, 330,331,332,333, 300,301,302,303, 100,200, 103,203, 133,233,
unsigned int code rain1[] = {1, 100, 3,303,33,333,999};
unsigned int code rain2[] = {1, 80, 2,302,32,332,999};
unsigned int code rain3[] = {1, 50, 1,301,31,331,999};
unsigned int code rain4[] = {1, 30, 0,300,30,330,999};
unsigned int code rain5[] = {50, 1, 110,210,220,120, 111,211,221,121, 112,212,222,122, 113,213,223,123,999};


Third segment is the basic functions.
“play” will draw a shape

//turn on/off a led at (x,y,z)
void onoff(unsigned int x, unsigned int y, unsigned int z) {
unsigned int n, d0, d1, d2, d3;
//enable z layer
px0 = px1 = px2 = px3 = 0;
if (z==0) px0 = 1 ;
if (z==1) px1 = 1 ;
if (z==2) px2 = 1 ;
if (z==3) px3 = 1 ;
//convert (x,y) to nth pin;
n = x + y * 4;
//convert decimal to binary
if (n >=8 ) { d3 = 1; n = n - 8; } else d3 = 0;
if (n >=4 ) { d2 = 1; n = n - 4; } else d2 = 0;
if (n >=2 ) { d1 = 1; n = n - 2; } else d1 = 0;
if (n >=1 ) { d0 = 1; } else d0 = 0;
pd0 = d0; pd1 = d1; pd2 = d2; pd3 = d3;
}

void delay1ms(unsigned int n) // 12Mhz, 1ms
{ int i; while (n--) { i = 600; while (i--) ; } ; }

void play(unsigned int *c) {
unsigned int i,sp, turn, x,y,z;
sp = c[0]; turn = c[1];
while (turn > 0 ) {
i = 2;
while (i < 999) {
  x = c[i] / 100;   y = (c[i] - x * 100)/ 10;   z = (c[i] - x * 100 - y * 10);
  onoff(x,y,z,1);
  delay1ms(sp);
  i ++;
  if (c[i]==999) i = 999 ;
};
turn --;
};

}

Lastly the main loop of the program. That repeatedly draws “z”, “cube” and “rain”.

void main(void)
{ unsigned int i;
while (1) {

    play(zz);
    play(cube);
  for (i = 0; i < 4; i++) {
   play(rain1); play(rain2); play(rain3); play(rain4); play(rain5);
  };
}
}

That is it. Enjoy :)