Need Help Making an RGB LED Rubik's Cube

Hey Everyone, first time posting here!

So the title says it all. I'm in a introductory electronics course and desperately need some help with my final project. We are allowed to use any resources out there, so I'm coming to you all!

Our group is going to build a 3x3 LED cube equipped with 12 buttons to simulate the real deal. The rub is that besides from a two day Arudino workshop, I have no coding experience whatsoever. Here's where I am so far.

I know that we'll need individual control over 54 RGB LED's, which means 162 ports. In addition, we'll need 12 buttons for each possible rotation, so we're looking at ~174 ports in general. For the multiplexing, I will be using ~25 STP16C596 shift registers. I realize there are better ones out there, but this is what we're going with.

At this point, my biggest struggle is coding for this many shift registers. I have a good idea of what I need to do, but don't know how to accomplish it. To get started I've been studying the example code that came with my Arduino. It uses the shift register I am planning to use, which is basically why I chose it. I've put the code at the bottom without all of the comments.

I really like the shiftWrite function they defined, but don't know how to extend it to multiple shift registers. The function basically let's you control any port on one shift register using a function analogous to digitalWrite on the arduino.

Provided I CAN individually write to whatever port on whatever shift register I want, my plan was this:

  1. Create one variable for each port on each shift register, and one variable for the status of each port that will be equal to either one or zero, (on or off).

  2. Properly assign all of the variable so that the Cube will appear solved on start-up. This will require keeping track of which variables belong to which LED.

  3. Write out 12 functions to be executed with push buttons. Each function will effectively swap the variables associated certain ports in order to properly change the LED's (I have written exactly what needs to be swapped for each move).

This is what I've thought out so far, and feel as if it should be able to work. Guys and Gals, I would really appreciate all the help I can get- whether it's advice on how to control multiple shift registers, or ideas for how I can solve this problem more elegantly.

Thanks you all so much :art: :wink: :sunglasses:

Here is the example code, by the way.

nt datapin = 2;
int clockpin = 3;
int latchpin = 4;
byte data = 0;

void setup()
{

pinMode(datapin, OUTPUT);
pinMode(clockpin, OUTPUT);
pinMode(latchpin, OUTPUT);
}

void loop()
{
oneAfterAnother();
}

void shiftWrite(int desiredPin, boolean desiredState)
{
bitWrite(data,desiredPin,desiredState);
shiftOut(datapin, clockpin, MSBFIRST, data);
digitalWrite(latchpin, HIGH);
digitalWrite(latchpin, LOW);
}

void oneAfterAnother()
{
int index;
int delayTime = 100;

for(index = 0; index <= 7; index++)
{
shiftWrite(index, HIGH);
delay(delayTime);
}

for(index = 7; index >= 0; index–)
{
shiftWrite(index, LOW);
delay(delayTime);
}
}
void binaryCount()
{
int delayTime = 1000; // time (milliseconds) to pause between LEDs
// make this smaller for faster switching

// Send the data byte to the shift register:

shiftOut(datapin, clockpin, MSBFIRST, data);

// Toggle the latch pin to make the data appear at the outputs:

digitalWrite(latchpin, HIGH);
digitalWrite(latchpin, LOW);

// Add one to data, and repeat!
// (Because a byte type can only store numbers from 0 to 255,
// if we add more than that, it will “roll around” back to 0
// and start over).

data++;

// Delay so you can see what’s going on:

delay(delayTime);
}

You'll need at least one dynamic 2D matrix and an algorithm to juggle all that around.

Maybe 7 switches for rotation; 3 vertical, 3 horiz, 1 for spin direction (hold spin dir down with the H or V is one way, no spin dir with H or V for other way.)

Hmm, could you explain to me what a dynamic 2D matrix is and how it would work in this context?

Sure. Here are three faces of that array.

char coolarray[6][9] = {
{"R","R","R"},
{"R","R","R"},
{"R","R","R"},
{"O","O","O"},
{"O","O","O"},
{"O","O","O"},
{"G","G","G"},
{"G","G","G"},
{"G","G","G"},
...
};

So you'd have to scan the elements and then implement the color PWMs accordingly.
When you spin the rows or columns or whatever the jargon is then that matrix, above, would have to be changed accordingly (the dynamic part of it.)
Maybe there's a better way.
Thinking about it more - 3 more switches will be needed (3 for each dimension and 1 for which way to spin.)
3 for spinning the levels
3 for the faces
3 for the edges

Do you have to use that design?
Seems like the physical wiring will be quite a challenge.
I'd be tempted to use NeoPixels which will make the wiring and programming quite a bit simpler.

--- bill

Hi, I second the neopixel/ws2812b idea. If you can find a way to construct the cube from 26 smaller cubes made from some translucent material, or one large cube of translucent material with internal, opaque dividing walls, you would only need 26 rgb leds to internally illuminate each part of the cube (the 27th is of course always hidden in the centre). This type of led means only 3 wires daisy-chaining all 26 leds together and needs only 1 arduino output to control all 26 leds in the chain.

Unfortunately I can’t think of an equally slick design for your buttons. Where were you thinking of placing them? For 12 buttons you can use as few as 4 arduino inputs/outputs using a technique called charlieplexing (which only works if, like your situation, only one of the buttons will ever be pressed at a time).

Paul

PaulRB:
Unfortunately I can't think of an equally slick design for your buttons. Where were you thinking of placing them? For 12 buttons you can use as few as 4 arduino inputs/outputs using a technique called charlieplexing (which only works if, like your situation, only one of the buttons will ever be pressed at a time).

Paul

Switch to the analog domain. You could support all of them on one arduino pin if you use a resistor ladder and only need to support having one button pressed at a time.

Many of the LCD shields out there use this technique to get support for 5 buttons using only a single AVR analog pin.

--- bill

Excellent idea Bill. But would a resistor ladder be appropriate, rather than some other resistor network? With a ladder, wouldn't each switch have half the effect at the Arduino analog input compared to the switch next to it? Would that be a problem with 10-bit adc and 12 buttons? Would a simple resistor network with 12 different values (plus a 13th resistor to form a voltage divider) be the way to go?