Introduction: LED Rubik's Cube With Arduino
In this instructable I'll show you how you can build your own LED Rubik's cube. This project was done for an introductory electronics course at Pomona College. Groups were given approximately two months to complete a project of their choosing, the only requirement being that the project rely on electronics built by the students.
Our group decided to build a Rubik's cube that uses RGB LED's for its faces, and buttons to simulate rotations. This should walk you through the process in enough detail for it should be clear what you would have to do to recreate our project.
Step 1: Essential Electronics.
Below are the components on which the cube's electronics run:
- 5mm RGB LED x 54
- 330 Ohm Resistor (1/4 Watt) x 162 (3 per LED)
- 74HC595 8-bit Shift Register x 54
- Amico 8.5mm 4 pin DIP pushbutton x48
- Arduino Uno
- 28 Gauge Wire
The RGB LED's, resistors, and pushbuttons are self-explanatory, but the Shift Registers aren't. The LED's can generally be found for about $.75 each, while the shift registers are about a buck a piece on Amazon.com. The buttons are on Amazon and are about $.05 a piece.
Step 2: The Shift Register
The Single Shift Register
In isolation, a single shift register gets you eight outputs for the price of three I/O's on your Arduino. It is an integrated circuit that requires power and ground, and takes 3 inputs from the Arduino. These input pins (11,12,14) are called the clock pin, latch pin, and data pin respectively. Of the shift register's sixteen pins, eight are outputs which can be used to control various devices digitally. The states of these outputs are determined by sending the shift register data. Given one byte of data the shift register will turn its eight outputs either high or low, 1 for high, 0 for low. The Arduino uses the clock and latch pins to tell the shift register when to receive data and when to process it, while the the data pin is where the data is actually carried. The Arduino has a built in command to give data to the shift register. A tutorial can be found here: http://www.arduino.cc/en/Tutorial/ShiftOut. Knowledge of the shiftOut command described in the tutorial is important, but easily summarized. The syntax is:
digitalWrite(latchpin;LOW); //signals shift register that it is about to receive data
shiftOut(dataPin, clockPin, MSBFIRST, data); //sends out byte named 'data', starting with the most significant bit.
digitalWrite(latchpin;HIGH); //signals shift register to process the data, switching desired outputs.
All this command does it tell the Arduino to send out whatever byte we have called 'data' to the shift register. The shift register will take a byte, and use the value of the first bit to control its first output and so on. The MSBFIRST command tells the Ardunio which bit to send out first. The leftmost bit is the most significant. So, as an example, if data=11111111, the shift register will write all of its outputs to high. If data=00000000, the shift register will write all of its outputs to low.
Multiple Shift Registers: The Daisy Chain
The real power in the shift register comes from their ability to be linked together in a daisy chain. If two shift registers have their clock pins and latch pins connected, and we connect the data out pin (9) of one shift register to the data pin (14) of another, the Arduino can communicate to both serially. In this fashion the Arduino can communicate to a virtually unlimited number shift registers and other devices, still using only three I/O's. If we replace our lone byte ,'data', by an array of bytes such as: data[]={a,b}; where a=00000000 and b=11111111, then the command shiftOut(dataPin, clockPin, MSBFIRST, data); will give byte a to the second shift register, and byte b to the original shift register. In this way an arbitrarily long daisy chain works just like a conveyor belt. The first byte in the data array is the first one to be shifted out, and goes straight to the first shift register, which hands it off the next shift register and so on until the end of the chain. This happens with each byte, so the last shift register ends up receiving the first byte in the array, while the first shift register receives the last. This makes chain of shift registers a great way to control a series of 54 RGB LED's by coding with an Arduino.
Step 3: Concept
By connecting each LED to a shift register, and shifting out a data array of 54 bytes to a daisy chain of shift registers, we can control our LED's however we want. Using only digital writes, the three diodes in an RBG LED provide us with 8 colors to choose from: Red, Green, Blue, Yellow(RG), Violet(RB), Teal(BG), and White(RGB). If we connect our LED's systematically so that their leads correspond to the same pins on each shift register, then we can define 8 bytes, each of which represent a color an LED receive.
To operate the cube we create a 54-byte array, in which each of the six colors we choose appears nine times. The order of bytes in this array is important, because, upon start, this array will get shifted out immidiately, and must bring the cube to a state in which it is already solved. Rotations are executed by swapping array values in a one-for-one manner, and then shifting out the array again. As each LED always corresponds to the same index in the array, we can easily figure out which values must be swapped to achieve a given rotation.
Upon inspecting a Rubik's cube you should find that there are exactly twelve distinct operations that can be performed. A Rubik's cube has six faces, and we can take any face and rotate in one of two directions. Keeping a fixed orientation, each rotation will change the position of twelve squares along the edge of the cube, as well as 8 squares on one of the faces. Thus, in our code, we must have twelve subroutines that each swap twenty bytes in the array. For operating the cube, we decided on 8 buttons per face, so that we can rotate either of the four edges of that face in either direction. For a cube with six faces, and 48 buttons, there will four sets of twelve identical buttons. To account for this we electrically connect identical buttons, so that they can share an input at the Arduino. Thus, we use 15 pins on the Arduino in all. We could have cut this number down buy addressing the buttons with a multiplexer that requires fewer inputs.
Step 4: Designing the Cube, Part 2
While the theory behind how the cube works is straightforward, implementation was difficult. Our first prototype was built on a breadboard, and contained an unruly amount of wires. Doing some numbers:
9 LEDS x 4 wires per LED=36 wires
27 Resistors x 2 leds per resistor= 54 leads
9 Shift register x 7 wires per LED (clock, data, latch, data out, power x2, ground x2)=63 Wires
8 buttons x2 wires per button (one wire to Arduino and one to ground) = 16 wires.
Let's be nice and say we would required about 90-100 wires per face. At six faces, it becomes impossible to design a self contained Rubik's cube using this many wires. At a certain point we came to the reality that we were going to have to design our own circuit boards.
Step 5: Designing the Cube, Part 3
Designing a circuit board is not too difficult with some guidance. We used Eagle Hobbyist to design a 4"x4" circuit board that did everything our bulky prototype was capable of doing. Eagle is a neat software package that works by compiling enormous libraries of parts that one can add to a schematic file. In the schematic file we add our parts and then use the 'net' function to electrically connect the necessary parts. From the schematic file, Eagle automatically creates a board file, in which we design the board's layout, including the size and spacing between parts. We then use the auto-route function to calculate the most efficient way to electrically connect all of the pins as designated in the schematic file. Once satisfied with the board, we export a series of gerber files that any circuit board printer readto fabricate printed circuit boards (PCB's). Eagle does offer links to services where you can order your board boards directly. The two photos above are images of our schematic and board files.
https://www.dropbox.com/sh/zkxd1svqe9wmol0/AACX3mn...
Here is a link where you can download higher quality images.
Step 6: Assembly, Part 1
With our circuit boards in hand, we had a LOT of soldering to do. All of our components must be soldered directly into each board, a total of nearly 300 joints per board.
Step 7: Soldering
A solid workstation is an must. Ideally you'll have a stand that can grip your board by the edges. Solder Flux is also an invaluable tool. It's a flowing agent that helps with heat transfer. This can be an advantage because too much heat can be damaging to your components. It also saves quite a bit of time in the long run. Solder wick, to remove solder is also essential. You will make mistakes, and this will come in handy. Lastly, some isopropyl alcohol with a small brush to clean the board can also be very helpful, as solder flux is sticky when it dries.
Step 8: Assembly, Part 2
In order to enclose the Arduino in the cube, we screwed it to a spot in one of the boards with no routing. We also had to remove the Arduino's power and USB ports to save space. We instead soldered our own USB cable directly to the Arduino. We had to determine which of our pushbuttons were redundant, and connect those buttons, linking only one button in each group to the Arduino. We connected boards together, giving them all a common +5 and ground, also making sure that the last shift register on one board is properly connected to the first on the next (clock, latch, data) . Thus, a total of 10 wires link a board to its two neighbors. On the schematic and board files in Eagle, we added the appropriate connectors to make this process easy. The photo above shows the six boards with all of the wiring done.
Step 9: Assembly, Part 3
Assembling this thing required a lot super glue. The process was carried out one edge at a time, leaving ample time for drying. The final face, the one carrying the Arduino, was sealed using silicon rather than super glue, allowing us to break the seal in the future if needed.
Step 10: Voila
We're pretty happy with how it turned out, though we are still waiting on diffuser caps for our LED's to take the edge off the brightness. Sorry for the crappy video. A better one will be coming soon, hopefully. Our code is included in the next step. Our hope is that if you're crazy enough to build a second copy of the world's most useless/expensive Rubik's cube, you'll find this instructable to a handy guide. It's not an instruction manual by any means, but it should give you a clear idea of what the challenges are and how you can address them.
Please contact me if you have questions. I'm hoping to add to this instructable as I continue to update the cube. The next step is to try and add modes so that it can function as an RGB LED lamp as well. I'm also working on getting better quality images of the schematic available for download.
A very special thanks goes out to Tony Grigsby and Dwight Whitaker at Pomona College. None of this would have been remotely possible without their assistance.