Last week I built an LED cube — 64 LEDs which you can program to create fantastic futuristic light shows — and I hope you did too, because this is a great project to motivate you and expand your Arduino skill set. I’ve left a few basic applications for you to think about, but today I’ll present a few more bits of software I’ve made for the cube, along with code explanations. The purpose of this is not only to give you some nicer light shows, but also to learn about some of the limitations of cube programming and learn some new programming concepts along the way.

This is a fairly advanced encoding; you really need to read all my previous Arduino tutorials and guide for arduino beginners. before customizing the provided code.

Application 1: Mini Snake

Instead of launching a sequence of patterns like a snake, I wanted to program a snake — an artificial one that would make its own random choices and be completely unpredictable. It is limited to only two segments which I will explain later and you can see a demo below. Download full code here.

When working with 3D space, you need 3 coordinates for one point: x, Y and Z.

Arduino led cube

However, in our cube, the X and Z planes are represented by LED pins, and Y is directly mapped onto the cathode plane. To make it easier to work with these coordinates and figure out the movement around the cube, I created a new data type (using struct ) to represent one point on the cube, which I named «xyz». It consists of only two integers: «xz» and «y». With this structure, I could also represent the direction given below in our special (xz, y) coordinate system:

Y movement (up down) : (xz, y + 1), (xz, y-1)
Traffic Z (back and forth) : (xz-1, y), (xz + 1, y)
Movement X (left, right) : (xz + 4, y), (xz-4, y)

For example, to move the LED to position (0.0) from left to right, we apply (xz + 4, y) and finally we get (0.4) .

There are certain restrictions on movement, namely: Y coordinates can only be possible from 0 to 3 (0 is the bottom layer, 3 is the top), and the XZ coordinates are from 0 to 15 . A further constraint is placed on the Z movement to prevent «jumping» from behind to the front of the cube, and vice versa. In this case, we use the modulo function to test for a multiplicity of 4 and reject this move attempt. This logic is presented in the function valid() which returns true if the suggested direction is acceptable and false otherwise. I have added another function to check reverse direction — that is, if the snake is moving in one direction, we don’t want it to move backward on its own, even if it is otherwise a valid place to move — and Function move() which takes a coordinate, a direction, and returns the new coordinate.

Functions XYZ datatype, valid() , move() and reverse() can be found in the file xyz.h in downloaded files. If you’re wondering why this was placed in a separate file instead of the main program file, it’s due to some tricky Arduino compiler rules that don’t allow functions return custom data types ; they must be placed in their own file and then imported at the beginning of the main file.

Back in the main executable, the directions array stores all the possible moves the snake can make; we can just pick a random array member to get a new direction. Variables are also created to store the current location (now), previous directions and previous locations . The rest of the code should be fairly obvious to you; just for looping and turning the LEDs on and off. In the main loop, we check if the proposed direction is correct, and if so, then we go that way. If not, we choose a new direction.

The only thing to watch out for in the main loop are some checks to fix a multiplexing bug I found: if the new location was on the same cathode plane or on the same anode pin, turning off the previous LED would cause both go out. Also at this point I realized that going beyond the 2-segment snake would be impossible with my current implementation: try lighting 3 LEDs in a corner arrangement. You can’t do that because with active 2 layers and 2 LED pins, 4 LEDs will turn on, not 3. This is an inherent problem with our limited multiplexed cube design, but don’t worry: we just need to use the power constancy of vision overwrite draw method.

Persistence of vision means that when light reaches our eyes sequentially — faster than we can process it — it appears to be a single image. In our case, instead of drawing all four layers at the same time, we have to draw the first one, deactivate it, draw the second and deactivate it: faster than we can tell any change is even happening. This is the principle by which the authors of the messages work, for example:

New Draw Method Using Persistence of Vision

First of all, a new drawing procedure. I created two-dimensional array bits 4×16 (true or false) to literally represent the state of the LED cube. The draw routine implements vision persistence by simply iterating over it all and dumping each layer into a cube for a short time. It will continue to draw itself in its current state until the update time expires, at which point we will pass control back to the main loop (). I’ve saved this section of code in this LED_cube_POV file, so if you just want to get into programming your own games and such, feel free to use that as a base.

Appendix 2: The Game of Life

For now, let’s turn this into a basic version of Conway’s game of life. For those of you who are unfamiliar (try to google it for an awesome easter egg animation) » Game of Life» is an example of cellular automata that create an exciting pattern of emergent behavior given just a few simple rules.

15700259

This is, for example, how ants seem to move with the intelligence and mind of the hive, despite the biological fact that they are simply following the most basic hormonal rules. Here is the complete download code : click the button reset to reload. If you find yourself getting the same pattern over and over, try holding the rest button longer.

https://www.youtube.com/watch?v=iBnL8pulJ&xid=17259,15700023,15700186,15700190,15700256,15700259,15700262,15700265,15700271,15700283&usg=ALkJrhgrAqwDQWVZ4LcCLkw3PwwvZ4LcCLkw3PwwvZ4LcCLkw3PwwvZ4Lcclw3PwwvZ4

Here are the rules of the game of life:

  • Any live cell with fewer than two live neighbors dies as if it were caused by insufficient population.
  • Any living cell with two or three living neighbors survives to the next generation.
  • Any live cell with more than three live neighbors dies, as if due to overcrowding.
  • Any dead cell with exactly three living neighbors becomes a living cell, as if by reproduction.

Run the code. Within 5-10 «generations» you will notice that the automata have probably stopped, having stabilized at a certain position; sometimes this stable model changes location and moves around the board. In rare cases, they may even die out completely. This is a limitation of only using 4x4x4 LEDs, but it’s a good learning exercise anyway.

To explain the code:

Improvements : I spent too much time on this, but you can try adding a check that automatically resets the board after 5 or more generations of the same pattern. then please let me know! I would also suggest trying to add a POV methodology to the snake game to hopefully make a longer snake possible.

That’s all from me today. I may come back to other Arduino LED Cube applications later, but hopefully you can modify my code and create your own game rules: let us know what you think in the comments so we can all upload your creations! As always, I’ll be here to answer your questions and defend my terrible coding skills.

Image Credit: Cartesian coordinates — Wikimedia user Sakurambo

Похожие записи