Part 2: the circuit.

This is where the transistors come into play.

Each of the "power" points on the trasistor bases are actually pins from the micro controller.

Now onto the hard stuff.

This was the real reason the cube was built: to figure out the strange voodoo which is C+. Before we get ahead of ourselves, there is a basic schematic to follow. Both the cathodes and anodes need to be attached to their own transistors.

Why transistors? It serves as a buffer to protect the Arduino from having too much current being pulled out the pins (which will fry the board).

Here’s the short version: transistors act like switches, this we all know. For a low base current, you can allow a greater amount of current to flow through the collector to the emitter, meaning that the transistor acts as a signal amplifier: small signal in, large signal out.That is just the tip of the iceberg. There is far more to get into, but luckily there are only two states which interest us: “on” or “off”.

*Full disclaimer: this works but it’s not pretty, nor is it the most effective way of utilizing the LED cube. What it is,however, is a great way to understand statements within a code*

Note: this is important. Anodes are connected to emitters and cathodes to collectors.

The transistor setup is very specific because if the anode was connected to the collector the LED would be able to bypass the transistor when current is applied; the same is to be said for the cathode and the emitter.

The idea is that you can control rows and columns via a combination of 2 of the transistors.

Connecting the cube to an Arduino (Uno).

There are 12 output pins to use, which means a 3 by 3 cube will virtually max out your pin capacity if you’re going to use a single pin per column/layer. There are however workarounds, none of which we are going to get into right now, but trust us they are out there.

Keep track of which pin goes where. Mark it down whichever way you like, as long as the system makes sense to you. Working from left to right is a good way to go: that way every third number will be the counterpart of the LED just one row down. So in the context of the led cube (3 by 3, that is) the left will be the 1st, 4th, and 7th pin. It makes the process simpler when trying to visualize how the code is going to work.

Just one snag: pin 1 was a dud. Pin 1 made up its mind that it will always be HIGH for some odd reason. But not to fear pin 13 is still open.

Because of this, wiring everything up to fit made my pin sequence look like a hot mess:

13,2,3,6,4,5,9,7,8

contextually that would mean my first row was 13,2 and 3 and the second 6, 4, 5 ect.

In addition to this, the first, second and third rows were 9, 10 and 11.

Now the code:

This one was a learning experience, but here are some simple quirks that aren’t apparent when you just start out.

The arduino handles commands sequentially:

When you have a set of statements the Arduino will handle them one at a time, top to bottom, which has a specific influence on situations where only having one set of variables active at a time is important.

For example :

For code where you have two LED’s and you only want to turn one on at a time:

(Incorrect)

void
loop
{
digitalWrite
(LED1 ,
HIGH
)
digitalWrite
(LED2,
HIGH
)
digitalWrite
(LED1,
LOW
)
digitalWrite
LED2,
LOW
)
}

- This is going to turn on both and off at (virtually) the same time

(correct)

void
loop
{
digitalWrite
(LED1 ,
HIGH
)
digitalWrite
(LED1,
LOW
)

digitalWrite
(LED2,
HIGH
)
digitalWrite
(LED2,
LOW
)
}

- This time the first LED is turned on, then off,after which the second led is turned on then off (since there is no delay commands, it going to look as if both are on anyway)

Circumstantial commands:

These are the quintessence of the Arduino: commands which only become active when an arbitrary value is reached. In this case, the Arduino internally writes a number for x which increases by single increment every time an action is completed.

In terms of code it looks something like this :

for
(int x=0 ; x<1000 ; x++ )()

int: defines a parameter
= : defines a set value, and should not be confused with == which states a change of value.
++ is a increment.
X < 1000 (specifically) a check to see if x is smaller than 1000 if it is not ( and not otherwise instructed) x will reset to 0 ( but that’s because of the overall statement x= 0 initially and the increment (x++) doesn’t change the initial value)

Simple, right? If this is new territory, it’s best to experiment.

Multiplexing at it simplest :

Multiplexing is rapidly switching values/ states so as to make it appear as if it is one command, which becomes particularly important with led cubes.

digitalWrite
(LED1 ,
HIGH
)
delay
30
digitalWrite
(LED1,
LOW
)

Would mean that the total time taken to turn the LED on and off will be 32 milliseconds.This is not NASA, and by extension NOT rocket science, which means that extra 2 milliseconds won’t have a profound effect on how the cube will react in the end, but if the effect is compounded enough, expect to see some flickering.

There is a good deal more to say on the subject but that’s all the “required” knowledge for this build.

Here is a situation:

If you have a LED square of 4 LEDs (that’s 2^2) and you wanted to activate the bottom left LED (let’s make this the first in the sequence, i.e. 1,1) as well as the top right LED in the same plane (2,2); if a continuous DC signal is sent, 4 of the LEDs will light up. The path for current will now be open on both rows for all activated columns. This is where multiplexing comes in, allowing the ability to activate a single LED for a fraction of a second, which gives you the ability to make it seem as if the LED is on continuously.

The full code:

Got you. There is no way of fitting that monster on this page but if you want the IDE, feel free to download it here.

Here is the short

for
(int x=0 ; x<1000 ; x++ )(
If
( x>0 && x<300) {
digitalWrite
(lvl_1 ,
HIGH
)
digitalWrite
(pin1 ,
HIGH
)
delay
3
digitalWrite
(pin1 ,
LOW
)
digitalWrite
(lvl_1,
LOW
)
digitalWrite
(lvl_2 ,
HIGH
)
digitalWrite
(pin2 ,
HIGH
)
delay
3
digitalWrite
(pin2 ,
LOW
)
digitalWrite
(lvl_2,
LOW
)
}
)

This code will be repeated between the interval of x=0 and x=300, turning on only the LED(1,1) and LED(2,2); but unlike direct DC will leave the LEDS at position (2,1) and (1,2) off.And that is how it’s done. Here’s a couple of pointers to start off with: the first being that this represents a single frame. To move on to a new set of LEDs, there is going to have to be a second If statement. That is why this works the best, because when not inside the stated parameters, the microcontroller will not try to use the commands. The second pointer is that there is a limit to how many LEDs can be multiplexed at a time (shortening or lengthening individual intervals will change that limit significantly). Have too many active at once, and you will notice flickering, which will only get worse as the complexity of the executed code increases.

Conclusion?

The quirk with this way of programming is that it is labor intensive. Changing an interval is a pain and keeping track of interval sets is a must. There are more complex ways of programming the same commands, which equated to less typing work, but for total beginners this is pretty easy to understand.

Super easy, and the most of anything invested is time, but it’s worth the work.

Now go try it yourself.

Sources:

A brilliant video explain how multiplexing works and how to improve the design even more.

How the coding works as well as all the commands available for the arduino.