Instructables

8x8x8 LED Cube with Arduino Mega (+Sound +PS controller +Game)

FeaturedContest Winner

This is a instructable which is based on the Cube
by Chr, ( http://www.instructables.com/id/Led-Cube-8x8x8/ )
by SuperTech-IT, ( http://www.instructables.com/id/CHRs-8X8X8-LED-Cu... )
and by das-labor.org, ( http://www.das-labor.org/wiki/Borg3d_Bauanleitung... )
but i think its better and easier.

I started this Project without any skills from soldering toprogramming.

First of all I apologize first for my poor English. Because of this parts of this instructable are German.
Maybe I translate it later.


this happens if you lose

wining looks like this


and these are the effects:

 
Remove these adsRemove these ads by Signing Up

Step 1: The Component list

Deutsch:
Für den Cube:
512x LEDs
10x Versilberter Draht 0.8mm für Platinen und LED Gitter, 7m SILBER 0,8MM

Für die Platinen:
2x Lochraster Platine 160x100 H25PR160

Platine 1, Säule:

3x 36pol. Stiftleiste, gerade,
10x 10pol. Buchsenleiste, gerade, RM 2,54 BL 1X10G8
1x 74HC138 IC
8x 8 fach D-Flipflop 74HCT574
8x Sockel D-Flipflops GS 20P
100x Widerstände 47 Ohm
9x Kondensator 100nF KERKO 100N
1x 16 pin IC Sockel

Platine 2, Ebenen:

8x Mosfet Transistor BUZ11
2x 36pol. Stiftleiste, gerade,
2x 10pol. Buchsenleiste, gerade, RM 2,54 BL 1X10G8

Für Musik:
Ähnlich wie hier: http://arduino.cc/en/Tutorial/tone
1x Arduino Uno
1x 100 Ohm Widerstände
1x Lautsprecher 8 Ohm
2x Widerstände zwischen 1,5 K und 47 K
1x Schalter 2 oder 3 Positionen
1x oder 2x 10K ohm Widerstände

Für den Controller:
1x Playstation controller

Für Gehäuse:
1x kleine Tube Plexiglas Kleber transparent
1x Plexiglas ca. 405x405mm (for the top)
4x Plexiglas ca. 400x400mm
Genug Holz für den Unterbau und die Schablone

Und:
1x Steckerschaltnetzteil SNT 2500 (5V)
1x Arduino Mega 2560 R3
Und natürlich eine Menge Lot Draht und Kleinzeug.



English:
for the cube:
512x LEDs
10x Silver plated wire 0.8mm for sinkers and LED grid

for the sinkers:
2x Breadboard 160x100 H25PR160

for sinker 1, pillar:
3x 36pol. Male connector, straight,
10x 10pol. Female connector, straight, RM 2,54 BL 1X10G8
1x 74HC138 IC
8x 8xD-Flipflop 74HCT574
8x socket D-Flipflops GS 20P
100x resistors 47 Ohm
9x capacitor 100nF KERKO 100N
1x 16 pin IC socket

for sinker 2, layers:
8x Mosfet Transistor BUZ11
2x 36pol Male connector, straight,
2x 10pol. Female connector, straight, RM 2,54 BL 1X10G8

for the sound:
similar to this: http://arduino.cc/en/Tutorial/tone
1x Arduino Uno
1x 100 Ohm resistor
1x Speaker 8 Ohm
2x resistor between 1,5 K and 47 K
1x switch 2 or 3-positions
1x or 2x 10K ohm resistor

for the controller:
1x Playstation controller

for the case:
1x small tube of adhesive acrylic glass transparent:
1x acrylic glass ca. 405x405mm (for the top)
4x acrylic glass ca. 400x400mm
Enough wood for the base and the template

and:
1x SNT 2500 (5. Female connector, straight power supply)
1x Arduino Mega 2560 R3
and a lot of wire, solder and other little things you find somwhere

Step 2: Build the Cube

Deutsch:
Den Cube baute ich nach der Anleitung von das Labor denn dies ist etwas einfacher als nach der Methode die hier in den Anleitungen kursieren.
http://www.das-labor.org/wiki/Borg3d_W%C3%BCrfel_...

1. Schablone für je 8x8 LEDs bauen
- Größe für den Cube überlegen
Ich entschied mich für 4cm Abstend zwichen den LEDs also eine gesamt größe von ca 28cm
Die Holzplatte zur Herstellung sollte dem entsprechend gößer sein.
- 8 Nuten senkrecht fräsen mit einer Tiefe von 7mm und einer Breite von ca 3mm
- 8 Nuten senkrecht fräsen mit einer Tiefe von 1- bis 2mm und einer Breite von ca 3mm
- Für die LEDs muss noch 2mm über jeder Kreuzung eine Vertiefung für die LED gemacht werden

English:
I build the cube itself after this:
http://www.das-labor.org/wiki/Borg3d_W%C3%BCrfel_B...
It's much cuter than intractables I’ve seen on this site.

1. Build a Template for 8x8 LEDs
- Consider the size for the cube
- I chose 4cm as the distance between the LEDs yielding to a total size of approx 28cm

The wooden plate for making should be bigger according to the following.
- 8 grooves milled vertically to a depth of 7 mm and a width of about 3mm
- 8 grooves milled vertically to a depth of 1 - to 2 mm and a width of about 3mm
- Still a 2mm recess for the LED needs to be done about every intersection for the LEDs

Step 3: Build the sinkers

Picture of Build the sinkers
plan 1 pillars.bmp
plan 3 PSX.bmp

German:
Die Platine baute ich ebenfalls nach:
https://www.das-labor.org/wiki/Borg3d_Platinen_Bau...

Doch ich entschied mich später so um zubauen wie es bei chr (Step 9) beschrieben wurde.
Von der Platine mit mc nutze ich nur noch die Transistoren, denn als mc verwendete ich einen arduino uno bzw. mittlerweile einen arduino Mega.
Den Cube selbst kann ich wie auch schon bei chr beschieben mit allen Effeken auf einem arduino uno laufen lassen, allerdings wollte ich noch einen Playstation controller nachrüsten, deshalb änderte ich das Programm auf die Hardware für den Arduino Mega.



Englisch:

The board I built also by:
https://www.das-labor.org/wiki/Borg3d_Platinen_Bau...

But later I decided, however, to assemble the board with mc as described by chr in (Step 9).
From the board, I only use the transistor circuit, because as mc I used an arduino uno and now a arduino mega.
The Cube itself I can already run like chr with all effecs on arduino uno, but I still wanted a Playstation controller upgrade, so I changed the program to the hardware for the Arduino Mega.



On the wiring diagram i am still working. This will take some time and follows later. I changed too much too many times. It´s a mix from chr and das-labor. But easyer.




Step 4: PIN wiring

Picture of PIN wiring
PinMap2560sma_.png

Please check the pictures, how to connect the mega to the sinkers.

Step 5: Build the case, power supply etc...

see the pictures
the cube has a acrylic glass hood made with 5 pieces of acrylic glass and a bit glue

1x ca 405x405mm (for the top)
4x ca. 400x400mm
you will figure it out
but test it before gluing and read first how the glue works (my glue cures only by blacklight)

i made the rest out of boards laying around

Step 6: Programm (Arduino Mega setup)

Vorerst hier nur die Änderung im setup für den Arduino Mega:
ursprungscode von chr
http://www.instructables.com/id/Led-Cube-8x8x8/ (step 70)

Here you find the changes I made to his code. (from Arduino UNO (like chr) to Arduino Mega)

void setup()
{ int i;
//Pins 22 bis 50 als Ausgänge festsetzen
for(i=22; i<50; i++) pinMode(i, OUTPUT);

// pinMode(A0, OUTPUT) as specified in the arduino reference didn't work. So I accessed the registers directly.
DDRC = 0xff;
PORTC = 0x00;

// Reset any PWM configuration that the arduino may have set up automagically!
TCCR2A = 0x00;
TCCR2B = 0x00;

// zähler, Uhr initialisieren
TCCR2A |= (0x01 << WGM21); // CTC mode. clear counter on TCNT2 == OCR2A
OCR2A = 10; // Interrupt every 25600th cpu cycle (256*100)
TCNT2 = 0x00; // start counting at 0
TCCR2B |= (0x01 << CS22) | (0x01 << CS21); // Start the clock with a 256 prescaler
TIMSK2 |= (0x01 << OCIE2A); //Timer Interrupt Mask Register
}

//interrupt
ISR (TIMER2_COMPA_vect)
{
int i;
// PORTA = 8x Databus (8-Bit-Latches) PIN 22-30 (bei uno Pins 0-7 PortD)
// PORTL = 3x Adressbus + OE
// PORTC = 8x Ebenen (Layer)
// Char cube [ 8 ] enthält 64 Bits von Daten für die Halteanordnung
// all layer selects off
PORTC = 0x00;
PORTL &= 0x0f; // PortL 3xAdressbus
PORTL |= 0x08; // output enable off.

// Zählen bis 8
for (i=0; i<8; i++)
{
PORTA = cube[current_layer][i]; //(PortA = 8xDatabus) PIN 22-30 (bei uno Pins 0-7 PortD)
PORTL = (PORTL & 0xF8) | (0x07 & (i+1)); // (i+1) => 74HC138 erhält die folgende Sequenz: 1 2 3 4 5 6 7 0 (muss immer eins voraus sein)
}
PORTL &= 0b00110111; // Output enable on.

//ebenen
if (current_layer < 8)
{
PORTC = (0x01 << current_layer);
}
current_layer++;
if (current_layer == 8)
current_layer = 0;
}

Step 7: Programm PSX

Picture of Programm PSX
IMG_4517.JPG
ps1 controller.png
PS1 pins.JPG
psx wiring.JPG

#include psx

diese library kann man unter:
load it here:
http://playground.arduino.cc/Main/PSXLibrary


you have to change parts in this lib for the new Arduino IDE (I used 1.0.5) if you want to use a old Playstation controller!
you might also can use a ps2 or ps3 controller but then you need a other library.

Vor dem importieren muss allerdings eine Datei manuell angepasst werden da die PSXLibrary nicht für die Arduino IDE 1.0.5. angepasst wurde.

Because PSXLibrary ist not combatible with Arduino EDE 1.0.5 a file has to be adjusted before import like this:


Dazu die Herruntergeladene Datei öffnen - open the downloaded file

den ordner PSX öffnen - open the PSX

Die Datei PSX.h öffnen - open the PSX_h file

dort den Befehl #include "WConstants.h" - change #include "WConstants.h"

ändern zu #include "Arduino.h" - to #include "Arduino.h"

speichern - safe

nun sollte die Ardunio IDE keine Probleme mehr beim kompilieren machen.
after this it should compile.

Pin verdrahtung:

#define dataPin 50 //PS-Pin 1 brown

#define cmndPin 51 //PS-Pin 2 orange

#define attPin 52 //PS-Pin 6 yellow

#define clockPin 53 //PS-Pin 7 blue

//PS-Pin 4 GND black

//PS-Pin 5 VCC 3V red

Step 8: Programm (Arduino Mega effekte)

Here is a sample of the code (effects)
you find the complete (and current) code in last step


void loop()
{
int i,x,y,z;



while (gamechoice == 0)
{

effect_count_up(); //AZ
effect_count_thru(); //AZ

effect_text(1000,0,13);
effect_text_up(5000,0,6);

effect_rain(50);

effect_random_filler(75,1);
effect_random_filler(75,0);

effect_planboing(AXIS_Z, 400);
effect_planboing(AXIS_Y, 400);
effect_planboing(AXIS_X, 400);

effect_boxside_randsend_parallel (AXIS_X, 0, 150, 1);
effect_boxside_randsend_parallel (AXIS_X, 1, 150, 1);
effect_boxside_randsend_parallel (AXIS_Y, 0, 150, 1);
effect_boxside_randsend_parallel (AXIS_Y, 1, 150, 1);
effect_boxside_randsend_parallel (AXIS_Z, 0, 150, 1);
effect_boxside_randsend_parallel (AXIS_Z, 1, 150, 1);
effect_fireworks(10,30,500);
effect_intro();
sinelines(4000,10);
linespin(1500,10);
mirror_ripples(600,400);
effect_axis_updown_randsuspend(AXIS_Z, 550,5000,0);
effect_axis_updown_randsuspend(AXIS_Z, 550,5000,1);
effect_axis_updown_randsuspend(AXIS_Z, 550,5000,0);
effect_axis_updown_randsuspend(AXIS_Z, 550,5000,1);
effect_axis_updown_randsuspend(AXIS_X, 550,5000,0);
effect_axis_updown_randsuspend(AXIS_X, 550,5000,1);
effect_axis_updown_randsuspend(AXIS_Y, 550,5000,0);
effect_axis_updown_randsuspend(AXIS_Y, 550,5000,1);
side_ripples (300, 500);
effect_random_sparkle();
quad_ripples (600,300);

box_filled(2,2,2,5,5,5);
box_walls(2,2,2,5,5,5);
box_wireframe(2,2,2,5,5,5);

}
}

// ==========================================================================================
// Effect functions
// ==========================================================================================

void draw_positions_axis (char axis, unsigned char positions[64], int invert)
{
int x, y, p;

fill(0x00);

for (x=0; x<8; x++)
{
for (y=0; y<8; y++)
{
if (invert)
{
p = (7-positions[(x*8)+y]);
} else
{
p = positions[(x*8)+y];
}

if (axis == AXIS_Z)
setvoxel(x,y,p);

if (axis == AXIS_Y)
setvoxel(x,p,y);

if (axis == AXIS_X)
setvoxel(p,y,x);
}
}

}

// effect_count_up (AZ).
void effect_count_up ()
{
int i, ii, iii;
int x;
int y;
int z;

fill(0x00);
for (i=0; i<8; i++)
{
if (i <= 0)
{
x = 0;
y = 0;
z = 0;
}
for (ii=0; ii<8; ii++)
{

for (iii=0; iii<7; iii++)
{
setvoxel(x,y,z);
delay_ms(500);
z = z++;
}
setvoxel(x,y,z);
delay_ms(500);
y = y++;
z = 0;
}

setvoxel(x,y,z);
delay_ms(500);
x = x++;
y = 0;
}
}

// effect_count_thru (AZ).
void effect_count_thru ()
{
int i, ii, iii;
int x;
int y;
int z;

fill(0x00);
for (i=0; i<8; i++)
{
if (i <= 0)
{
x = 0;
y = 0;
z = 0;
}
for (ii=0; ii<8; ii++)
{

for (iii=0; iii<7; iii++)
{
setvoxel(x,y,z);
delay_ms(1000);
clrvoxel(x,y,z);
z = z++;
}
setvoxel(x,y,z);
delay_ms(1000);
clrvoxel(x,y,z);
y = y++;
z = 0;
}

setvoxel(x,y,z);
delay_ms(1000);
clrvoxel(x,y,z);
x = x++;
y = 0;
}
}


void effect_text_up (int delayt, int First, int Last){

const int charNum = 6;
char string[charNum] = {'S','U','P','E','R'};

fill(0x00);
for (int ltr = First; ltr < Last; ltr++){// For each letter in string array
for(int dist = 0; dist < 8; dist++) { //bring letter forward
fill(0x00);//blank cube
int rev = 0;
for (int rw = 7; rw >= 0; rw--) {//copy rows
// put this in for miswired backwards cube: cube[rev][dist] = bitswap(font_data[string[ltr]][rw]);
// cube[rev][dist] = font_data[string[ltr]][rw];
cube[dist][rev] = font[string[ltr]][rw];
// use above line for proper cubes
rev++;
}
delay_ms(delayt);
}
}
}


void effect_text(int delayt, int First, int Last){

const int charNum = 13;
char string[charNum] = {'P','r','e','s','s',' ','S','t','a','r','t','!',' '};

fill(0x00);
for (int ltr = First; ltr < Last; ltr++){// For each letter in string array
for(int dist = 0; dist < 8; dist++) { //bring letter forward
fill(0x00); //blank cube
int rev = 0;
for (int rw = 7; rw >= 0; rw--) {//copy rows
// put this in for normal cube:
cube[rev][dist] = bitswap(font[string[ltr]][rw]);
//cube[rev][dist] = font[string[ltr]][rw];
// cube[dist][rev] = font[string[ltr]][rw];
// use above line for backward ass cubes
rev++;
}
delay_ms(delayt);
}
}
}


void effect_boxside_randsend_parallel (char axis, int origin, int delay, int mode)
{
int i;
int done;
unsigned char cubepos[64];
unsigned char pos[64];
int notdone = 1;
int notdone2 = 1;
int sent = 0;

for (i=0;i<64;i++)
{
pos[i] = 0;
}

while (notdone)
{
if (mode == 1)
{
notdone2 = 1;
while (notdone2 && sent<64)
{
i = rand()%64;
if (pos[i] == 0)
{
sent++;
pos[i] += 1;
notdone2 = 0;
}
}
} else if (mode == 2)
{
if (sent<64)
{
pos[sent] += 1;
sent++;
}
}

done = 0;
for (i=0;i<64;i++)
{
if (pos[i] > 0 && pos[i] <7)
{
pos[i] += 1;
}

if (pos[i] == 7)
done++;
}

if (done == 64)
notdone = 0;

for (i=0;i<64;i++)
{
if (origin == 0)
{
cubepos[i] = pos[i];
} else
{
cubepos[i] = (7-pos[i]);
}
}


delay_ms(delay);
draw_positions_axis(axis,cubepos,0);

}

}


void effect_rain (int iterations)
{
int i, ii;
int rnd_x;
int rnd_y;
int rnd_num;

for (ii=0;ii {
rnd_num = rand()%4;

for (i=0; i < rnd_num;i++)
{
rnd_x = rand()%8;
rnd_y = rand()%8;
setvoxel(rnd_x,rnd_y,7);
}

delay_ms(1500);
shift(AXIS_Z,-1);
}
}

// Set or clear exactly 512 voxels in a random order.
void effect_random_filler (int delay, int state)
{
int x,y,z;
int loop = 0;


if (state == 1)
{
fill(0x00);
} else
{
fill(0xff);
}

while (loop<511)
{
x = rand()%8;
y = rand()%8;
z = rand()%8;

if ((state == 0 && getvoxel(x,y,z) == 0x01) || (state == 1 && getvoxel(x,y,z) == 0x00))
{
altervoxel(x,y,z,state);
delay_ms(delay);
loop++;
}
}
}


// Draw a plane on one axis and send it back and forth once.
void effect_planboing (int plane, int speed)
{
int i;
for (i=0;i<8;i++)
{
fill(0x00);
setplane(plane, i);
delay_ms(5000);
}

for (i=7;i>=0;i--)
{
fill(0x00);
setplane(plane,i);
delay_ms(5000);
}
}

void effect_fireworks (int iterations, int n, int delay)
{
fill(0x00);

int i,f,e;

float origin_x = 3;
float origin_y = 3;
float origin_z = 3;

int rand_y, rand_x, rand_z;

float slowrate, gravity;

// Particles and their position, x,y,z and their movement, dx, dy, dz
float particles[n][6];

for (i=0; i {

origin_x = rand()%4;
origin_y = rand()%4;
origin_z = rand()%2;
origin_z +=5;
origin_x +=2;
origin_y +=2;

// shoot a particle up in the air
for (e=0;e {
setvoxel(origin_x,origin_y,e);
delay_ms(600+500*e);
fill(0x00);
}

// Fill particle array
for (f=0; f {
// Position
particles[f][0] = origin_x;
particles[f][1] = origin_y;
particles[f][2] = origin_z;

rand_x = rand()%200;
rand_y = rand()%200;
rand_z = rand()%200;

// Movement
particles[f][3] = 1-(float)rand_x/100; // dx
particles[f][4] = 1-(float)rand_y/100; // dy
particles[f][5] = 1-(float)rand_z/100; // dz
}

// explode
for (e=0; e<25; e++)
{
slowrate = 1+tan((e+0.1)/20)*10;

gravity = tan((e+0.1)/20)/2;

for (f=0; f {
particles[f][0] += particles[f][3]/slowrate;
particles[f][1] += particles[f][4]/slowrate;
particles[f][2] += particles[f][5]/slowrate;
particles[f][2] -= gravity;

setvoxel(particles[f][0],particles[f][1],particles[f][2]);


}

delay_ms(delay);
fill(0x00);
}

}

}

void effect_intro(){
int cnt,cnt_2,time;

//Bottom To Top

for(cnt=0;cnt<=7;cnt++){
box_wireframe(0, 0, 0, 7, 7, cnt);
delay_ms(2000);
}
for(cnt=0;cnt<7;cnt++){
clrplane_z(cnt);
delay_ms(2000);
}

//Shift Things Right
//1
shift(AXIS_Y,-1);
for(cnt=0;cnt<=7;cnt++){
setvoxel(cnt,0,6);
}
delay_ms(2000);
//2
shift(AXIS_Y,-1);
for(cnt=0;cnt<=7;cnt++){
setvoxel(cnt,0,5);
}
setvoxel(0,0,6);
setvoxel(7,0,6);
delay_ms(2000);
//3
shift(AXIS_Y,-1);
for(cnt=0;cnt<=7;cnt++){
setvoxel(cnt,0,4);
}
setvoxel(0,0,5);
setvoxel(7,0,5);
setvoxel(0,0,6);
setvoxel(7,0,6);
delay_ms(2000);

//4
shift(AXIS_Y,-1);
for(cnt=0;cnt<=7;cnt++){
setvoxel(cnt,0,3);
}
setvoxel(0,0,4);
setvoxel(7,0,4);
setvoxel(0,0,5);
setvoxel(7,0,5);
setvoxel(0,0,6);
setvoxel(7,0,6);
delay_ms(2000);

//5
shift(AXIS_Y,-1);
for(cnt=0;cnt<=7;cnt++){
setvoxel(cnt,0,2);
}
setvoxel(0,0,3);
setvoxel(7,0,3);
setvoxel(0,0,4);
setvoxel(7,0,4);
setvoxel(0,0,5);
setvoxel(7,0,5);
setvoxel(0,0,6);
setvoxel(7,0,6);
delay_ms(2000);

//6
shift(AXIS_Y,-1);
for(cnt=0;cnt<=7;cnt++){
setvoxel(cnt,0,1);
}
setvoxel(0,0,2);
setvoxel(7,0,2);
setvoxel(0,0,3);
setvoxel(7,0,3);
setvoxel(0,0,4);
setvoxel(7,0,4);
setvoxel(0,0,5);
setvoxel(7,0,5);
delay_ms(2000);


//7
shift(AXIS_Y,-1);
for(cnt=0;cnt<=7;cnt++){
setvoxel(cnt,0,0);
}
setvoxel(0,0,1);
setvoxel(7,0,1);
setvoxel(0,0,2);
setvoxel(7,0,2);
setvoxel(0,0,3);
setvoxel(7,0,3);
setvoxel(0,0,4);
setvoxel(7,0,4);
setvoxel(0,0,5);
setvoxel(7,0,5);
delay_ms(2000);

//Right To Left
for(cnt=0;cnt<=7;cnt++){
box_wireframe(0, 0, 0, 7, cnt, 7);
delay_ms(2000);
}
for(cnt=0;cnt<7;cnt++){
clrplane_y(cnt);
delay_ms(2000);
}

//Shift to the bottom
for(cnt_2=6;cnt_2>=0;cnt_2--){
shift(AXIS_Z,-1);
for(cnt=0;cnt<=7;cnt++){
setvoxel(cnt,cnt_2,0);
}
for(cnt=6;cnt>cnt_2;cnt--){
setvoxel(0,cnt,0);
setvoxel(7,cnt,0);
}

delay_ms(2000);
}

//Make All Wall Box

for(cnt=0;cnt<=6;cnt++){
fill(0x00);
box_walls(0,0,0,7,7,cnt);
delay_ms(2000);
}

time = 2000;
for(cnt_2=0;cnt_2<5;cnt_2++){
time = time - 300;
//Make Box Smaller
for(cnt=0;cnt<=3;cnt++){
fill(0x00);
box_walls(cnt,cnt,cnt,7-cnt,7-cnt,7-cnt);
delay_ms(time);
}

//Make Box Bigger
for(cnt=0;cnt<=3;cnt++){
fill(0x00);
box_walls(3-cnt,3-cnt,3-cnt,4+cnt,4+cnt,4+cnt);
delay_ms(time);
}
}
for(cnt_2=0;cnt_2<5;cnt_2++){
time = time + 300;
//Make Box Smaller
for(cnt=0;cnt<=3;cnt++){
fill(0x00);
box_walls(cnt,cnt,cnt,7-cnt,7-cnt,7-cnt);
delay_ms(time);
}

//Make Box Bigger
for(cnt=0;cnt<=3;cnt++){
fill(0x00);
box_walls(3-cnt,3-cnt,3-cnt,4+cnt,4+cnt,4+cnt);
delay_ms(time);
}
}
delay_ms(2000);
}


void sinelines (int iterations, int delay)
{
int i,x;

float left, right, sine_base, x_dividor,ripple_height;

for (i=0; i {
for (x=0; x<8 ;x++)
{
x_dividor = 2 + sin((float)i/100)+1;
ripple_height = 3 + (sin((float)i/200)+1)*6;

sine_base = (float) i/40 + (float) x/x_dividor;

left = 4 + sin(sine_base)*ripple_height;
right = 4 + cos(sine_base)*ripple_height;
right = 7-left;

//printf("%i %i \n", (int) left, (int) right);

line_3d(0-3, x, (int) left, 7+3, x, (int) right);
//line_3d((int) right, 7, x);
}

// delay_ms(delay);
fill(0x00);
}
}

void linespin (int iterations, int delay)
{
float top_x, top_y, top_z, bot_x, bot_y, bot_z, sin_base;
float center_x, center_y;

center_x = 4;
center_y = 4;

int i, z;
for (i=0;i {

//printf("Sin base %f \n",sin_base);

for (z = 0; z < 8; z++)
{

sin_base = (float)i/50 + (float)z/(10+(7*sin((float)i/200)));

top_x = center_x + sin(sin_base)*5;
top_y = center_x + cos(sin_base)*5;
//top_z = center_x + cos(sin_base/100)*2.5;

bot_x = center_x + sin(sin_base+3.14)*10;
bot_y = center_x + cos(sin_base+3.14)*10;
//bot_z = 7-top_z;

bot_z = z;
top_z = z;

// setvoxel((int) top_x, (int) top_y, 7);
// setvoxel((int) bot_x, (int) bot_y, 0);

//printf("P1: %i %i %i P2: %i %i %i \n", (int) top_x, (int) top_y, 7, (int) bot_x, (int) bot_y, 0);

//line_3d((int) top_x, (int) top_y, (int) top_z, (int) bot_x, (int) bot_y, (int) bot_z);
line_3d((int) top_z, (int) top_x, (int) top_y, (int) bot_z, (int) bot_x, (int) bot_y);
}

// delay_ms(delay);
fill(0x00);
}

}

void mirror_ripples(int iterations, int delay)
{
// 16 values for square root of a^2+b^2. index a*4+b = 10*sqrt
// This gives the distance to 3.5,3.5 from the point
unsigned char sqrt_LUT[]={49,43,38,35,43,35,29,26,38,29,21,16,35,25,16,7};
//LUT_START // Macro from new tottymath. Commented and replaced with full code
unsigned char LUT[65];
init_LUT(LUT);
int i;
unsigned char x,y,height,distance;
for (i=0;i {
fill(0x00);
for (x=0;x<4;x++)
for(y=0;y<4;y++)
{
// x+y*4 gives no. from 0-15 for sqrt_LUT
distance=sqrt_LUT[x+y*4];// distance is 0-50 roughly
// height is sin of distance + iteration*4
//height=4+totty_sin(LUT,distance+i)/52;
height=(196+totty_sin(LUT,distance+i))/49;
// Use 4-way mirroring to save on calculations
setvoxel(x,y,height);
setvoxel(7-x,y,height);
setvoxel(x,7-y,height);
setvoxel(7-x,7-y,height);
setvoxel(x,y,7-height);
setvoxel(7-x,y,7-height);
setvoxel(x,7-y,7-height);
setvoxel(7-x,7-y,7-height);

}
delay_ms(delay);
}
}

void effect_axis_updown_randsuspend (char axis, int delay, int sleep, int invert)
{
unsigned char positions[64];
unsigned char destinations[64];

int i,px;

// Set 64 random positions
for (i=0; i<64; i++)
{
positions[i] = 0; // Set all starting positions to 0
destinations[i] = rand()%8;
}

// Loop 8 times to allow destination 7 to reach all the way
for (i=0; i<8; i++)
{
// For every iteration, move all position one step closer to their destination
for (px=0; px<64; px++)
{
if (positions[px] {
positions[px]++;
}
}
// Draw the positions and take a nap
draw_positions_axis (axis, positions,invert);
delay_ms(delay);
}

// Set all destinations to 7 (opposite from the side they started out)
for (i=0; i<64; i++)
{
destinations[i] = 7;
}

// Suspend the positions in mid-air for a while
delay_ms(sleep);

// Then do the same thing one more time
for (i=0; i<8; i++)
{
for (px=0; px<64; px++)
{
if (positions[px] {
positions[px]++;
}
if (positions[px]>destinations[px])
{
positions[px]--;
}
}
draw_positions_axis (axis, positions,invert);
delay_ms(delay);
}
}

void side_ripples(int iterations, int delay)
{
// 16 values for square root of a^2+b^2. index a*4+b = 10*sqrt
// This gives the distance to 3.5,3.5 from the point
unsigned char sqrt_LUT[]={49,43,38,35,43,35,29,26,38,29,21,16,35,25,16,7};
//LUT_START // Macro from new tottymath. Commented and replaced with full code
unsigned char LUT[65];
init_LUT(LUT);
int i;
unsigned char x,y,height,distance;
for (i=0;i {
fill(0x00);
for (x=0;x<4;x++)
for(y=0;y<4;y++)
{
// x+y*4 gives no. from 0-15 for sqrt_LUT
distance=sqrt_LUT[x+y*4];// distance is 0-50 roughly
// height is sin of distance + iteration*4
//height=4+totty_sin(LUT,distance+i)/52;
height=(196+totty_sin(LUT,distance+i))/49;
// Use 4-way mirroring to save on calculations
setvoxel(x,height,y);
setvoxel(7-x,height,y);
setvoxel(x,height,7-y);
setvoxel(7-x,height,7-y);
setvoxel(x,7-height,y);
setvoxel(7-x,7-height,y);
setvoxel(x,7-height,7-y);
setvoxel(7-x,7-height,7-y);

}
delay_ms(delay);
}
}

// blink 1 random voxel, blink 2 random voxels..... blink 20 random voxels
// and back to 1 again.
void effect_random_sparkle (void)
{
int i;

for (i=1;i<20;i++)
{
effect_random_sparkle_flash(5,i,200);
}

for (i=20;i>=1;i--)
{
effect_random_sparkle_flash(5,i,200);
}

}

void quad_ripples(int iterations, int delay)
{
// 16 values for square root of a^2+b^2. index a*4+b = 10*sqrt
// This gives the distance to 3.5,3.5 from the point
unsigned char sqrt_LUT[]={49,43,38,35,43,35,29,26,38,29,21,16,35,25,16,7};
//LUT_START // Macro from new tottymath. Commented and replaced with full code
unsigned char LUT[65];
init_LUT(LUT);
int i;
unsigned char x,y,height,distance;
for (i=0;i {
fill(0x00);
for (x=0;x<4;x++)
for(y=0;y<4;y++)
{
// x+y*4 gives no. from 0-15 for sqrt_LUT
distance=sqrt_LUT[x+y*4];// distance is 0-50 roughly
// height is sin of distance + iteration*4
//height=4+totty_sin(LUT,distance+i)/52;
height=(196+totty_sin(LUT,distance+i))/49;
// Use 4-way mirroring to save on calculations
setvoxel(x,y,height);
setvoxel(7-x,y,height);
setvoxel(x,7-y,height);
setvoxel(7-x,7-y,height);
setvoxel(x,y,7-height);
setvoxel(7-x,y,7-height);
setvoxel(x,7-y,7-height);
setvoxel(7-x,7-y,7-height);
setvoxel(x,height,y);
setvoxel(7-x,height,y);
setvoxel(x,height,7-y);
setvoxel(7-x,height,7-y);
setvoxel(x,7-height,y);
setvoxel(7-x,7-height,y);
setvoxel(x,7-height,7-y);
setvoxel(7-x,7-height,7-y);


}
delay_ms(delay);
}
}

// ==========================================================================================
// Draw functions
// ==========================================================================================


// Set a single voxel to ON (or)
void setvoxel(int x, int y, int z)
{
if (inrange(x,y,z))
cube[z][y] |= (1 << x);
}


// Set a single voxel to ON (and)
void clrvoxel(int x, int y, int z)
{
if (inrange(x,y,z))
cube[z][y] &= ~(1 << x);
}



// This function validates that we are drawing inside the cube.
unsigned char inrange(int x, int y, int z)
{
if (x >= 0 && x < 8 && y >= 0 && y < 8 && z >= 0 && z < 8)
{
return 0x01;
} else
{
// One of the coordinates was outside the cube.
return 0x00;
}
}

// Get the current status of a voxel
unsigned char getvoxel(int x, int y, int z)
{
if (inrange(x,y,z))
{
if (cube[z][y] & (1 << x))
{
return 0x01;
} else
{
return 0x00;
}
} else
{
return 0x00;
}
}

// In some effect we want to just take bool and write it to a voxel
// this function calls the apropriate voxel manipulation function.
void altervoxel(int x, int y, int z, int state)
{
if (state == 1)
{
setvoxel(x,y,z);
} else
{
clrvoxel(x,y,z);
}
}

// Flip the state of a voxel.
// If the voxel is 1, its turned into a 0, and vice versa.
void flpvoxel(int x, int y, int z)
{
if (inrange(x, y, z))
cube[z][y] ^= (1 << x);
}

// Makes sure x1 is alwas smaller than x2
// This is usefull for functions that uses for loops,
// to avoid infinite loops
void argorder(int ix1, int ix2, int *ox1, int *ox2)
{
if (ix1>ix2)
{
int tmp;
tmp = ix1;
ix1= ix2;
ix2 = tmp;
}
*ox1 = ix1;
*ox2 = ix2;
}

// Sets all voxels along a X/Y plane at a given point
// on axis Z
void setplane_z (int z)
{
int i;
if (z>=0 && z<8)
{
for (i=0;i<8;i++)
cube[z][i] = 0xff;
}
}

// Clears voxels in the same manner as above
void clrplane_z (int z)
{
int i;
if (z>=0 && z<8)
{
for (i=0;i<8;i++)
cube[z][i] = 0x00;
}
}

void setplane_x (int x)
{
int z;
int y;
if (x>=0 && x<8)
{
for (z=0;z<8;z++)
{
for (y=0;y<8;y++)
{
cube[z][y] |= (1 << x);
}
}
}
}

void clrplane_x (int x)
{
int z;
int y;
if (x>=0 && x<8)
{
for (z=0;z<8;z++)
{
for (y=0;y<8;y++)
{
cube[z][y] &= ~(1 << x);
}
}
}
}

void setplane_y (int y)
{
int z;
if (y>=0 && y<8)
{
for (z=0;z<8;z++)
cube[z][y] = 0xff;
}
}

void clrplane_y (int y)
{
int z;
if (y>=0 && y<8)
{
for (z=0;z<8;z++)
cube[z][y] = 0x00;
}
}

void setplane (char axis, unsigned char i)
{
switch (axis)
{
case AXIS_X:
setplane_x(i);
break;

case AXIS_Y:
setplane_y(i);
break;

case AXIS_Z:
setplane_z(i);
break;
}
}

void clrplane (char axis, unsigned char i)
{
switch (axis)
{
case AXIS_X:
clrplane_x(i);
break;

case AXIS_Y:
clrplane_y(i);
break;

case AXIS_Z:
clrplane_z(i);
break;
}
}

// Fill a value into all 64 byts of the cube buffer
// Mostly used for clearing. fill(0x00)
// or setting all on. fill(0xff)
void fill (unsigned char pattern)
{
int z;
int y;
for (z=0;z<8;z++)
{
for (y=0;y<8;y++)
{
cube[z][y] = pattern;
}
}
}



// Draw a box with all walls drawn and all voxels inside set
void box_filled(int x1, int y1, int z1, int x2, int y2, int z2)
{
int iy;
int iz;

argorder(x1, x2, &x1, &x2);
argorder(y1, y2, &y1, &y2);
argorder(z1, z2, &z1, &z2);

for (iz=z1;iz<=z2;iz++)
{
for (iy=y1;iy<=y2;iy++)
{
cube[iz][iy] |= byteline(x1,x2);
}
}

}

// Darw a hollow box with side walls.
void box_walls(int x1, int y1, int z1, int x2, int y2, int z2)
{
int iy;
int iz;

argorder(x1, x2, &x1, &x2);
argorder(y1, y2, &y1, &y2);
argorder(z1, z2, &z1, &z2);

for (iz=z1;iz<=z2;iz++)
{
for (iy=y1;iy<=y2;iy++)
{
if (iy == y1 || iy == y2 || iz == z1 || iz == z2)
{
cube[iz][iy] = byteline(x1,x2);
} else
{
cube[iz][iy] |= ((0x01 << x1) | (0x01 << x2));
}
}
}

}

// Draw a wireframe box. This only draws the corners and edges,
// no walls.
void box_wireframe(int x1, int y1, int z1, int x2, int y2, int z2)
{
int iy;
int iz;

argorder(x1, x2, &x1, &x2);
argorder(y1, y2, &y1, &y2);
argorder(z1, z2, &z1, &z2);

// Lines along X axis
cube[z1][y1] = byteline(x1,x2);
cube[z1][y2] = byteline(x1,x2);
cube[z2][y1] = byteline(x1,x2);
cube[z2][y2] = byteline(x1,x2);

// Lines along Y axis
for (iy=y1;iy<=y2;iy++)
{
setvoxel(x1,iy,z1);
setvoxel(x1,iy,z2);
setvoxel(x2,iy,z1);
setvoxel(x2,iy,z2);
}

// Lines along Z axis
for (iz=z1;iz<=z2;iz++)
{
setvoxel(x1,y1,iz);
setvoxel(x1,y2,iz);
setvoxel(x2,y1,iz);
setvoxel(x2,y2,iz);
}

}

unsigned char bitswap (unsigned char x)//Reverses a byte (so letters aren't backwards);
{ byte result;

asm("mov __tmp_reg__, %[in] \n\t"
"lsl __tmp_reg__ \n\t" /* shift out high bit to carry */
"ror %[out] \n\t" /* rotate carry __tmp_reg__to low bit (eventually) */
"lsl __tmp_reg__ \n\t" /* 2 */
"ror %[out] \n\t"
"lsl __tmp_reg__ \n\t" /* 3 */
"ror %[out] \n\t"
"lsl __tmp_reg__ \n\t" /* 4 */
"ror %[out] \n\t"

"lsl __tmp_reg__ \n\t" /* 5 */
"ror %[out] \n\t"
"lsl __tmp_reg__ \n\t" /* 6 */
"ror %[out] \n\t"
"lsl __tmp_reg__ \n\t" /* 7 */
"ror %[out] \n\t"
"lsl __tmp_reg__ \n\t" /* 8 */
"ror %[out] \n\t"

: [out] "=r" (result) : [in] "r" (x));
return(result);
}

// Returns a byte with a row of 1's drawn in it.
// byteline(2,5) gives 0b00111100
char byteline (int start, int end)
{
return ((0xff< }

// Flips a byte 180 degrees.
// MSB becomes LSB, LSB becomes MSB.
char flipbyte (char byte)
{
char flop = 0x00;

flop = (flop & 0b11111110) | (0b00000001 & (byte >> 7));
flop = (flop & 0b11111101) | (0b00000010 & (byte >> 5));
flop = (flop & 0b11111011) | (0b00000100 & (byte >> 3));
flop = (flop & 0b11110111) | (0b00001000 & (byte >> 1));
flop = (flop & 0b11101111) | (0b00010000 & (byte << 1));
flop = (flop & 0b11011111) | (0b00100000 & (byte << 3));
flop = (flop & 0b10111111) | (0b01000000 & (byte << 5));
flop = (flop & 0b01111111) | (0b10000000 & (byte << 7));
return flop;
}

// Draw a line between any coordinates in 3d space.
// Uses integer values for input, so dont expect smooth animations.
void line(int x1, int y1, int z1, int x2, int y2, int z2)
{
float xy; // how many voxels do we move on the y axis for each step on the x axis
float xz; // how many voxels do we move on the y axis for each step on the x axis
unsigned char x,y,z;
unsigned char lasty,lastz;

// We always want to draw the line from x=0 to x=7.
// If x1 is bigget than x2, we need to flip all the values.
if (x1>x2)
{
int tmp;
tmp = x2; x2 = x1; x1 = tmp;
tmp = y2; y2 = y1; y1 = tmp;
tmp = z2; z2 = z1; z1 = tmp;
}


if (y1>y2)
{
xy = (float)(y1-y2)/(float)(x2-x1);
lasty = y2;
} else
{
xy = (float)(y2-y1)/(float)(x2-x1);
lasty = y1;
}

if (z1>z2)
{
xz = (float)(z1-z2)/(float)(x2-x1);
lastz = z2;
} else
{
xz = (float)(z2-z1)/(float)(x2-x1);
lastz = z1;
}



// For each step of x, y increments by:
for (x = x1; x<=x2;x++)
{
y = (xy*(x-x1))+y1;
z = (xz*(x-x1))+z1;
setvoxel(x,y,z);
}

}

// Delay loop.
// This is not calibrated to milliseconds,
// but we had allready made to many effects using this
// calibration when we figured it might be a good idea
// to calibrate it.
void delay_ms(uint16_t x)
{
uint8_t y, z;
for ( ; x > 0 ; x--){
for ( y = 0 ; y < 90 ; y++){
for ( z = 0 ; z < 6 ; z++){
asm volatile ("nop");
}
}
}
}

void line_3d (int x1, int y1, int z1, int x2, int y2, int z2)
{
int i, dx, dy, dz, l, m, n, x_inc, y_inc, z_inc,
err_1, err_2, dx2, dy2, dz2;
int pixel[3];
pixel[0] = x1;
pixel[1] = y1;
pixel[2] = z1;
dx = x2 - x1;
dy = y2 - y1;
dz = z2 - z1;
x_inc = (dx < 0) ? -1 : 1;
l = abs(dx);
y_inc = (dy < 0) ? -1 : 1;
m = abs(dy);
z_inc = (dz < 0) ? -1 : 1;
n = abs(dz);
dx2 = l << 1;
dy2 = m << 1;
dz2 = n << 1;
if ((l >= m) && (l >= n)) {
err_1 = dy2 - l;
err_2 = dz2 - l;
for (i = 0; i < l; i++) {
//PUT_PIXEL(pixel);
setvoxel(pixel[0],pixel[1],pixel[2]);
//printf("Setting %i %i %i \n", pixel[0],pixel[1],pixel[2]);
if (err_1 > 0) {
pixel[1] += y_inc;
err_1 -= dx2;
}
if (err_2 > 0) {
pixel[2] += z_inc;
err_2 -= dx2;
}
err_1 += dy2;
err_2 += dz2;
pixel[0] += x_inc;
}
} else if ((m >= l) && (m >= n)) {
err_1 = dx2 - m;
err_2 = dz2 - m;
for (i = 0; i < m; i++) {
//PUT_PIXEL(pixel);
setvoxel(pixel[0],pixel[1],pixel[2]);
//printf("Setting %i %i %i \n", pixel[0],pixel[1],pixel[2]);
if (err_1 > 0) {
pixel[0] += x_inc;
err_1 -= dy2;
}
if (err_2 > 0) {
pixel[2] += z_inc;
err_2 -= dy2;
}
err_1 += dx2;
err_2 += dz2;
pixel[1] += y_inc;
}
} else {
err_1 = dy2 - n;
err_2 = dx2 - n;
for (i = 0; i < n; i++) {
setvoxel(pixel[0],pixel[1],pixel[2]);
//printf("Setting %i %i %i \n", pixel[0],pixel[1],pixel[2]);
//PUT_PIXEL(pixel);
if (err_1 > 0) {
pixel[1] += y_inc;
err_1 -= dz2;
}
if (err_2 > 0) {
pixel[0] += x_inc;
err_2 -= dz2;
}
err_1 += dy2;
err_2 += dx2;
pixel[2] += z_inc;
}
}
setvoxel(pixel[0],pixel[1],pixel[2]);
//printf("Setting %i %i %i \n", pixel[0],pixel[1],pixel[2]);
//PUT_PIXEL(pixel);
}

void init_LUT(unsigned char LUT[65])
{
unsigned char i;
float sin_of,sine;
for (i=0;i<65;i++)
{
sin_of=i*PI/64; // Just need half a sin wave
sine=sin(sin_of);
// Use 181.0 as this squared is <32767, so we can multiply two sin or cos without overflowing an int.
LUT[i]=sine*181.0;
}
}

int totty_sin(unsigned char LUT[65],int sin_of)
{
unsigned char inv=0;
if (sin_of<0)
{
sin_of=-sin_of;
inv=1;
}
sin_of&=0x7f; //127
if (sin_of>64)
{
sin_of-=64;
inv=1-inv;
}
if (inv)
return -LUT[sin_of];
else
return LUT[sin_of];
}

int totty_cos(unsigned char LUT[65],int cos_of)
{
unsigned char inv=0;
cos_of+=32;// Simply rotate by 90 degrees for COS
cos_of&=0x7f;//127
if (cos_of>64)
{
cos_of-=64;
inv=1;
}
if (inv)
return -LUT[cos_of];
else
return LUT[cos_of];
}

void effect_random_sparkle_flash (int iterations, int voxels, int delay)
{
int i;
int v;
for (i = 0; i < iterations; i++)
{
for (v=0;v<=voxels;v++)
setvoxel(rand()%8,rand()%8,rand()%8);

delay_ms(delay);
fill(0x00);
}
}

// Shift the entire contents of the cube along an axis
// This is great for effects where you want to draw something
// on one side of the cube and have it flow towards the other
// side. Like rain flowing down the Z axiz.
void shift (char axis, int direction)
{
int i, x ,y;
int ii, iii;
int state;

for (i = 0; i < 8; i++)
{
if (direction == -1)
{
ii = i;
} else
{
ii = (7-i);
}


for (x = 0; x < 8; x++)
{
for (y = 0; y < 8; y++)
{
if (direction == -1)
{
iii = ii+1;
} else
{
iii = ii-1;
}

if (axis == AXIS_Z)
{
state = getvoxel(x,y,iii);
altervoxel(x,y,ii,state);
}

if (axis == AXIS_Y)
{
state = getvoxel(x,iii,y);
altervoxel(x,ii,y,state);
}

if (axis == AXIS_X)
{
state = getvoxel(iii,y,x);
altervoxel(ii,y,x,state);
}
}
}
}

if (direction == -1)
{
i = 7;
} else
{
i = 0;
}

for (x = 0; x < 8; x++)
{
for (y = 0; y < 8; y++)
{
if (axis == AXIS_Z)
clrvoxel(x,y,i);

if (axis == AXIS_Y)
clrvoxel(x,i,y);

if (axis == AXIS_X)
clrvoxel(i,y,x);
}
}
}

Step 9: Programm (Game)

I wrote this part all by myself and changed it so many times that I almost got crazy.
You will find it in last step, and if you now it better please text me.
I know it’s not the finest work but it’s ok for me.

If you have some tips for me, or a new game or effect, or something, please text me.

Step 11: The final code

Have fun!

If you have any questions please aks, after you googled it.

If you have some tips for me, or a new game or effect, or something, please text me.

I noticed that the code is only found only on the http://www.instructables.com and not on .de page.

Anred Zynch

saleendvr6 months ago

Awesome design! I am thinking of a way i might be able to expand on this design with RGB LEDs so that I can control the color of each LED independently. I was thinking for the Invaders game that having the ship one color, the bullets being fired from the shit another color, and the enemy ships a third color would make the visualization of the game easier and cooler.

Any ideas as to how this might be accomplished? I have some theories, but I figure since you designed this much of the cube already then you probably know more about how to do this then I do lol

Thanks!

Bryan

Anred Zynch (author)  saleendvr6 months ago

I see some RBG Cubes on youtube.
Here is a sample it's arduino based:

The part with the controller you just need to copy.

But its going to be a huge project dude.

if you need specific help, or have any questions feel free to ask.

My RGB control board and LED base

CIMG3142.JPGF61VPIGHURHTMLO.jpg
skawikk7 months ago

It's amazing!:D

I'm wondering: can You add an effect like a waterfall? something like this:

http://designingsound.org/2013/07/unlimited-dialog...

for example: when i will listen music cube will have an mic or something to do an waterfall effect, like an equalizer, but in 3D?

sorry about my english;)

M.

My cube controllers now have music trigger input and take a mic module, and a 4 channel wireless remote module. All is controlled by the ATmega32A. No other PC or external processing is used. The new boards will be available for sale in March 2014. See demos on my instructable listed at the top of this instructable.

Whgoooooaaaa;D

Tthe SMT boards are ready. The through hole version is still in fabrication.

http://www.instructables.com/id/CHRs-8X8X8-LED-Cube-Revisited-with-improvements/step19/ANNOUNCING/

skawikk skawikk6 months ago

How does it work? Arduino hear such a song from the computer and converts it to visualize? Do you have preloaded song permanently? I let go of a radio and watch the waves at the cube to the rhythm of what's it going?

Anred Zynch (author)  skawikk7 months ago

Something like that?


Yes, I
think this is possible the cube can communicate over USB to a PC (with arduino
serial) I tested this and it work beside the interrupts. I only need a program
witch reed the audio and send the signals.

this is what my boards can do right now. I am adding more music effects soon.

WinAmp has an visulisation lugin with serial comunication. something like this:

and:

and:

http://forums.winamp.com/showthread.php?p=2956514

M.

Anred Zynch (author)  skawikk7 months ago

Ok,
I will test this as soon as possible. But need some time for other things.

hehe do not hurry;)
If you do, when you do it, my girlfriend will hate You:P

Because I will disappear for a week to soldering and testing .... ;)

M.

No external computer. Just music into the control board.

Absolutely fantastic work!

Azzurro8 months ago

Borg O_o

davest8 months ago

I was so excited to see this instructable...I've been wanting to make a project just like this! Unfortunately, I don't speak German. : / A translation (especially of the parts list) would be extremely helpful!

Anred Zynch (author)  davest8 months ago

I'll soon be done, but first the wiring diagram

Anred Zynch (author)  Anred Zynch8 months ago

done

deg15738 months ago

Congratulations Friend, is incredible..

lpots8 months ago

about how much this this cost?

Anred Zynch (author)  lpots8 months ago

honestly, I have no idea because I have very often rebuilt. I would appreciate so pi times thumb 350€.

Greasetattoo8 months ago

you should put a mirror behind it!
GREAT job!

Anred Zynch (author)  Greasetattoo8 months ago

and I should clean up my flat. By time i will do that. But this is no fun the Upload takes about 4 hours.

smac748 months ago
Great Job, I would love to try this myself but I think I should start with a smaller project first and build up to this slowly. Well done.
Anred Zynch (author)  smac748 months ago

yea, I wish I would have started with something small. Do it, and I recommend the arduino platform if you have no knowledge of micro controllers.

nejo00178 months ago

very nice 'ible! thanks for sharing!
i love your wired pcb :) reminds me on my highways of threaded copper years ago...
p.s.: the port manipulation 'digitalWrite(A0)' is implemented as 'digitalWrite(14)' or something like that; but i didn't use it for years...
great job, i hope to find the time for something like that!
my longTermGoal is such a cube or something like that: http://www.youtube.com/watch?v=DTb0k_P1wlY
best from berlin,
jo

Anred Zynch (author)  nejo00178 months ago

great link!

someday I will build by time someone like this

http://www.youtube.com/watch?v=EMvFMUCJxco

Excellent.
But, I wish I spoke German.
Perhaps someone will help you translate.
Thank you for posting your hard work.

Anred Zynch (author)  Ricardo Furioso8 months ago

Where did you get the biggest problems, then I translate there first.

tpobrienjr8 months ago

Nice project, very well done. Thanks for the videos.

Anred Zynch (author) 8 months ago

Thanks
to you all. And thanks to the free Pro account.

Es sieht schon! Sie konnen 3D-snake zu machen...

Anred Zynch (author)  Antzy Carmasaic8 months ago

This
was my first Idea, but I’ve seen it somewhere else

There it is: http://www.youtube.com/watch?v=OBjLsvXdw9o

Because that -> boring

Additional I don’t know how
to do multithreading beside the multiplexing.

goldenshuttle8 months ago

nice work indeed.

audreyobscura8 months ago

Good work!

Anred Zynch (author)  audreyobscura8 months ago

Thanks!