What is it?

Charliecube is a 4x4x4 tri-color LED Cube designed and created by Asher Glick and Kevin Baker. But what makes it special? Other cubes use shift registers, decade counters, or other components to control all the LEDs and can cost upwards of $150. The charliecube can be run using only 16 digital pins with no extra components and costs $30 plus an arduino.

How is it built?

This section will cover two things
First: Assembling a Spire one of the 16 columns of the cube
Second: Putting it all together to build the whole Cube!

Parts List

  • 64 RGB Leds, diffused, ours were common cathode $0.311 each
  • 1 Large Radioshack PC Grid Proto Board (4.5” x 6.625”) $2.95
  • 40 feet of solid core 20 gauge wire (or similar size) for supporting the spires
  • 10 feet of stranded 22 gauge wire (or similar size) for connecting spires together
  • We like to use old floppy cables we have lying around. One is enough for this.
  • Optional - paint to color the proto board differently. White reflects nicely, and black hides everything.
  • Assembling a Spire

    Take four LEDs and bend all the leads out.
    be sure to do this the same way for each LED so it is easier to put together later
    In each spire the LEDs will all be rotated 90° from each other (or π/2 rad for you who do math)
    So keep track of which way the leds are rotated!
    If you have lost track of which the rotations, each led has a notch on the side of the package wich you can use
    Solder wires to each lead of the LED
    If you accadentaly solder two LEDs in the same orintation it may glitch out other parts of the cube when attempting to display
    After soldering the spire together you can cut the prodruding leads off.
    make sure that all the leds turn on before you cut the extra leads, if you soldered it wrong then it will be harder to correct later.

    Building the whole cube!

    put one of the spires on to the cube and solder it in.
    Remember the direction that the spire is facing.
    Each spire has a 3x3 footprint where each leg is 1 hole away from the adjacent ones.
    Then solder the other spires on in the same direction.
    if you dont solder them all in the same direction that is ok and can be fixed in the software.
    each spire has 9 holes in between them on our cube.
    Flip the board over to attach the wires. The easiest way to wire the board is in four groups of four
    The first and the second groups are fairly simple.
    The third group is kinda tricky and the fourth group is the hardest in my oppinion.
    Connect those 16 wires to any pins on the arduino, and then you are done.
    Ours uses digital pins 2 - 13 and analog pins 0-3.

    Wire NumberArduino PinAVR 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]

    How is it programmed?

    The libraries developed 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
                  #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
                  #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
                  #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
                  #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
                  #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
                  #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

    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

    Downloads and Links