Full walk through tutorial.. After the break..

4×4 RGB Charlie Cube

What is it?

Charliecube is a programmable Full Color 4x4x4 LED Cube. What makes it special is it’s the first of it kind to employ the use  of full color Led’s with out all the additional hardware such as shift registers. Using shift register IC’s both up’s the cost and complexity. Thanks to Asher Glick who developed this new method a 4x4x4 RGB LED Cube can be built using very few materials, on the cheap and my fav, the finished product is hands down Way more organized and pleasing to the eyes. So with this new method all 64 RGB Leds can be controlled with only 16 digital Pins from a single arduino.

 

The Build. SECTION: 1

In this section I’m am going to show you what you need and how to build 1 of the 16 LED Spires.

 

Materials:

  • Arduino: any type with a 328p Chip. Hopefully you already have one. If not Check EBAY A NANO Clone is about $15 free Shipping
  • 64 RGB LEDS, Diffused, Common Cathode  ( I sourced  100 of them from Ebay for about $15 free shipping.  LINK )
  • 1 Large RadioShack PC Grid Proto Board (4.5″ x 6.625″ ) $2.19
  • 40 feet of Solid Core 20 Gauge Wire (or Similar Size) for supporting the spires. “Lowes” has a nice package of 20 gauge x 175ft galvanized steel Wire for about $5-6  Wire Package Looks like This
  • 10 feet of 22 gauge wire (or Similar) for wiring the Spires together and to Arduino.
  • Optional – Paint to Color protoboard. White reflects, Black Hides Everything.
  • Optional – Large project case from Radio shack to put your Cube in and hide the unsightly.

 

Building a Spire:

Take your first 4 Leds and bend all the Leads out as shown below.

Make note of the notch so you bend ALL leds the SAME!

How To Bend LED Leads

 

 

 

 

 

 

 

Next I found it best to build a jig. This is so you can solder them all spaced evenly.

To do this I found an old package box. You can use what ever you have that is deep enough for the led leads to poke through.

I then poked four holes in a straight line using a Ruler spaced  “3.5cm=35mm” apart.

Then start from the top and placing your leds in each hole.

Note: VERY IMPORTANT! Each Led is 90 degrees clockwise from each other. :

  1.  TOP = Notch on Right
  2. Next one down = Notch on the bottom
  3. Third one down = Notch on the left
  4. Bottom = Notch on top

Below you can see a Picture of what this looks like…

Spire Jig / measurements

 

 

 

 

 

 

 

 

Now your going to need some of the 20 gauge steel wire to solder together your LED Spires.

NOTE: The biggest trick to this looking good is to get the wire as straight as possible.

The wire as you get it is wound up so when you try to straighten it ends up anything but. There are many different methods to getting it straight again. I found my way to be the quickest and cheapest with pretty damn good results. I though about just explaining how i do it but in the end who doesn’t just want to see in action RIGHT!

So here’s a video with me showing you how I do it.

 

 

Note: I cut the wire lengths to about 20cm=200mm So I have plenty extra wire hanging off the top and bottom.

Next Were going to take 4 wires  and one by one solder them to there parallel leads as shown below.

After you solder all four leads to the single piece of wire.  Rotate all your leds in your jig so it is easier to solder with the wire on top.

You can see in the picture below I have already done two sides. Try to use as little solder as possible.

NOTE: Check ONE MORE TIME all your LEDS are Rotated Correctly. Before You solder all your leads. It’s much simpler to fix a mistake here than it will be later on.

Solder support wire on Jig

 

 

 

 

 

 

 

 

 

 

Ok once you have all four side soldered.

And you have made 15 more exactly the same. You should have a grand total of 16 spires looking like THIS!

Assembled Spires

 

 

 

 

 

 

 

 

 

And now would be a good time to check all your connections. If you have AA battery or 3-5v power source you can put them on the wires in every combination  to make sure all you leds light up. When your properly satisfied or Have Tiger Blood Confidence and decide to skip checking them you can move on to trimming all the leads sticking out.

After the Trimming you should end up with  bunch of these.

Trimmed Spires

 

 

 

 

 

 

 

 

 

Time For The ProtoBoard:

So For the protoboard I know there is going to be 16 spires in all. Too have a good even spacing, that would also fit on the protoboard I Marked 10 holes between each spire future location’s center evenly on the board. After i mark it all out you can see the cut edge of the board on the right. I cut down the access board i didn’t need so the spires would be even from both edges. then drilled holes for mounting. The holes for mounting are only if you intend to put it in an enclosure. As these holes will need to be drilled to fit what ever enclosure you decide to use if you use one.

Once your marking are made you should end up with a board looking like this.

Marked ProtoBoard

 

 

 

 

 

 

 

 

 

At This Point..Take a darn Break you deserve it. I’m sure all that soldering has left you a soldering professional with hand cramps and permanent scwinty Eye Syndrome.

 

Assembly.  Section: 2

Time to Start placing the spires in there proper locations and soldering them in. Pay Attention to the rotation of the spires you want them all Facing the same direction. Below is a diag showing notch locations on the led. If by mistake you get them facing the wrong direction as long as there all facing the same direction, all that will be off are which colors turn on and can be changed in the code. How ever don’t make a mistake Why add stuff to do. lol

Assembly Diag.

Soldering Spires to ProtoBoard

 

 

 

 

 

 

 

 

Start from the back and work your way to the front. It makes it simpler to solder that way. So your not trying to solder in between everything.

 

Wiring. Section: 3

So Now It’s Time to turn the Board over and start wiring.

 

 

 

 

 

 

 

 

The Easiest way to wire the board is in four groups of four.

The First and Second groups are fairly simple.

Group one Wires 1-4

Group two wires 5-8

 

 

 

 

 

 

 

The third and fourth Groups Are a Little tricky just take your time and double and triple check before you solder.

NOTE: That the Fourth Group’s Wires are not in the Same order.

Group Three Wires 9-12

Group Four Wires 13-16

 

 

 

 

 

 

 

Arduino Pins. Section:4

Connect those 16 Wires to the arduino as lists below and then you are done.

You’ll see that we use 3 of the analog pins as Digital pins. Cool Huh!

 

Wire Number Arduino Pin AVR Pin
1        Digital 2           Port D – Pin 2 [PD2]
2         Digital 3           Port D – Pin 3 [PD3]
3         Digital 4           Port D – Pin 4 [PD4]
4         Digital 5           Port D – Pin 5 [PD5]
5         Digital 6           Port D – Pin 6 [PD6]
6         Digital 7           Port D – Pin 7 [PD7]
7         Digital 8           Port B – Pin 0 [PB0]
8         Digital 9           Port B – Pin 1 [PB1]
9         Digital 10           Port B – Pin 2 [PB2]
10         Digital 11           Port B – Pin 3 [PB3]
11         Digital 12           Port B – Pin 4 [PB4]
12         Digital 13           Port B – Pin 5 [PB5]
13 Analog 0 (Digital 14)           Port C – Pin 0 [PC0]
14 Analog 1 (Digital 15)           Port C – Pin 1 [PC1]
15 Analog 2 (Digital 16)           Port C – Pin 2 [PC2]
16 Analog 3 (Digital 17)           Port C – Pin 3 [PC3]

 The AVR pins are ment for an ATmega328 if you are using an ATmega32U4 (Arduino Leonardo) you will need to use a different pin mapping

 

 

Download Project Files/Sketch. HERE

 

 

 

 

 

Programming. Section:6

The libraries developed by Asher Glick  for the charliecube provide you with a nice set of functions that you can use to draw animations.

drawLed() drawBoxOutline() drawHollowBox() flushBuffer()
drawBox() drawBoxWalls() drawLine() clearBuffer()

=-=-==-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

drawLed()

 

This function turns on leds at a specified position. Depending on which color this function turns on different colors of the LED

Valid Permutations drawLed(color, brightness, x-pos, y-pos, z-pos);
drawLed(color,             x-pos, y-pos, z-pos);
Arguments color: what color the led should be
integer: red, blue, green, purple, yellow, teal, white, off
brightness: what brightness should the led be at
integer 0 1 2 3 4 5 6 7 8 HALF=4 FULL=8
start-x: x coordinate for the starting point
integer 0 1 2 3
start-y: y coordinate for the starting point
integer 0 1 2 3
start-z: z coordinate for the starting point
integer 0 1 2 3
Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include "cubeplex.h"
int color = red;
void setup() {
  // initilize the cube display
  initCube();
  
  // how many secconds until continuePattern is set to false
  animationMax = 10;
}
void loop() {
  randomLed();
}
void randomLed(){
  continuePattern = true;
  int animationSpeed = 100;
  while (continuePattern) {
    int xpos = random(0,4);
    int ypos = random(0,4);
    int zpos = random(0,4);
  
    drawLed(color,xpos,ypos,zpos);
    
    flushBuffer();
    clearBuffer();
    delay(animationSpeed);
  }
}

=-=-==-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

drawBox()

This function will draw a filled in box of the specified color on the cube

Valid Permutations drawBox(color, brightness, start-x, start-y, start-z, end-x, end-y, end-z);
drawBox(color,             start-x, start-y, start-z, end-x, end-y, end-z);
Arguments color: what color the led should be
integer red blue green purple yellow teal white off
brightness: what brightness should the led be at
integer 0 1 2 3 4 5 6 7 8 HALF=4 FULL=8
start-x: x coordinate for the starting point
integer 0 1 2 3
start-y: y coordinate for the starting point
integer 0 1 2 3
start-z: z coordinate for the starting point
integer 0 1 2 3
end-x: x coordinate for the ending point
integer 0 1 2 3
end-y: y coordinate for the ending point
integer 0 1 2 3
end-z: z coordinate for the ending point
integer 0 1 2 3
Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include "cubeplex.h"
void setup() {
  //initilize the cube display
  initCube();
  
  // set the number of seconds until continuePattern is set to false
  animationMax = 10;
}
void loop() {
  bigBlueBox();
  tinyGreenBox();
}
void bigBlueBox() {
  continuePattern = true;
  draw(blue,0,0,0,3,3,3);
  flushBuffer();
  clearBuffer();
  // do nothing while the pattern continues
  while(continuePattern);
}
void tinyGreenBox() {
  continuePattern = true;
  drawBox(green,FULL,1,1,1,2,2,2);
  flushBuffer();
  clearBuffer();
  // loop until the pattern is done
  while(continuePattern);
}

=-=-==-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

drawHollowBox()

This function will draw the walls, celing, and floor of a defined box

Valid Permutations drawHollowBox(color, brightness, start-x, start-y, start-z, end-x, end-y, end-z);
drawHollowBox(color,             start-x, start-y, start-z, end-x, end-y, end-z);
Arguments color: what color the led should be
integer red blue green purple yellow teal white off
brightness: what brightness should the led be at
integer 0 1 2 3 4 5 6 7 8 HALF=4 FULL=8
start-x: x coordinate for the starting point
integer 0 1 2 3
start-y: y coordinate for the starting point
integer 0 1 2 3
start-z: z coordinate for the starting point
integer 0 1 2 3
end-x: x coordinate for the ending point
integer 0 1 2 3
end-y: y coordinate for the ending point
integer 0 1 2 3
end-z: z coordinate for the ending point
integer 0 1 2 3
Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include "cubeplex.h"
int color = red;
void setup() {
  // initilize the cube display
  initCube();
  // set the number of seconds each animation should run for
  animationMax = 10;
}
void loop() {
  pulsingCube();
}
void pulsingCube() {
  continuePattern = true;
  int animationSpeed = 100;
  while (continuePattern) {
    for (int i = 0; i < 4; i++) {
      drawHollowBox(color,0,0,0,i,i,i);
      flushBuffer();
      clearBuffer();
      delay(animationSpeed);
    }
    for (int i = 0; i < 4; i++) {
      drawHollowBox(color,i,i,i,3,3,3);
      flushBuffer();
      clearBuffer();
      delay(animationSpeed);
    }
    color=nextColor(color);
  }
}

=-=-==-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

drawBoxOutline()

This function will draw edges of a defined box but none of the planes

Valid Permutations drawBoxOutline(color, brightness, start-x, start-y, start-z, end-x, end-y, end-z);
drawBoxOutline(color,             start-x, start-y, start-z, end-x, end-y, end-z);
Arguments color: what color the led should be
integer red blue green purple yellow teal white off
brightness: what brightness should the led be at
integer 0 1 2 3 4 5 6 7 8 HALF=4 FULL=8
start-x: x coordinate for the starting point
integer 0 1 2 3
start-y: y coordinate for the starting point
integer 0 1 2 3
start-z: z coordinate for the starting point
integer 0 1 2 3
end-x: x coordinate for the ending point
integer 0 1 2 3
end-y: y coordinate for the ending point
integer 0 1 2 3
end-z: z coordinate for the ending point
integer 0 1 2 3
Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include "cubeplex.h"
int color = red;
 
void setup() {
  // initilize the cube display
  initCube();
  // set the number of seconds each animation should run for
  animationMax = 10;
}
void loop() {
  pulsingCube();
}
void pulsingCube() {
  continuePattern = true;
  int animationSpeed = 100;
  while (continuePattern) {
    for (int i = 0; i < 4; i++) {
      drawBoxOutline(color,0,0,0,i,i,i);
      flushBuffer();
      clearBuffer();
      delay(animationSpeed);
    }
    for (int i = 0; i < 4; i++) {
      drawBoxOutline(color,i,i,i,3,3,3);
      flushBuffer();
      clearBuffer();
      delay(animationSpeed);
    }
    color=nextColor(color);
  }
}

=-=-==-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

drawBoxWalls()

This function will draw the virtical walls and all four sides of a defined box

Valid Permutations drawBoxWalls(color, brightness, start-x, start-y, start-z, end-x, end-y, end-z);
drawBoxWalls(color,             start-x, start-y, start-z, end-x, end-y, end-z);
Arguments color: what color the led should be
integer red blue green purple yellow teal white off
brightness: what brightness should the led be at
integer 0 1 2 3 4 5 6 7 8 HALF=4 FULL=8
start-x: x coordinate for the starting point
integer 0 1 2 3
start-y: y coordinate for the starting point
integer 0 1 2 3
start-z: z coordinate for the starting point
integer 0 1 2 3
end-x: x coordinate for the ending point
integer 0 1 2 3
end-y: y coordinate for the ending point
integer 0 1 2 3
end-z: z coordinate for the ending point
integer 0 1 2 3
Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include "cubeplex.h"
int color = red;
 
void setup() {
  // initilize the cube display
  initCube();
  // set the number of seconds each animation should run for
  animationMax = 10;
}
void loop() {
  fountian();
}
void fountian() {
  continuePattern = true;
  int animationSpeed = 100;
  while (continuePattern) {
    for (int z = 0; z <= 3; z++) {
      drawBoxWalls(color,1,1,z,2,2,z);
      flushBuffer();
      clearBuffer();
      delay(animationSpeed);
    }
    for (int z = 3; z >= 0; z--) {
      drawBoxWalls(color,0,0,z,3,3,z);
      flushBuffer();
      clearBuffer();
      delay(animationSpeed);
    }
    color=nextColor(color);
  }
}

=-=-==-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

drawLine()

This function will attempt to draw a line between the two points given. Due to the limited avalibility of pixels the best approximation is chosen for each pixel value

Valid Permutations drawLine(color, brightness, start-x, start-y, start-z, end-x, end-y, end-z);
drawLine(color,             start-x, start-y, start-z, end-x, end-y, end-z);
Arguments color: what color the led should be
integer red blue green purple yellow teal white off
brightness: what brightness should the led be at
integer 0 1 2 3 4 5 6 7 8 HALF=4 FULL=8
start-x: x coordinate for the starting point
integer 0 1 2 3
start-y: y coordinate for the starting point
integer 0 1 2 3
start-z: z coordinate for the starting point
integer 0 1 2 3
end-x: x coordinate for the ending point
integer 0 1 2 3
end-y: y coordinate for the ending point
integer 0 1 2 3
end-z: z coordinate for the ending point
integer 0 1 2 3
Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include "cubeplex.h"
int color = red;
void setup() {
  initCube;
  animationMax = 10;
}
void loop() {
  planarSpin();
}
void planarSpin() {
  continuePattern = true;
  int animationSpeed = 50;
  int spinsPerColor = 5; // a spin is actually half a revolution
  while (continuePattern) {
    int x = 0;
    int y = 0;
    for (int i = 0; i < spinsPerColor; i++) {
      for (int x = 0; x < 3; x++) {
        drawLine(color,x,0,0,3-x,3,0);
        drawLine(color,x,0,1,3-x,3,1);
        drawLine(color,x,0,2,3-x,3,2);
        drawLine(color,x,0,3,3-x,3,3);
        flushBuffer();
        clearBuffer();
        delay(animationSpeed);
      }
      for (int y = 0; y < 3; y++) {
        drawLine(color,3,y,0,0,3-y,0);
        drawLine(color,3,y,1,0,3-y,1);
        drawLine(color,3,y,2,0,3-y,2);
        drawLine(color,3,y,3,0,3-y,3);
        flushBuffer();
        clearBuffer();
        delay(animationSpeed);
      }
    }
    color = nextColor(color);
  }
}

=-=-==-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

flushBuffer()

This takes the buffer frame and sets the display memory to match, because the display memory needs to be faster it is split up into two arrays instead of just one. The display frame is actually a ciclic linked list which allows the program to just loop through and turn on the LEDs without the need to check to see if it is at the end of the loop

Valid Permutations flushBuffer();
Arguments no arguments

Example

1

=-=-==-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

clearBuffer()

This function will clear the buffer that you can write to, this will allow you to draw an eniterly new frame int othe buffer

Valid Permutations clearBuffer();
Arguments no arguments

Example

1

Download Project Files/Sketch. HERE

Note: HW test sketch must have files above already installed..

Download HW Test Sketch