Ciao a tutti
Le vacanze estive in Germania stanno finendo e alcuni giovani talenti hanno sfruttato questo tempo libero per creare i propri progetti.
Oggi vogliamo Niklas Heinzel dare l'opportunità di presentare il suo progetto sul nostro blog. Niklas ha indossato il classico cubo LED e lo ha progettato e programmato completamente da zero:
Oggi vorrei presentarvi un nuovo entusiasmante progetto che ho realizzato a casa mia, un cubo LED nelle dimensioni 4x4x4.
Per questo utilizzo:
- 1 x Nano V3
- 4 transistor NPN 2n2222
- 4 resistori da 1k Ω
- 16 x 220Resistenze Ω
- 64 x LED blu diffusi (5mm)
- Porta micro USB
- LED giallo (SMD)
Per costruire il cubo LED:
Con tutti i 64 LED, l'anodo (sempre nello stesso punto) è piegato di 90 °. Questi vengono quindi portati al polo positivo.
Come si può vedere nella figura sopra, il cubo è costituito da un asse X-Y e 4 strati sovrapposti l'uno sull'altro. Lo strato inferiore ha il numero 0 e lo strato superiore ha il numero 3. Analogamente, i LED sono numerati come una matrice tridimensionale. Il LED in basso a sinistra si trova sul layer 0 (1,1). Il LED sopra è anche sullo strato 1 (1,1). Il LED giusto sul layer 0 (2,1) e così via. Tutti gli strati orizzontali sono i pin negativi dei LED saldati insieme.
Tutti i pin positivi dei LED sono trattati come colonne di questo cubo matrice. Quindi abbiamo 4 strati e 16 colonne che lo rendono 20 fili collegati ad Arduino. I pin (strati) positivi hanno resistori da 220 ohm.
Assemblare il cubo:
Per prima cosa abbiamo bisogno di un cartone o legno moderatamente spesso. Ora eseguiamo i fori in modo che venga creato un modello cubo 4 × 4 con la stessa spaziatura tra tutti i fori.
I fori da 5 mm (ogni foro è a 2,4 cm dal successivo (centro-centro)) sono stati praticati come modello per i LED.
Ora devi testare e preparare i tuoi LED. A questo scopo è possibile utilizzare una cella a bottone 3V. Prova tutti i LED in modo da non avere problemi in seguito!
Se vuoi che la luce fuoriesca da tutti i lati del LED, puoi disperdere la luce strofinando il guscio di plastica con carta vetrata.
Posizionare i LED nella confezione, ma prestare attenzione al loro orientamento. I pin positivi dei LED devono essere piegati e i pin negativi collegati come uno strato. Questo perché realizzeremo quattro di questi strati ed è facile saldarli insieme.
Ripetiamo questi strati 4x e li finiamo uno sopra l'altro, collegando tutti i + pin e posizionandoli uno sopra l'altro.
La scheda, pinout e connessioni:
nel mio caso ho scelto il seguente pinout per controllare il cubo come in una matrice:
È necessario effettuare queste connessioni e prestare attenzione anche alla scelta corretta dei pin, altrimenti l'animazione non verrà eseguita correttamente in seguito.
Ho progettato la scheda come segue e dovrei solo darti un'idea di come potrebbe essere il layout:
Scarica il circuito di collegamento
Tutto ciò che manca è il codice:
// LED Cube 1.0 // Niklas Heinzel //2019 int strato[4]={A3,A2,A1,A0}; // inizializzazione e dichiarazione di livelli led int colonna[16]={13,12,11,10,9,8,7,6,5,4,3,2,1,0,A5,A4}; // inizializzazione e dichiarazione di righe led int tempo = 250; vuoto configurazione() { per(int io = 0; io<16; io++) { pinMode(colonna[io], USCITA); // imposta le righe su output } per(int io = 0; io<4; io++) { pinMode(strato[io], USCITA); // imposta i layer sull'output } randomSeed(Leggi analogico(10)); // seeding random per pattern random } vuoto cappio() { turnEverythingOff(); flickerOn(); turnEverythingOn(); ritardo(tempo); turnOnAndOffAllByLayerUpAndDownNotTimed(); layerstompUpAndDown(); spiralInAndOut(); turnOnAndOffAllByColumnSideways(); ritardo(tempo); bordo intorno giù(); turnEverythingOff(); randomflicker(); randomRain(); diagonalRectangle(); goThroughAllLedsOneAtATime(); elica(); spiralInAndOut(); flickerOff(); turnEverythingOff(); ritardo(2000); } // spegni tutto vuoto turnEverythingOff() { per(int io = 0; io<16; io++) { digitalWrite(colonna[io], 1); } per(int io = 0; io<4; io++) { digitalWrite(strato[io], 0); } } // accendi tutto vuoto turnEverythingOn() { per(int io = 0; io<16; io++) { digitalWrite(colonna[io], 0); } // attivare i livelli per(int io = 0; io<4; io++) { digitalWrite(strato[io], 1); } } // disattiva le colonne vuoto turnColumnsOff() { per(int io = 0; io<16; io++) { digitalWrite(colonna[io], 1); } } // sfarfallio vuoto flickerOn() { int io = 150; mentre(io != 0) { turnEverythingOn(); ritardo(io); turnEverythingOff(); ritardo(io); io-= 5; } } // attiva e disattiva tutto per layer su e giù NON TEMPORIZZATO vuoto turnOnAndOffAllByLayerUpAndDownNotTimed() { int X = 75; per(int io = 5; io != 0; io--) { turnEverythingOn(); per(int io = 4; io!=0; io--) { digitalWrite(strato[io-1], 0); ritardo(X); } per(int io = 0; io<4; io++) { digitalWrite(strato[io], 1); ritardo(X); } per(int io = 0; io<4; io++) { digitalWrite(strato[io], 0); ritardo(X); } per(int io = 4; io!=0; io--) { digitalWrite(strato[io-1], 1); ritardo(X); } } } // attiva e disattiva tutto per colonna lateralmente vuoto turnOnAndOffAllByColumnSideways() { int X = 75; turnEverythingOff(); // attiva i livelli per(int io = 0; io<4; io++) { digitalWrite(strato[io], 1); } per(int y = 0; y<3; y++) { // attiva 0-3 per(int io = 0; io<4; io++) { digitalWrite(colonna[io], 0); ritardo(X); } // attiva 4-7 per(int io = 4; io<8; io++) { digitalWrite(colonna[io], 0); ritardo(X); } // attiva l'8-11 per(int io = 8; io<12; io++) { digitalWrite(colonna[io], 0); ritardo(X); } // attiva 12-15 per(int io = 12; io<16; io++) { digitalWrite(colonna[io], 0); ritardo(X); } // disattiva 0-3 per(int io = 0; io<4; io++) { digitalWrite(colonna[io], 1); ritardo(X); } // disattiva 4-7 per(int io = 4; io<8; io++) { digitalWrite(colonna[io], 1); ritardo(X); } // disattiva 8-11 per(int io = 8; io<12; io++) { digitalWrite(colonna[io], 1); ritardo(X); } // disattiva 12-15 per(int io = 12; io<16; io++) { digitalWrite(colonna[io], 1); ritardo(X); } // attiva 12-15 per(int io = 12; io<16; io++) { digitalWrite(colonna[io], 0); ritardo(X); } // attiva l'8-11 per(int io = 8; io<12; io++) { digitalWrite(colonna[io], 0); ritardo(X); } // attiva 4-7 per(int io = 4; io<8; io++) { digitalWrite(colonna[io], 0); ritardo(X); } // attiva 0-3 per(int io = 0; io<4; io++) { digitalWrite(colonna[io], 0); ritardo(X); } // disattiva 12-15 per(int io = 12; io<16; io++) { digitalWrite(colonna[io], 1); ritardo(X); } // disattiva 8-11 per(int io = 8; io<12; io++) { digitalWrite(colonna[io], 1); ritardo(X); } // disattiva 4-7 per(int io = 4; io<8; io++) { digitalWrite(colonna[io], 1); ritardo(X); } // disattiva 0-3 per(int io = 0; io<4; io++) { digitalWrite(colonna[io], 1); ritardo(X); } } } // su e giù per singolo strato stomp vuoto layerstompUpAndDown() { int X = 75; per(int io = 0; io<4; io++) { digitalWrite(strato[io], 0); } per(int y = 0; y<5; y++) { per(int contare = 0; contare<1; contare++) { per(int io = 0; io<4; io++) { digitalWrite(strato[io], 1); ritardo(X); digitalWrite(strato[io], 0); } per(int io = 4; io !=0; io--) { digitalWrite(strato[io-1], 1); ritardo(X); digitalWrite(strato[io-1], 0); } } per(int io = 0; io<4; io++) { digitalWrite(strato[io], 1); ritardo(X); } per(int io = 4; io!=0; io--) { digitalWrite(strato[io-1], 0); ritardo(X); } } } // sfarfallio vuoto flickerOff() { turnEverythingOn(); per(int io = 0; io!= 150; io+=5) { turnEverythingOff(); ritardo(io+50); turnEverythingOn(); ritardo(io); } } // attorno al bordo del cubo verso il basso vuoto aroundEdgeDown() { per(int X = 200; X != 0; X -=50) { turnEverythingOff(); per(int io = 4; io != 0; io--) { digitalWrite(strato[io-1], 1); digitalWrite(colonna[5], 0); digitalWrite(colonna[6], 0); digitalWrite(colonna[9], 0); digitalWrite(colonna[10], 0); digitalWrite(colonna[0], 0); ritardo(X); digitalWrite(colonna[0], 1); digitalWrite(colonna[4], 0); ritardo(X); digitalWrite(colonna[4], 1); digitalWrite(colonna[8], 0); ritardo(X); digitalWrite(colonna[8], 1); digitalWrite(colonna[12], 0); ritardo(X); digitalWrite(colonna[12], 1); digitalWrite(colonna[13], 0); ritardo(X); digitalWrite(colonna[13], 1); digitalWrite(colonna[15], 0); ritardo(X); digitalWrite(colonna[15], 1); digitalWrite(colonna[14], 0); ritardo(X); digitalWrite(colonna[14], 1); digitalWrite(colonna[11], 0); ritardo(X); digitalWrite(colonna[11], 1); digitalWrite(colonna[7], 0); ritardo(X); digitalWrite(colonna[7], 1); digitalWrite(colonna[3], 0); ritardo(X); digitalWrite(colonna[3], 1); digitalWrite(colonna[2], 0); ritardo(X); digitalWrite(colonna[2], 1); digitalWrite(colonna[1], 0); ritardo(X); digitalWrite(colonna[1], 1); } } } // sfarfallio casuale vuoto randomflicker() { turnEverythingOff(); int X = 10; per(int io = 0; io !=750; io+=2) { int randomLayer = casuale(0,4); int randomColumn = casuale(0,16); digitalWrite(strato[randomLayer], 1); digitalWrite(colonna[randomColumn], 0); ritardo(X); digitalWrite(strato[randomLayer], 0); digitalWrite(colonna[randomColumn], 1); ritardo(X); } } // pioggia casuale vuoto randomRain() { turnEverythingOff(); int X = 100; per(int io = 0; io!=60; io+=2) { int randomColumn = casuale(0,16); digitalWrite(colonna[randomColumn], 0); digitalWrite(strato[0], 1); ritardo(X+50); digitalWrite(strato[0], 0); digitalWrite(strato[1], 1); ritardo(X); digitalWrite(strato[1], 0); digitalWrite(strato[2], 1); ritardo(X); digitalWrite(strato[2], 0); digitalWrite(strato[3], 1); ritardo(X+50); digitalWrite(strato[3], 0); digitalWrite(colonna[randomColumn], 1); } } // rettangolo diagonale vuoto diagonalRectangle() { int X = 350; turnEverythingOff(); per(int contare = 0; contare<5; contare++) { //in alto a sinistra per(int io = 0; io<8; io++) { digitalWrite(colonna[io], 0); } digitalWrite(strato[3], 1); digitalWrite(strato[2], 1); ritardo(X); turnEverythingOff(); // medio centrale per(int io = 4; io<12; io++) { digitalWrite(colonna[io], 0); } digitalWrite(strato[1], 1); digitalWrite(strato[2], 1); ritardo(X); turnEverythingOff(); //in basso a destra per(int io = 8; io<16; io++) { digitalWrite(colonna[io], 0); } digitalWrite(strato[0], 1); digitalWrite(strato[1], 1); ritardo(X); turnEverythingOff(); // in basso al centro per(int io = 4; io<12; io++) { digitalWrite(colonna[io], 0); } digitalWrite(strato[0], 1); digitalWrite(strato[1], 1); ritardo(X); turnEverythingOff(); //in basso a sinistra per(int io = 0; io<8; io++) { digitalWrite(colonna[io], 0); } digitalWrite(strato[0], 1); digitalWrite(strato[1], 1); ritardo(X); turnEverythingOff(); // medio centrale per(int io = 4; io<12; io++) { digitalWrite(colonna[io], 0); } digitalWrite(strato[1], 1); digitalWrite(strato[2], 1); ritardo(X); turnEverythingOff(); //in alto a destra per(int io = 8; io<16; io++) { digitalWrite(colonna[io], 0); } digitalWrite(strato[2], 1); digitalWrite(strato[3], 1); ritardo(X); turnEverythingOff(); // in alto al centro per(int io = 4; io<12; io++) { digitalWrite(colonna[io], 0); } digitalWrite(strato[2], 1); digitalWrite(strato[3], 1); ritardo(X); turnEverythingOff(); } //in alto a sinistra per(int io = 0; io<8; io++) { digitalWrite(colonna[io], 0); } digitalWrite(strato[3], 1); digitalWrite(strato[2], 1); ritardo(X); turnEverythingOff(); } //elica vuoto elica() { turnEverythingOff(); int X = 90; per(int y = 4; y>0; y--) { per(int io = 0; io<6; io++) { // attiva il livello digitalWrite(strato[y-1], 1); // a1 turnColumnsOff(); digitalWrite(colonna[0], 0); digitalWrite(colonna[5], 0); digitalWrite(colonna[10], 0); digitalWrite(colonna[15], 0); ritardo(X); // b1 turnColumnsOff(); digitalWrite(colonna[4], 0); digitalWrite(colonna[5], 0); digitalWrite(colonna[10], 0); digitalWrite(colonna[11], 0); ritardo(X); // c1 turnColumnsOff(); digitalWrite(colonna[6], 0); digitalWrite(colonna[7], 0); digitalWrite(colonna[8], 0); digitalWrite(colonna[9], 0); ritardo(X); // d1 turnColumnsOff(); digitalWrite(colonna[3], 0); digitalWrite(colonna[6], 0); digitalWrite(colonna[9], 0); digitalWrite(colonna[12], 0); ritardo(X); // d2 turnColumnsOff(); digitalWrite(colonna[2], 0); digitalWrite(colonna[6], 0); digitalWrite(colonna[9], 0); digitalWrite(colonna[13], 0); ritardo(X); // d3 turnColumnsOff(); digitalWrite(colonna[1], 0); digitalWrite(colonna[5], 0); digitalWrite(colonna[10], 0); digitalWrite(colonna[14], 0); ritardo(X); } } // d4 turnColumnsOff(); digitalWrite(colonna[0], 0); digitalWrite(colonna[5], 0); digitalWrite(colonna[10], 0); digitalWrite(colonna[15], 0); ritardo(X); } // spirale dentro e fuori vuoto spiralInAndOut() { turnEverythingOn(); int X = 60; per(int io = 0; io<6; io++) { // spirale in senso orario digitalWrite(colonna[0], 1); ritardo(X); digitalWrite(colonna[1], 1); ritardo(X); digitalWrite(colonna[2], 1); ritardo(X); digitalWrite(colonna[3], 1); ritardo(X); digitalWrite(colonna[7], 1); ritardo(X); digitalWrite(colonna[11], 1); ritardo(X); digitalWrite(colonna[15], 1); ritardo(X); digitalWrite(colonna[14], 1); ritardo(X); digitalWrite(colonna[13], 1); ritardo(X); digitalWrite(colonna[12], 1); ritardo(X); digitalWrite(colonna[8], 1); ritardo(X); digitalWrite(colonna[4], 1); ritardo(X); digitalWrite(colonna[5], 1); ritardo(X); digitalWrite(colonna[6], 1); ritardo(X); digitalWrite(colonna[10], 1); ritardo(X); digitalWrite(colonna[9], 1); ritardo(X); // spirale in senso antiorario digitalWrite(colonna[9], 0); ritardo(X); digitalWrite(colonna[10], 0); ritardo(X); digitalWrite(colonna[6], 0); ritardo(X); digitalWrite(colonna[5], 0); ritardo(X); digitalWrite(colonna[4], 0); ritardo(X); digitalWrite(colonna[8], 0); ritardo(X); digitalWrite(colonna[12], 0); ritardo(X); digitalWrite(colonna[13], 0); ritardo(X); digitalWrite(colonna[14], 0); ritardo(X); digitalWrite(colonna[15], 0); ritardo(X); digitalWrite(colonna[11], 0); ritardo(X); digitalWrite(colonna[7], 0); ritardo(X); digitalWrite(colonna[3], 0); ritardo(X); digitalWrite(colonna[2], 0); ritardo(X); digitalWrite(colonna[1], 0); ritardo(X); digitalWrite(colonna[0], 0); ritardo(X); // spirale in senso antiorario digitalWrite(colonna[0], 1); ritardo(X); digitalWrite(colonna[4], 1); ritardo(X); digitalWrite(colonna[8], 1); ritardo(X); digitalWrite(colonna[12], 1); ritardo(X); digitalWrite(colonna[13], 1); ritardo(X); digitalWrite(colonna[14], 1); ritardo(X); digitalWrite(colonna[15], 1); ritardo(X); digitalWrite(colonna[11], 1); ritardo(X); digitalWrite(colonna[7], 1); ritardo(X); digitalWrite(colonna[3], 1); ritardo(X); digitalWrite(colonna[2], 1); ritardo(X); digitalWrite(colonna[1], 1); ritardo(X); digitalWrite(colonna[5], 1); ritardo(X); digitalWrite(colonna[9], 1); ritardo(X); digitalWrite(colonna[10], 1); ritardo(X); digitalWrite(colonna[6], 1); ritardo(X); // spirale in senso orario digitalWrite(colonna[6], 0); ritardo(X); digitalWrite(colonna[10], 0); ritardo(X); digitalWrite(colonna[9], 0); ritardo(X); digitalWrite(colonna[5], 0); ritardo(X); digitalWrite(colonna[1], 0); ritardo(X); digitalWrite(colonna[2], 0); ritardo(X); digitalWrite(colonna[3], 0); ritardo(X); digitalWrite(colonna[7], 0); ritardo(X); digitalWrite(colonna[11], 0); ritardo(X); digitalWrite(colonna[15], 0); ritardo(X); digitalWrite(colonna[14], 0); ritardo(X); digitalWrite(colonna[13], 0); ritardo(X); digitalWrite(colonna[12], 0); ritardo(X); digitalWrite(colonna[8], 0); ritardo(X); digitalWrite(colonna[4], 0); ritardo(X); digitalWrite(colonna[0], 0); ritardo(X); } } // passa attraverso tutti i led uno alla volta vuoto goThroughAllLedsOneAtATime() { int X = 15; turnEverythingOff(); per(int y = 0; y<5; y++) { //0-3 per(int contare = 4; contare != 0; contare--) { digitalWrite(strato[contare-1], 1); per(int io = 0; io<4; io++) { digitalWrite(colonna[io], 0); ritardo(X); digitalWrite(colonna[io], 1); ritardo(X); } digitalWrite(strato[contare-1], 0); } //4-7 per(int contare = 0; contare < 4; contare++) { digitalWrite(strato[contare], 1); per(int io = 4; io<8; io++) { digitalWrite(colonna[io], 0); ritardo(X); digitalWrite(colonna[io], 1); ritardo(X); } digitalWrite(strato[contare], 0); } //8-11 per(int contare = 4; contare != 0; contare--) { digitalWrite(strato[contare-1], 1); per(int io = 8; io<12; io++) { digitalWrite(colonna[io], 0); ritardo(X); digitalWrite(colonna[io], 1); ritardo(X); } digitalWrite(strato[contare-1], 0); } //12-15 per(int contare = 0; contare < 4; contare++) { digitalWrite(strato[contare], 1); per(int io = 12; io<16; io++) { digitalWrite(colonna[io], 0); ritardo(x); digitalWrite(colonna[io], 1); ritardo(x); } digitalWrite(strato[contare], 0); } } }
Una volta che il codice è stato caricato, puoi ammirare e aggiungere alle animazioni.
4 commenti
Niklas Heinzel
Die Platine kann bei mir erworben werden. Bei Interesse bitte an niklas-heinzel@gmx.de.
Niklas Heinzel
Die Platine kann erworben werden. Bei Interesse bitte an niklas-heinzel@gmx.de.
AxelF
Kann man die Platine, wie abgebildet, käuflich erwerben?
Ich kann sie nämlich nicht herunterladen.
Andreas K.
Hm… wie ist das mit der maximalen Strombelastung?
Ab 40mA pro Ausgangs-Pin bzw. 200mA in Summe auf allen Ausgangs-Pins (geht durch Masse bzw VCC) wird es beim 328 irgendwann kritisch.
Wenn alle LEDs leuchten, kommen mit den 220 Ohm Widerständens schon mal 300mA oder mehr zusammen, die dann insgesamt durch die Massepins fließen.
Wie lange macht der MC das mit?