Self-Contained 7x7x7 LED Cube

26 Schritt:Schritt 1: Kenntnisse erforderlich Schritt 2: wie es funktioniert! Schritt 3: Werkzeuge Schritt 4: Materialien Schritt 5: Machen Sie eine Prototype Schritt 6: Schaltpläne Schritt 7: Laser Cut die Lötschablone Schritt 8: Lötmittelschichten Schritt 9: Montieren Sie den Cube Schritt 10: Solder Flachbandkabel, um die Schichten Schritt 11: Solder Circuit Boards Schritt 12: Acrylic Box Schritt 13: Draht Alles zusammen Schritt 14: Software Intro Schritt 15: Programmübersicht Schritt 16: Koordinatensystem Schritt 17: Allon Schritt 18: CornerToCorner Schritt 19: CubeFrame Schritt 20: Fade Schritt 21: Ripple Schritt 22: Welle Schritt 23: PouringRain Schritt 24: BouncingBall Schritt 25: Feuerwerk Schritt 26: Emissionsspektrum

Self-Contained 7x7x7 LED Cube

LED-Würfel sind echte 3D-Displays, die durch Aufleuchten Punkte in einem 3D-Gitter LED-Arbeit.

Auf der 3D-Anzeige können Sie einige wirklich faszinierende Animationen zu erzeugen. Diese Instructable führt Sie durch die Schaffung eines LED Würfel für sich selbst das ist völlig in sich abgeschlossen und angetrieben von einem Arduino Mega gehen. Sobald Sie es programmiert ist, ist alles was Sie tun müssen, stecken Sie es in die Wand, und es wird angezeigt, was Sie es zu sagen! Dieser Würfel vermeidet die Komplikation der Multiplexer und verwendet stattdessen ein Arduino Mega zur direkten Steuerung Transistorschaltungen.

Ohne weitere Umschweife, hier ist ein Video des Würfels in Aktion:
(Zwar gibt es Einschränkungen, die ein 2D-Video einer 3D-Anzeige)



Wir werden, indem die physische Würfel beginnen und dann in die Programmierung es einzuschalten.

-----------------------------------------------------------------------------------------------------------------

Abgesehen davon, dass für Spaß, ist dieses Projekt ein Eintrag für das Make-to-Learn, Beleuchtung und Epilog Challenge-V Wettbewerbe. Ich würde wirklich zu schätzen Ihre Stimme!

** Bitte klicken Sie auf den orangefarbenen Abstimmung Band in der oberen rechten Ecke dieser Seite, wenn Sie genießen Sie diese Instructable. **
-----------------------------------------------------------------------------------------------------------------
Was würden Sie tun, wenn Sie die Epilog Zing Laser gewinnen gab?

My High School bekam ein Epilog Laser in diesem Jahr, und darauf hatte ich meine erste Erfahrung mit einem Laserschneider. Ich war sofort von, wie effektiv es war zu drehen Entwürfe in die Realität geschlagen.

Ich zum ersten Mal verwendet wird, im Dezember letzten Jahres zu kunstvollen Schneeflocke Weihnachtsschmuck aus Acryl und Holz, von denen einige in Bild 2 auf Schritt 12 abgebildet schneiden Nicht nur, dass sie mich inspirieren mich Illustrator lehren, aber die Ergebnisse waren sehr nett, und ich hoffe, um den Prozess in einem zukünftigen Instructable teilen. Ich ging auf die Laserschneider verwenden, um Stanford-Logo von klebrigen Filz schneiden, um die Spitze von meinem Abschlusskappe zu schmücken, sowie Acryl Untersetzer, Tischsets und die LED-Schicht-Vorlage die Box für dieses Projekt zu machen.

Leider, denn ich habe nun absolviert, ich habe Zugang zu dem Laserschneider verloren. Laserschneidanlagen besitzen die Genauigkeit, die Dinge, wäre im Wesentlichen unmöglich ist, auf andere Weise herzustellen, wie beispielsweise die radial-symmetrischen Linien auf den Schneeflockeverzierungen oder den punkt Löcher, die die Beine der LED Würfel durch den Deckel der Box ruhen lassen zu machen. Wenn ich den Epilog Laser gewinnen, würde ich weiterhin verwenden, um ordentlich Artikel zu zart und zu komplex, um nichts anderes gemacht werden zu fertigen. Kurz gesagt, ich würde gerne, um den Laser zu meinem Abenteuer des Lernens, wie Objekte mit computergesteuerten Maschinen zu erstellen weiterhin zu gewinnen.

-----------------------------------------------------------------------------------------------------------------
Hier sind meine Antworten auf den Wettbewerb Make-to-Learn Youth Contest Fragen:

Was haben Sie zu machen?

I gebaut und programmiert einen 7x7x7 LED Würfel von Grund auf neu. Die obige Beschreibung und der Rest der Instructable erzählen die Geschichte viel besser als in der kurzen Antwort auf eine Frage möglich. Deshalb finden Sie in den Rest der Instructable verweisen für eine vollständige Antwort auf diese Frage.

Wie haben Sie es geschafft?

Ich wurde ursprünglich von chr die Instructable (hier), die erste hat mich mit LED-Würfel und wie ordentlich sie inspiriert. Ich wollte eine LED-Würfel, der in sich geschlossene war zu machen -, dass man gerade in die Wand stecken und ausgeführt haben - und nicht eine, die von einem Computer eingegeben benötigt.

I kooptiert die Idee, die Beine der LEDs, um den Rahmen der Gitter, die die meisten anderen LED-Cubes verwenden bilden, aber ich kam mit dem Rest der physischen und Schaltungsdesign auf eigene Faust. Ich baute und montierte die gesamte Würfel von Grund auf neu. Einige der Routinen, die die Würfelläufe wurden durch chr inspiriert, aber ich den Code mit Unterrichten meiner Cousine zu Programm schrieb mich oder in Verbindung.

Der einzige große Änderung der Pläne hatte ich beim Aufbau des Würfels war es, ein Mega Arduino statt einer Due verwenden. Der Grund hat den Vorteil einer höheren Taktrate, aber ich erkannte, dass ich 5V für die digitalen Anschlussstifte in der Lage sein, um die Transistoren zu schalten voll in meiner Schaltung sein. Andernfalls würde der Spannungsabfall an den LEDs auf 2.6V anstatt 3,3V sie wurden bewertet verkappt sein.

Wo hast du es schaffen?

Ich habe den Großteil der Arbeit an diesem Projekt im Labor und Werkstatt an meiner High School, da dies war mein zweiter Semesterprojekt für meine Applied Science Research Klasse. Wir haben ein Laser-Cutter in unserem Schullabor, die ich verwendet, um schneiden Sie die Acryl-Box.

Ich habe etwas von dem Löten zu Hause als auch.

Was hast du gelernt?

Viel! Ich habe gelernt, Adobe Illustrator verwendet, um Dinge mit dem Laser-Cutter erstellen. In Bezug auf die Elektronik, kam ich, um wirklich zu verstehen, wie Transistoren arbeiten während der Arbeit an diesem Projekt, und es war mit Abstand die größten und komplexesten Stromkreis, den ich je entworfen haben. Auf der Seite der Programmierung, habe ich gelernt, wie man Zeiger und Speicherverwaltung verwenden, um den C ++ Code, der die Würfel steuert schreiben. Es war ordentlich, einen realen Anwendung des Polymorphismus zu sehen und über die virtuelle Schlüsselwort in C ++ zu lernen.

Allgemeiner gesagt, hat mich gelehrt, dieses Projekt den Wert der Bau einer kleineren Prototyp und die Macht der digitalen Schaltungen in Verbindung mit einem Mikroprozessor.

Mein Cousin war bei mir, während ich den Würfel Programmierung. Er hatte keine Programmiererfahrung, aber ich brachte ihm genug, dass mit etwas Hilfe konnte er zwei der acht Routinen, die auf dem Würfel angezeigt werden, zu schreiben. Mehr dazu im Programmierbereich!

Schritt 1: Kenntnisse erforderlich

  1. Self-Contained 7x7x7 LED Cube
    Die für dieses Projekt erforderlichen Fähigkeiten sind eigentlich ziemlich minimal; die meisten können auf dem Weg gelernt werden, zumal man plant, aus der Arbeit zu haben.

    Davon abgesehen, sollten Sie wirklich etwas Erfahrung mit Grundlagen der Elektronik und auch mit Löten, da dieses Projekt erfordert eine Menge davon.

    Meine Programme sollten für Sie aus dem Kasten heraus zu arbeiten, aber wenn Sie Ihre eigenen Anzeigeroutinen schreiben wollen, würden einige Erfahrung mit objektorientierter Programmierung in C ++ (Arduino) hilfreich sein.

Schritt 2: wie es funktioniert!

  1. Self-Contained 7x7x7 LED Cube
    In seiner einfachsten Form ist ein LED-Würfel eine dreidimensionale Anordnung der Leuchten im Raum, wobei jede Licht entweder an oder aus zu einem gegebenen Zeitpunkt. Die vollständige Kontrolle über diese Lichter zu erreichen, muss jede LED zu erscheinen, um individuell gesteuert werden.

    Dabei direkt, jedoch nicht möglich ist. Wenn x ist die Anzahl der LEDs auf jeder Seite der LED-Würfel, würden wir 3 x Digital-Ausgabe-Ports benötigen, um zu steuern jeweils einzeln LED. Dies könnte für kleinere Würfel arbeiten, aber für größere Werte von x, dies schnell die Anzahl der Ports direkt auf jedem Standard-Microcontroller zur Verfügung überschreitet. Aus diesem 7x7x7 Würfel, würde 343-Ports benötigt werden.

    Dieses Problem wird üblicherweise durch Flackern durch die Schichten der LED-Würfel schnell genug, um die Illusion der Lage zu kontrollieren, jeder unabhängig LED erzeugen gelöst. Lassen Sie uns an, wie dies die Anzahl der Ports benötigt reduzieren:

    In jeder Farbschicht auf dem Foto oben ist die Kathode (gegen Masse) Schenkel jedes LED verbunden. Die Anode (Spannung in) Beine aller LEDs in jeder Spalte angeschlossen sind. Ohne ins Detail noch davon aus, dass der Mikrocontroller anschließen und trennen Sie jede Spalte von Macht und jede Schicht vom Boden aus.

    Um etwas auf dem Würfel angezeigt werden, würden wir zuerst die rote Erde Schicht und gelten Spannung an den Säulen wir eingeschaltet werden soll. Dann würden wir alles trennen und wiederholen Sie den Vorgang für die Orange-Schicht, diesmal eine Spannung nur an den Säulen der LEDs wir in dieser Schicht leuchten soll.

    Durch schnelles Flackern durch die Schichten, wird jede Schicht scheint auf einmal beleuchtet werden. Die Flimmerverschmelzungsfrequenz Schwellen die Rate oberhalb dessen flackerndes Licht konstant erscheint, beim Menschen beträgt ca. 60 Hz, so dass die Würfel benötigt, um durch jede Schicht mindestens 60 mal pro Sekunde.

    Schalten der LEDs in Schichten und Spalten macht größere Würfel denkbar. Eine Gesamtzahl von x 2 + x digitale Ausgänge benötigt werden, um einen solchen Würfel steuern: x 2 für die Spalten und x für die Schichten. Deshalb, um einen 7x7x7-Würfel bauen, sind 56 Ports benötigt, anstatt 343. Das Arduino Mega hat 70 Pins, die als digitale I / O-Ports verwendet werden können, so dass 14-Anschlüsse für externe Druckschalter geöffnet, um das Muster zu wechseln auf angezeigt der Würfel.

Schritt 3: Werkzeuge

  1. Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Um die Elektronik tun müssen: Gut Lötkolben Patience Abisolierzange 2 Paar Spitzzange Augenschutz usw.
    Krokodilklemmen und eine Stromversorgung sind praktisch, da ist ein Ohmmeter zur Verbindungsüberprüfung.

    Ich habe ein Laserschneider, meine Acryl-Box zu bauen und um die Vorlage I zum Löten verwendet werden. Ich bin sicher, eine erfinderische Person könnte durch zu bekommen, ohne, aber der Laser-Cutter war enorm hilfreich.

    Sättel sind auch hilfreich, aber nicht notwendig.

    Wie immer, stellen Sie sicher wissen, wie man sicher mit einem Tool, bevor Sie es.

Schritt 4: Materialien

  1. Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Sie finden zu diesem Projekt benötigen:

    1x Arduino Mega
    --Die Gehirne unserer Projekt

    1000x 3mm diffus blaue LEDs
    ** Kaufen Sie diese off von eBay und stellen Sie sicher, um die diffuse Vielfalt zu erhalten. Sie werden sein
    viel billiger, dass Art und Weise (~ 25 €) und diffusem LEDs haben eine viel bessere
    Blickwinkel als normale LEDs.

    1x 5V Steckernetzstromversorgung
    --Dieser Wird die Stromversorgung des Projekts liefern.
    ** EBay ist ein großartiger Ort, um diese zu erhalten. Ich habe eine 2A, aber 1A sollte nur Arbeit
    Ordnung.

    1x DC weiblich Stromanschluss
    --get Leistung aus dem Steckernetzteil
    ** Achten Sie darauf, die Buchse Größe entspricht der Größe der Buchse am Netzteil
    Du kauftest. Wie hier .

    8x Drucktaster
    --user Eingang zu Programmen wechseln
    ** Ich habe mir bei Radioshack hier .

    1x Schalter bewertet, um die mindestens 1A, die durch ein Loch Halterungen
    --on / Aus-Schalter
    ** Ich habe ein DPDT-Schalter, aber auch andere Arten würde gut funktionieren.

    2x Prototype Foren
    ** Erhalten Sie diejenigen, die einige Löcher bereits angeschlossen haben. Es erspart Ihnen eine
    Menge Zeit. Ich habe mir hier .

    ~ Kopfstifte
    --Für Verbindungsleiterplatten und für den Anschluss von Flachbandkabel an den Arduino.
    ** Holen Sie sich ein Bündel von den männlichen Einsen und einige kleinere Fassungen wie die auf
    die Arduino.

    6ft 7+ Leiterbandkabel

    3ft 35+ Leiterbandkabel

    1pkg Klett
    --secure Platten im Inneren box

    53x 100Ω Widerstand

    53x 560Ω Widerstand

    9x 4.7kΩ Widerstand

    8x 10k Widerstand

    9x TIP31C NPN-Leistungstransistor
    --Für Schaltschichten

    53x 2N3904 NPN-Transistor
    --Für Schaltsäulen

    ~ 3ft 24 und 22 Gauge isolierten Draht

    1x Acrylic Sheet
    --Für Fall

    4x 3 "von 1/8" Schrauben aus rostfreiem Stahl mit Eichel-Kappen
    --Für Fall

    1x 1/8 "Spanplatten
    --Für Lötschablone

    1 Tonne Solder

    1x Tube of Epoxy

    2x männlich Schaltdrähte
    ** Könnte Draht und Kopfstifte ersetzen

    Die Gesamtkosten sollten irgendwo um 150 € sein.

Schritt 5: Machen Sie eine Prototype

  1. Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Es lohnt sich wirklich, einen Miniatur-Prototypen sicherzustellen, dass alles wie erwartet funktionieren zu machen.

    Ich baute ein 2x2x2-Würfel von 8 grüne LEDs, die herumlagen in der Schule und bekam es in einem spiralförmigen Muster leuchten. Ich werde nicht ins Detail gehen, da die verwendet werden, um den Prototyp zu bauen Methoden sind dieselben wie für die Haupt Würfel.

    Zumindest, bauen den Prototyp zu sehen, was Sie sich einlassen.

Schritt 6: Schaltpläne

  1. Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Der elektrische Schaltkreis muss drei Aufgaben erfüllen: Bereitstellung eines stabilen Gleichstromversorgung, so dass der Strom-sensitive, digitalen Ausgangs-Pins auf der Arduino, um die relativ hohe Ströme für die LEDs benötigt wechseln, und es dem Arduino zu erkennen, wenn die Routine Schalttasten gedrückt. Die Schaltpläne unten setzen sich diese drei verschiedene Aufgaben zu reflektieren gebrochen.

    Für die DC-Versorgung selbst, habe ich die Verwendung eines 5V, 2A Steckernetzstromversorgung, um die AC aus der Steckdose zu konvertieren. Wenn in der Steckdose, tatsächlich bietet es 5,4 V, aber die Arduino-internen Spannungsregler in der Lage ist, dass die Spannung bis auf den 5V es erfordert zu bringen. Tests mit einer variablen Spannungsleistungsversorgung festgestellt, dass das Arduino Mega weiterhin funktionieren, auch wenn nur 3,9 V versorgt wurde.

    Buchse des Steckernetz der Stecker in eine Netzanschluss durch ein Loch in der Acryl-Gehäuse. Wie im zweiten Diagramm dargestellt, die Leitungen auf dem Port zu einem Doppel-Pole, Umschalter, die Leistung leicht abgeschaltet werden von der Außenseite des Würfels, ohne die Netzbuchse entfernen können laufen. Die Strom- und Masseleitungen gehen Sie dann, um die Schaltungen Ansteuerung der LEDs Strom zu versorgen und zu den unregulierten Spannungseingang und Masse-Pins auf dem Arduino.

    Vor der Erörterung der zweiten Schaltung ist es notwendig, die Auswahl von LEDs für den Würfel erklären. Ich wählte 3mm diffus blaue LEDs, weil sie hell sind, geben Sie das Aussehen von einer Punktlichtquelle und haben eine bessere Blickwinkeln als nicht-diffuse LEDs. Die Vielfalt I erworben wurden entwickelt, um 3,3 V fallen und haben einen Strom von 20mA, indem sie ihnen einen effektiven Widerstand von 165 Ω.

    Die Transistorschaltung, die die Arduino Pins, um die Spalten und Schichten der Würfel umschalten können ist wesentlich komplexer. Eine abgekürzte Diagramm wird in dem ersten Bild dargestellt. Die 5V-Leitung von der Stromkreis bietet Läufe in dieser Schaltung. Die folgende Schaltung für jede Spalte wiederholt. Der 5V läuft zunächst einen 100Ω Widerstand, um die Spannung genug für die LED fallen zu lassen und um es in einer ausreichend niedrigen Niveau, das sie von dem 5V Arduino Stift gesteuert werden bringen. Der Strom dann in ein NPN-Transistor fließt, dessen Basis mit einem Arduino Ausgangsstift durch einen 560Ω Widerstand geschützt gesteuert.

    Strom fließt dann von dem Emitter des Transistors aus zu den Anoden der LEDs in dieser Spalte.

    Ein weiterer NPN-Transistor steuert die Erdung der jede der Schichten. Der Strom fließt aus dem Sammel Kathode für diese Schicht in den Kollektor des NPN-Transistors eines Strom. Der Strom durch diesen Transistor könnte 20mA * 49 = 0.98A, so ein Leistungstransistor benötigt entsprechen. A 4.7kΩ Widerstand schützt die Arduino Pin, der diesen Transistor steuert. Der Emitter des Transistors ist direkt mit Erde verbunden.

    Die endgültige Schaltung zum Erfassen, wenn die Druckknopfschalter auf der Außenseite der Acrylgehäuse gedrückt werden verwendet. Die Schaltung ist in dem letzten Bild schematisch dargestellt. Wenn der Druckknopf geöffnet ist, wird der digitale Eingangsanschluss durch den Widerstand geerdet. Wenn die Taste gedrückt wird, jedoch das digitale Eingangs wird am 5V aus der Arduino Spannungsregler sein. Dies ermöglicht es dem Mikrokontroller zu detektieren wobei der Knopf gedrückt wird, so dass er weiß, wann sie zu einem anderen Anzeigemodus wechseln.

Schritt 7: Laser Cut die Lötschablone

  1. Self-Contained 7x7x7 LED Cube
    Beginnen wir mit der LED Gitter zu starten.

    Um jede Schicht der LED Gitter löten, werden wir eine 2D-Vorlage benötigen. Messen Sie die kürzere Etappe der LEDs mit einem Paar von Bremssätteln, oder ersatzweise ein Lineal.

    Sie wollen, um eine Lochgitter genau das Abstand von Mitte zu Mitte Abstand zu machen. Die Löcher sollten die LEDs eng zu halten. Ich benutzte Illustrator und ein Laserschneider, um die Vorlage von 1/8 "Spanplatte erstellen, aber Sie könnten wahrscheinlich tun es mit einer Bohrmaschine.

    Stellen Sie sicher, dass die Löcher gehen den ganzen Weg durch das Material, um das Entfernen der LEDs erleichtern.

Schritt 8: Lötmittelschichten

  1. Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Für jede Schicht des Würfels, um eine perfekte 7x7 Array von LEDs machen mit ihren Kathoden verbunden wollen.

    Ich begann, indem LEDs in die Vorlage in L mit der Kathode Bein gebogen flach an der benachbarten LED. Die Kathoden wurden dann miteinander verlötet, und mehrere Reihen von LEDs wurden zu beginnen, um einen Kamm zu bilden, so beginnt sich in dem zweiten Bild dargestellt wird.

    Ich fügte dann mehrere Drähte zur Stärkung der "Kamm", wie im zweiten Bild gezeigt. Ich habe 24-Gauge-Kabel, um die Beine der LEDs am besten entsprechen. Um den Draht zu begradigen, ziehen Sie einfach an beiden Enden mit einer Zange und glätten jede Unebenheit mit Ihren Fingern. Die zusätzlichen Stützdrähte wurden am Ende und in der Mitte des Kammes aufgenommen (nicht abgebildet). Achten Sie darauf, keine Kurzschlüsse an den Anoden der LEDs haben.

    Schließlich sorgfältig poke jeweils aus der Vorlage, indem Sie von unten mit einem stumpfen Gegenstand LED.

    Wiederholen Sie diesen Vorgang für alle 7 Schichten.

    Nachdem Sie eine Schicht verlötet sind, ist es wert, weil, sobald es in den Würfel verlötet ist, gibt es keine Möglichkeit der Befestigung sein. Stellen Sie einfach Ihre Stromversorgung auf 5 Volt, schließen Sie die Kathoden durch einen 100Ω Widerstand an Masse und verbinden jede Anode mit 5V wiederum.

Schritt 9: Montieren Sie den Cube

  1. Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Der erste Schritt bei der Umsetzung der Schichten miteinander wird das Biegen der Spitzen der Anode Beine jeder LED in den unteren Schichten, um die LED über sie zu haken. Dann wurden die Holzdistanzstücke verwendet werden, um die nächste Schicht an Ort und Stelle stützen wie die gebogenen Anoden wurden auf der Basis der Anoden auf den LEDs über ihnen verlötet. Die Schichten wurden dann leicht, um sicherzustellen, daß jede Schicht war perfekt über einen darunter geschoben. Wiederholen dieses Prozesses siebenmal ergab die 7x7x7 LED Gitter.

    Schneiden Sie die Vorsprünge an den unteren Schenkel des Würfels und freuen Sie sich auf einen Job gut verlötet.

Schritt 10: Solder Flachbandkabel, um die Schichten

  1. Self-Contained 7x7x7 LED Cube
    Jede Schicht muss in absehbarer Zeit an die Leiterplatte angeschlossen werden, und Flachbandkabel ist der sauberste Weg, um das zu tun. Dazu wird ein Streifen aus Flachbandkabel an der hinteren linken Ecke des Würfels mit einem Draht gehen, um jede Schicht, wie gezeigt.

    Das Bild wurde von der Rückseite des Würfels gemacht.

Schritt 11: Solder Circuit Boards

  1. Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Mehr Löten!

    Die Transistorschaltungen Schalten der Spalten und Schichten und die Widerstände für die Tasten-Erfassungsschaltkreise an die Leiterplatten angelötet werden.

    Ich habe 35 der Spaltenschaltungen auf der unteren Platte 14 und auf dem oberen Bord. 7 Transistorschaltungen für die Schichten sind auf der oberen Platte, wie auch die Widerstände für die Drucktasten.

    Dann löten Kopf Stifte und Buchsen mit Masse und Macht zwischen den Platten zu verbinden.

Schritt 12: Acrylic Box

  1. Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Jetzt Laser schneiden Sie die Acryl-Box!

    Wenn Sie keinen Zugang zu einem Laserschneider, das ist okay. Es ist möglich, es gibt einen Ort, an einer TechShop beispielsweise und Online-Dienste, um zu bestellen Laserschneidteile vorhanden sind. Sie können aber wahrscheinlich ändern, eine vorgefertigte Gehäuse an Ihre Bedürfnisse anzupassen.

    In jedem Fall wird das Gehäuse benötigen, sind:
    --49 Öffnungen für die Beine der LEDs
    --Holes, Um den Schalter zu montieren
    -A Loch für den Arduino USB-Anschluss
    -A Loch für den Netzanschluss
    -A-Slot, um das Flachbandkabel, die Gründe die Schichten zugeben
    --Holes, Die ganze Sache zusammen verschrauben

    Ich habe die Illustrator-Dateien habe ich, wenn ich schneiden Sie die Box von 1/8 "Acryl befestigt. Die Unterseite der Box war identisch mit der Spitze, aber ohne die Löcher in der Mitte. Der Laserstrahl war gut genug, dass die Schnittspalt muss nicht korrigiert werden. Sie können bis zu Lochgrößen anpassen, wenn Sie Ihre Komponenten wurden verschiedenen Größen und von mir haben.

    Sobald die Box fertig ist, sorgfältig zu locken die Beine des Würfels in die Oberseite der Box. Es hilft, mit einer Seite beginnen und mit einem Bleistift, um die Beine an ihren Platz zu stoßen.

    Sorgfältig Epoxy die Macht Hafen, wo im Bild gezeigt.

Schritt 13: Draht Alles zusammen

  1. Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Alle 8 Artikel anzeigen
    Alle Schaltungen müssen nun mit Flachbandkabel angeschlossen werden.

    Ich begann, indem alle der Transistorschaltungen an den Arduino, um sicherzustellen, dass die Transistoren wurden den Arduino Pins in einer konsistenten Art und Weise verbunden. Ich entschied mich, es zu tun, oben nach unten, von links nach rechts. Dann verband ich die Schaltungen für die Drucktasten auf der Leiterplatte in die Arduino.

    Der schwierigste Teil ist das Flachbandkabel an den Kopfstiften geht in die Arduino Löten. Der mit Abstand einfachste Weg, dies zu tun ist, um die Stränge von jedem Draht um die Oberseite des Kopfstiftteil und dann drehen Sie sie auf der anderen Seite, Spann den Stift zwischen ihnen.

    Dann schrauben Sie alle Schalter durch die Acryl- und löten einer Seite all den Druckknopf zusammen schaltet. Löten Sie eine Hälfte eines männlichen Drahtbrücke zu. Dieser Draht wird in auf dem Arduino einem 5V Pin-Stecker an die Macht, um die Drucktaste Kreise versorgen. Löten einander Führung der Druckknöpfe mit einem Draht in einem Streifen aus Bandkabel.

    Als nächstes Lot Bandkabel an jedem Schenkel des LED Gitter unterhalb der Oberseite des Acryl-Box. Dies hält das Gitter fest. I verlötet über in Zeilen von links nach rechts, von vorne nach hinten, aus Gründen, die später klar werden wird. Sie können die Kabel in-Bild-Nummer 3 zu sehen.

    Dinge messy Löten des Würfels auf den Leiterplatten. Tun Sie es sorgfältig, entsprechend der ersten Transistorschaltung Sie auf die erste Spalte, gelötet, und es wird sich alles in Ordnung. Dann löten Sie das Bandkabel, die von den Drucktasten in die Taster Schaltkreise auf der Leiterplatte.

    Sie sind ganz nah dran! Schließlich löten Sie die Leitungen von der Stromanschluss an den Netzschalter. Führen Sie die Leitung von der Schalter auf der Leiterplatte anzutreiben und zu löten ein halb Schaltdrähte so die Macht in die Arduino gehen.

    Dann Velcro sich die Bretter in der Box, drücken Sie die Header-Stiften und Drahtbrücken in ihren Höhlen, und schrauben Sie die Box geschlossen. Die Hardware ist fertig!

Schritt 14: Software Intro

  1. Self-Contained 7x7x7 LED Cube
    Nun, da die Hardware fertig ist, lassen Sie uns die Würfel kommen lebendig!

    Ich habe eine ZIP-Datei von meinem ganzen Programm angeschlossen. Für diejenigen, die wollen einfach nur, um sie auszuführen, ziehen Sie die Inhalte der Bibliotheken Ordner in Ihrem Arduino Libraries Ordner, und ziehen Sie den Ordner in Ihrem LED_Cube Arduino-Ordner. Kompilieren und ausführen.

    Sie benötigen die neueste Version von Arduino (1.0.4) zu meinem Programm auszuführen. Andernfalls werden Sie Fehlermeldungen erhalten, dass die neue [] und delete [] Betreiber sind nicht definiert.

    Wenn Sie eine Taste drücken die ganze Würfel leuchtet auf, und wenn man loslassen, wird eine Anzeigeroutine beginnen. Dies könnte ein Feuerwerk-Simulation oder ein springenden Ball sein.

    Wenn ein oder mehrere Lichter nicht auf dem Würfel zu arbeiten, keine Panik. Für mich ein Lot kommen Sie auf die Gitter geknackt hatte. Finden Sie einfach die Pause mit einem Ohmmeter und reparieren mit dem Lötkolben.

Schritt 15: Programmübersicht

  1. Self-Contained 7x7x7 LED Cube
    Wenn Sie daran interessiert, wie das Programm funktioniert oder wie man seine eigene Anzeigeroutinen für den Cube zu schreiben sind, dann lesen Sie weiter.

    Für dieses Programm habe ich versucht, locker folgen dem Model-View-Controller-Paradigma. All das bedeutet, ist, dass ich halten die Informationen über das Modell - Informationen darüber, was der Staat sein sollte, und aktualisieren sie - getrennt von der Ansicht, dass die Informationen, die auf dem Würfel angezeigt. Der Haupt Arduino Skizze wirkt als Steuerung, Weitergabe von Informationen aus dem Modell zur Ansicht angezeigt wird.

    Wir werden schriftlich eine Menge von Klassen, um einen sauberen objektorientierten Programm zu machen. Arduino Angebote mit diesen Klassen-Bibliotheken. Bevor wir in das Hauptprogramm zu bekommen, werde ich über ein paar dieser Bibliotheken zu sprechen.

    Knopf drücken:

    Ein Druckknopf sich mit Eingaben aus den Druckschaltern auf der Vorderseite des Würfels. Sie sagen, dass es, was die Drucktaste Stift Stromkreis angeschlossen ist, und dann können Sie sie fragen, ob sie gedrückt oder freigegeben seit der letzten Kontrolle hat.

    Routine:

    Eine Routine-Objekt ist für die Berechnung, was die Würfel sollten Anzeigen in jedem Zug verantwortlich. Es wird immer wieder gesagt, um seinen Zustand auf der Grundlage der Höhe der Zeit, die vergangen ist, seit es zuletzt gesagt, zu aktualisieren zu aktualisieren. Wir können Routine zu erweitern und überschreiben Sie die Update-Methode, um neue Routinen für den Cube zu machen. Routinen halten auch eine 3D-Anordnung von booleans die den aktuellen Zustand des Würfels darstellt. Die Routine nicht die tatsächliche Anzeige der Anordnung auf dem Würfel zu tun. Das fällt auf die Würfelansicht.

    Würfelansicht:

    Ein Würfelansicht Griffe Anzeige eines 3D-Anordnung von Booleans (von der Routine) auf dem Würfel. Er tut dies, eine Schicht zu einer Zeit, Verschieben an die nächste Schicht jedes Mal, wenn Sie sagen, es zu zeigen.

    Jetzt für eine hohe Ansicht des Hauptprogramms:

    Das Hauptprogramm hält um einen Zeiger auf die Routine wir derzeit ausgeführt werden. In der Schleife () wir immer wieder sagen, die aktuelle Routine zu aktualisieren, kopieren Sie die neue Rahmen die Routine in eine lokale Variable erzeugt wird, und dann überprüfen Sie, ob es irgendeine Eingabe auf den Tasten. Wenn irgendwelche Tasten gedrückt wurden, wir löschen Sie die alte Routine und ersetzen Sie sie durch eine neue, die aufleuchtet, den ganzen Würfel. Wenn eine Taste losgelassen wird, wir löschen Sie die alte Routine und ersetzen sie durch eine neue Routine, die dieser Taste entspricht.

    Dieser Code wird immer wieder unterbrochen (420 mal pro Sekunde mit den aktuellen Einstellungen), um die nächste Schicht auf dem Würfel angezeigt werden soll. Hier geben wir nur das letzte Bild haben wir voll auf die Würfelansicht angezeigt werden berechnet. Mehr Informationen über Alarme finden Sie hier. Mit dem Anzeigeverfahren zu unterbrechen die anderen Code hält die Aktualisierungsrate unabhängig von der Rechenzeit und verhindert das Flackern.

    Wenn Sie Videos von einem Würfel Sie gebaut haben machen wollen, ändern Sie einfach die # define REFRESH_RATE so etwas wie 240, dass der Würfel Flash so schnell, dass die Kamera nicht abholen machen wird.

    Mehr über Routinen im nächsten Schritt:

     / **
     * LED_Cube
     *
     * Code für einen Mega, eine LED-Würfel steuern Arduino.  Ports 0-48 soll
     * Schalten Sie die Spalten, mit (0,0 bis 6) gehen, um Ports 0 bis 6,
     * (1,0 bis 6) los, um Anschlüsse 7 bis 13, usw.
     *
     * Ports A0 bis A6 steuern die Schichten mit A0 Steuerung z = 0 und A6
     * Steuerung z = 6.
     *
     * Ports A8 bis A15 dienen als Eingänge für den Druckschalter.
     *
     * Programm durch Lopuz3 geschrieben
     * Frühjahr 2013
     ** /
    
     #include <PushButton.h>
     #include <CubeView.h>
     #include <Routine.h>
     #include <AllOn.h>
     #include <CornerToCorner.h>
     #include <CubeFrame.h>
     #include <Fade.h>
     #include <Ripple.h>
     #include <Wave.h>
     #include <PouringRain.h>
     #include <BouncingBall.h>
     #include <Particle.h>
     #include <Firework.h>
    
     #define CUBE_SIZE 7
     #define NUM_BUTTONS 8
     #define REFRESH_RATE 60
    
     Pushbutton Tasten [NUM_BUTTONS];
     Würfelansicht cube = Würfelansicht ();
     Routine * currentRoutine = new Routine ();
    
     boolean lastCompleteFrame [CUBE_SIZE] [CUBE_SIZE] [CUBE_SIZE];
    
     Leere setup () 
     {
       setUpButtons ();
       setUpInterrupts ();
     }
    
     Leere setUpInterrupts ()
     {
       cli (); // Stop unterbricht, während wir stellen Sie sie
       // Bis ein Interrupt mit Timer 1 gesetzt
       TCCR1A = 0;
       TCCR1B = 0;
       TCNT1 = 0;
       // Stellen die Interrupt ocurr mit der richtigen Frequenz.  Die Frequenz ist REFRESH_RATE * CUBE_SIZE
       OCR1A = (16000000 / REFRESH_RATE / 1024 / CUBE_SIZE - 1);
       TCCR1B | = (1 << WGM12);
       // In den CS10 und CS12 Stellen so haben wir die 1024-
       TCCR1B | = (1 << CS12) | (1 << CS10);  
       TIMSK1 | = (1 << OCIE1A);
       sei (); // reallow Interrupts
     }
    
     Leere setUpButtons ()
     {
       für (byte i = 0; i <NUM_BUTTONS; i ++)
       {
         Tasten [i] = Taster (i + A8);
       }
     }
    
     // Genannt durch Timer-Interrupt
     ISR (TIMER1_COMPA_vect)
     {
       cube.displayLayer (lastCompleteFrame);
     }
    
     Leere Schleife () 
     {
       currentRoutine -> update (getTimeSinceLastFrameInMicros ());
       memcpy (& lastCompleteFrame, & currentRoutine -> cubeModel, sizeof (boolean) * * CUBE_SIZE CUBE_SIZE * CUBE_SIZE);
       getButtonInput ();
     }
    
     nichtig getButtonInput ()
     {
       if (anyButtonWasPressed ())
       {
         Löschen currentRoutine;
         currentRoutine = new Allon ();
       }
       if (Tasten [0] .wasReleased ())
       {
         Löschen currentRoutine;
         currentRoutine = new CornerToCorner ();
       }
       if (Tasten [1] .wasReleased ())
       {
         Löschen currentRoutine;
         currentRoutine = new CubeFrame ();
       }
       if (Tasten [2] .wasReleased ())
       {
         Löschen currentRoutine;
         currentRoutine = new Fade ();
       }
       if (Tasten [3] .wasReleased ())
       {
         Löschen currentRoutine;
         currentRoutine = new Ripple ();
       }
       if (Tasten [4] .wasReleased ())
       {
         Löschen currentRoutine;
         currentRoutine = new Welle ();
       }   
       if (Tasten [5] .wasReleased ())
       {
         Löschen currentRoutine;
         currentRoutine = new PouringRain ();
       }
       if (Tasten [6] .wasReleased ())
       {
         Löschen currentRoutine;
         currentRoutine = new BouncingBall ();
       }
       if (Tasten [7] .wasReleased ())
       {
         Löschen currentRoutine;
         currentRoutine = new Feuerwerk ();
       } 
     }
    
     boolean anyButtonWasPressed ()
     {
       für (byte i = 0; i <NUM_BUTTONS; i ++)
       {
         if (Tasten [i] .wasPressed ())
         {
           return true;
         }
       }
       return false;
     }
    
     / * Holen Sie sich die Zeit, die seit dem letzten Aufruf dieser Funktion in Mikrosekunden * /
     unsigned long getTimeSinceLastFrameInMicros ()
     {
       static unsigned long Lasttime = 0;
       unsigned long dt = micros () - Lasttime;
       Lasttime = micros ();
       zurück dt;
     }
    

     / **
     * PushButton.h
     *
     * Klasse auf eine Eingabe von einem Druckschalter zu steuern.
     *
     * Programm durch Lopuz3 geschrieben
     * Frühjahr 2013
     ** /
    
     #ifndef PushButton_h
     #define PushButton_h
    
     #include "Arduino.h"
    
     Klasse Pushbutton
     {
       Öffentlichkeit:
         Pushbutton (int-polig);
    	 Knopf drücken ();
         boolean isDown ();
    	 boolean wasPressed ();
         boolean wasReleased ();
       private:
         int _pin;
         boolean lastState;
     };
    
     #endif
    

     / **
     * Routine.h
     *
     * Basisklasse zur Einrichtung eines Modells für den Cube.
     *
     * Programm durch Lopuz3 geschrieben
     * Frühjahr 2013
     ** /
    
     #ifndef Routine_h
     #define Routine_h
    
     #define CUBE_SIZE 7
    
     #include "Arduino.h"
    
     Klasse Routine
     {
       Öffentlichkeit:
         Routine ();
    	 virtual ~ Routine ();
    	 virtual void update (unsigned long dt);
         boolean cubeModel [CUBE_SIZE] [CUBE_SIZE] [CUBE_SIZE];
     };
    
     #endif
    

     / **
     * CubeView.h
     *
     * Klasse, ein Modell auf dem Würfel angezeigt werden soll.
     *
     * Programm durch Lopuz3 geschrieben
     * Frühjahr 2013
     ** /
    
     #ifndef CubeView_h
     #define CubeView_h
    
     #define CUBE_SIZE 7
    
     #include "Arduino.h"
    
     Klasse Würfelansicht
     {
       Öffentlichkeit:
         Würfelansicht ();
    	 Leere Displaylayer (boolean Modell [CUBE_SIZE] [CUBE_SIZE] [CUBE_SIZE]);
       private:
    	 Byte currentLayer;
     };
    
     #endif
    

Schritt 16: Koordinatensystem

  1. Self-Contained 7x7x7 LED Cube
    Bevor wir uns um neue Erweiterungen der Routine, müssen wir ein Koordinatensystem definieren. Ich entschied mich für das oben abgebildete, denn es hielt den Standard 2D XY-Ebene für die Säulenschaltung, die über das Netz der Spalten einfacher für mich denken werden.

    Zu den booleschen entsprechend der LED bei (x, y, z) in einem 3D-Array zuzugreifen, wir cubeModel verwenden würden [x] [y] [z].

Schritt 17: Allon

  1. Self-Contained 7x7x7 LED Cube
    Jedes Mal, wenn wir ein neues Anzeigemuster für den Cube definieren wollen, müssen wir nur eine Klasse, die Routine zu schreiben erstreckt, und machen es zu einer Schaltfläche entsprechen im Hauptprogramm. Wenn Sie grundlegende Syntax für die Klassen in einer beliebigen Programmiersprache kennen, sollte es nicht schwer sein, zu lernen, wie man dies in C ++ zu tun, mit meiner Routinen als Modell.

    Legen Sie einfach Ihre .cpp und .h-Dateien in einem Ordner in Bibliotheken und man auf sie aus dem Hauptprogramm aufrufen können.

    Die einfachste Erweiterung der Routine ist es, alle Lichter auf, anstatt sie alle standardmäßig aktivieren. Dafür haben wir alle Koordinaten auf true im Konstruktor gerade gesetzt in unserem cubeModel.

     / **
     * AllOn.h
     *
     * Extention der Routine, um den gesamten Würfel leuchtet.
     *
     * Programm durch Lopuz3 geschrieben
     * Frühjahr 2013
     ** /
    
     #ifndef AllOn_h
     #define AllOn_h
    
     #include "Arduino.h"
     #include "Routine.h"
    
     Klasse Allon: public Routine
     {
       Öffentlichkeit:
    	 Allon ();
     };
    
     #endif
    


     / **
     * AllOn.cpp
     *
     * Extention der Routine, um den gesamten Würfel leuchtet.
     *
     * Programm durch Lopuz3 geschrieben
     * Frühjahr 2013
     ** /
    
     #include "Arduino.h"
     #include "AllOn.h"
    
     Allon :: Allon ()
     {
       für (Byte x = 0; x <CUBE_SIZE; x ++)
       {
         für (Byte y = 0; y <CUBE_SIZE; y ++)
         {
           für (Byte z = 0; z <CUBE_SIZE; Z ++)
           {
            cubeModel[x][y][z] = true ;
           }
         }
       }
     }
    

Step 18: CornerToCorner

  1. Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Alle 7 Artikel anzeigen
    In this extension of Routine I also overrode the update method, giving the cube behavior over time.

    The program starts by randomly choosing a vertex of the cube. Every step, the lights advance out from their starting vertex toward the opposing corner. When the light has filled the whole cube, it retreats away from the corner where it started. The routine then repeats with a new random corner.

    A simple rule tells the program to light a pixel: If the sum of the x, y and z distances is below a certain threshold, the pixel is lit. All other pixels remain off. The threshold is upped by one each step, and then the process is repeated in reverse to darken the cube.


    /**
    * CornerToCorner.h
     *
    * Extention of Routine to light up the cube starting at a corner.
     *
    * Program written by Lopuz3
    * Spring 2013
    **/
    
    #ifndef CornerToCorner_h
    #define CornerToCorner_h
    
    #define STEP_TIME 75000
    
    #include "Arduino.h"
    #include "Routine.h"
    
    class CornerToCorner : public Routine
     {
    	public :
    		CornerToCorner();
    		void update( unsigned long dt);
    	private :
    		unsigned long timeSinceLastStep;
    		int step;
    		boolean growing;
    		boolean xHigh, yHigh, zHigh;
     };
    
    #endif
    

    /**
    * CornerToCorner.cpp
     *
    * Extention of Routine to light up the cube starting at a corner.
     *
    * Program written by Lopuz3
    * Spring 2013
    **/
    
    #include "Arduino.h"
    #include "CornerToCorner.h"
    
    CornerToCorner :: CornerToCorner()
     {
    	timeSinceLastStep = 0 ;
    	step = 0 ;
    	growing = true ;
    	xHigh = random( 2 );
    	yHigh = random( 2 );
    	zHigh = random( 2 );
     }
    
    void CornerToCorner :: update( unsigned long dt)
     {	
    	timeSinceLastStep += dt;
    	if (timeSinceLastStep > STEP_TIME)
    	 {
    		if (growing)
    		 {
    			for (byte x = 0 ; x < CUBE_SIZE ; x ++ )
    			 {
    				for (byte y = 0 ; y < CUBE_SIZE ; y ++ )
    				 {
    					for (byte z = 0 ; z < CUBE_SIZE ; z ++ )
    					 {
    						int xDist = x;
    						if (xHigh)
    						{
    							xDist = CUBE_SIZE - x - 1 ;
    						 }
    						int yDist = y;
    						if (yHigh)
    						{
    							yDist = CUBE_SIZE - y - 1 ;
    						 }
    						int zDist = z;
    						if (zHigh)
    						{
    							zDist = CUBE_SIZE - z - 1 ;
    						 }
    						cubeModel[x][y][z] = (xDist + yDist + zDist <= step);
    					 }
    				 }
    			 }
    			step ++ ;
    			if (step > (CUBE_SIZE - 1 ) * 3 )
    			{
    				step = 0 ;
    				growing = false ;
    			 }
    		 }
    		else
    		{
    			for (byte x = 0 ; x < CUBE_SIZE ; x ++ )
    			{
    				for (byte y = 0 ; y < CUBE_SIZE ; y ++ )
    				{
    					for (byte z = 0 ; z < CUBE_SIZE ; z ++ )
    					{
    						int xDist = x;
    						if (xHigh)
    						{
    							xDist = CUBE_SIZE - x - 1 ;
    						 }
    						int yDist = y;
    						if (yHigh)
    						{
    							yDist = CUBE_SIZE - y - 1 ;
    						 }
    						int zDist = z;
    						if (zHigh)
    						{
    							zDist = CUBE_SIZE - z - 1 ;
    						 }
    						cubeModel[x][y][z] = ! (xDist + yDist + zDist <= step);
    					 }
    				 }
    			 }
    			step ++ ;
    			if (step > (CUBE_SIZE - 1 ) * 3 )
    			{
    				step = 0 ;
    				growing = true ;
    				xHigh = random( 2 );
    				yHigh = random( 2 );
    				zHigh = random( 2 );
    			 }
    		 }
    		timeSinceLastStep -= STEP_TIME;
    	 }
     }
    

Step 19: CubeFrame

  1. Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    This routine also starts with choosing a random vertex. This time the wire frame of a cube expands out of that corner before contracting back down. The process then repeats with a new corner.

    Again, a relatively simple rule allows us to decide whether a point is on the wire frame cube or not. At least two of the x, y, or z distances from the corner of must either be the current size or the cube or zero. The remaining distance must be less than the size of the cube.



    /**
    * CubeFrame.h
     *
    * Extention of Routine to expand and contract a wireframe of a cube.
     *
    * Program written by Lopuz3
    * Spring 2013
    **/
    
    #ifndef CubeFrame_h
    #define CubeFrame_h
    
    #define STEP_TIME 100000
    
    #include "Arduino.h"
    #include "Routine.h"
    
    class CubeFrame : public Routine
    {
    	public :
    		CubeFrame();
    		void update ( unsigned long dt);
    	private :
    		unsigned long timeSinceLastExpantion;
    		int wireframeSize;
    		boolean growing;
    		boolean xHigh, yHigh, zHigh;
     };
    
    #endif
    


    /**
    * CubeFrame.cpp
     *
    * Extention of Routine to expand and contract a wireframe of a cube.
     *
    * Program written by Lopuz3
    * Spring 2013
    **/
    
    #include "Arduino.h"
    #include "CubeFrame.h"
    
    CubeFrame :: CubeFrame()
    {
    	timeSinceLastExpantion = 0 ;
    	wireframeSize = 0 ;
    	growing = true ;
    	xHigh = random( 2 );
    	yHigh = random( 2 );
    	zHigh = random( 2 );
     }	
    
    void CubeFrame :: update ( unsigned long dt)
    {
    	timeSinceLastExpantion += dt;
    	if (timeSinceLastExpantion > STEP_TIME)
    	{
    		for (byte x = 0 ; x < CUBE_SIZE ; x ++ )
    		{
    			for (byte y = 0 ; y < CUBE_SIZE ; y ++ )
    			{
    				for (byte z = 0 ; z < CUBE_SIZE ; z ++ )
    				{
    					int xDist = x;
    					if (xHigh)
    					{
    						xDist = CUBE_SIZE - x - 1 ;
    					 }
    					int yDist = y;
    					if (yHigh)
    					{
    						yDist = CUBE_SIZE - y - 1 ;
    					 }
    					int zDist = z;
    					if (zHigh)
    					{
    						zDist = CUBE_SIZE - z - 1 ;
    					 }
    					if ( xDist < wireframeSize && yDist < wireframeSize && zDist < wireframeSize)
    					{
    						int count = 0 ;
    						if (xDist == 0 || xDist == wireframeSize - 1 )
    						{
    							count ++ ;
    						 }
    						if (yDist == 0 || yDist == wireframeSize - 1 )
    						{
    							count ++ ;
    						 }
    						if (zDist == 0 || zDist == wireframeSize - 1 )
    						{
    							count ++ ;
    						 }
    						
    						if (count >= 2 )
    						{
    							cubeModel[x][y][z] = true ;
    						 }
    						else
    						{
    							cubeModel[x][y][z] = false ;
    						 }
    					 }
    					else
    					{
    						cubeModel[x][y][z] = false ;
    					 }
    				 }
    			 }
    		 }
    		
    		if (wireframeSize == CUBE_SIZE)
    		{
    			growing = false ;
    		 }
    		if (wireframeSize == 0 )
    		{
    			growing = true ;
    			xHigh = random( 2 );
    			yHigh = random( 2 );
    			zHigh = random( 2 );
    		 }
    		if (growing)
    		{
    			wireframeSize ++ ;
    		 }
    		else
    		{
    			wireframeSize -- ;
    		 }
    		timeSinceLastExpantion -= STEP_TIME;
    	 }
     }
    

Step 20: Fade

  1. Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Here we randomly light up an unlit voxel (volumetric pixel) until the whole cube is lit. When that ocurrs, the voxels are then randomly turned back off, one by one.



    /**
    * Fade.h
     *
    * Extention of Routine randomly fade the cube in and out.
     *
    * Program written by Lopuz3
    * Spring 2013
    **/
    
    #ifndef Fade_h
    #define Fade_h
    
    #define STEP_TIME 20000
    
    #include "Arduino.h"
    #include "Routine.h"
    
    class Fade : public Routine
    {
    	public :
    		Fade();
    		void update( unsigned long dt);
    	private :
    		int numLeft;
    		unsigned long timeSinceLastStep;
    		boolean lighting;
     };
    
    #endif
    

    /**
    * Fade.cpp
     *
    * Extention of Routine randomly fade the cube in and out.
     *
    * Program written by Lopuz3
    * Spring 2013
    **/
    
    #include "Arduino.h"
    #include "Fade.h"
    
    Fade :: Fade()
    {
    	numLeft = CUBE_SIZE * CUBE_SIZE * CUBE_SIZE;
    	timeSinceLastStep = 0 ;
    	lighting = true ;
     }
    
    void Fade :: update( unsigned long dt)
    {
    	timeSinceLastStep += dt;
    	if (timeSinceLastStep > STEP_TIME)
    	{
    		int toToggle = random(numLeft);
    		int unchangedCounter = 0 ;
    		for (byte x = 0 ; x < CUBE_SIZE ; x ++ )
    		{
    			for (byte y = 0 ; y < CUBE_SIZE ; y ++ )
    			{
    				for (byte z = 0 ; z < CUBE_SIZE ; z ++ )
    				{
    					if (lighting != cubeModel[x][y][z])
    					{
    						if (unchangedCounter == toToggle)
    						{
    							cubeModel[x][y][z] = lighting;
    							numLeft -- ;
    						 }
    						unchangedCounter ++ ;
    					 }
    				 }
    			 }
    		 }
    		if (numLeft == 0 )
    		{
    			numLeft = CUBE_SIZE * CUBE_SIZE * CUBE_SIZE;
    			lighting = ! lighting;
    		 }
    		timeSinceLastStep -= STEP_TIME;
    	 }
     }
    

Step 21: Ripple

  1. Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Alle 7 Artikel anzeigen
    This routine shows a ripple calculated with trig functions. The height at each xy coordinate is a function of the sine of the distance from the center plus time.



    /**
    * Ripple.h
     *
    * Extention of Routine to display a ripple effect using the sin function.
     *
    * Program written by Lopuz3
    * Spring 2013
    **/
    
    #ifndef Ripple_h
    #define Ripple_h
    
    #include "Arduino.h"
    #include "Routine.h"
    
    class Ripple : public Routine
    {
    	public :
    		Ripple();
    		void update( unsigned long dt);
    	private :
    		float runTime;
     };
    #endif
    

    /**
    * Ripple.cpp
     *
    * Extention of Routine to display a ripple effect using the sin function.
     *
    * Program written by Lopuz3
    * Spring 2013
    **/
    
    #include "Arduino.h"
    #include "Ripple.h"
    
    Ripple :: Ripple()
    {
    	runTime = 0 ;
     }
    
    void Ripple :: update( unsigned long dt)
    {
    	runTime += 1.0 * dt / 1000000 ;
    
    	for (byte x = 0 ; x < CUBE_SIZE ; x ++ )
    	{
    		for (byte y = 0 ; y < CUBE_SIZE ; y ++ )
    		{
    			for (byte z = 0 ; z < CUBE_SIZE ; z ++ )
    			{
    				cubeModel[x][y][z] = false ;	
    			 }
    		 }
    	 }	
    	for (byte x = 0 ; x < CUBE_SIZE ; x ++ )
    	{
    		for (byte y = 0 ; y < CUBE_SIZE ; y ++ )
    		{
    			float cDist = sqrt(((x - 3 ) * (x - 3 )) + ((y - 3 ) * (y - 3 )));
    			
    			float zfloat = 3 * sin( .75 * cDist + 5 * runTime) + 3 ;
    		
    			int z = int (zfloat + .5 );
    		
    			cubeModel[x][y][z] = true ;
    		 }		
    	 }		
     }
    

Step 22: Wave

  1. Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    The routine again uses trig functions to trace out a wave through time. Again, disregarding constants, the height of each xy coordinate is a function of the sum of sin(x+time) + cos(y + time). Interestingly, there are lines of points through the cube that remain constant while the rest of the wave fluctuates.



    /**
    * Wave.h
     *
    * Extention of Routine to display a Wave effect using the sin function.
     *
    * Program written by Lopuz3
    * Spring 2013
    **/
    
    #ifndef Wave_h
    #define Wave_h
    
    #include "Arduino.h"
    #include "Routine.h"
    
    class Wave : public Routine
    {
    	public :
    		Wave();
    		void update( unsigned long dt);
    	private :
    		float runTime;
    		float fastSin( double x);
    		float fastCos( double x);
     };
    #endif
    

    /**
    * Wave.cpp
     *
    * Extention of Routine to display a Wave effect using the sin function.
     *
    * Program written by Lopuz3
    * Spring 2013
    **/
    
    #include "Arduino.h"
    #include "Wave.h"
    
    Wave :: Wave()
    {
    	runTime = 0 ;
     }
    
    void Wave :: update( unsigned long dt)
    {
    	runTime += 1.0 * dt / 1000000 ;
    
    	for (byte x = 0 ; x < CUBE_SIZE ; x ++ )
    	{
    		for (byte y = 0 ; y < CUBE_SIZE ; y ++ )
    		{
    			for (byte z = 0 ; z < CUBE_SIZE ; z ++ )
    			{
    				cubeModel[x][y][z] = false ;	
    			 }
    		 }
    	 }	
    	for (byte x = 0 ; x < CUBE_SIZE ; x ++ )
    	{
    		for (byte y = 0 ; y < CUBE_SIZE ; y ++ )
    		{			
    			float zfloat = 1.5 * sin( .75 * (x - 3 ) + 5 * runTime) + 1.5 * cos( .75 * (y - 3 ) + 5 * runTime) + 3 ;
    			int z = int (zfloat + .5 );
    		
    			cubeModel[x][y][z] = true ;
    		 }		
    	 }		
     }
    
    /**
    float Wave::fastSin(double x)
     {
     x = (int(100*x) % 628)*1.0/100;
     if(x > 4.71)
     {
     x-=6.28;
     }
     else if(x > 1.57)
     {
     x = 3.14-x;
     }
     return (x - x*x*x/6);
     }
    
    float Wave::fastCos(double x)
     {
     return fastSin(x + 1.57);
     }
    **/
    

Step 23: PouringRain

  1. Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Rain randomly pours down into the cube, piling up on the bottom.

    An unlit LED at the top of the cube is randomly chosen to become a drop. This drop then falls until it either hits the bottom of the cube or piles on top of a previously fallen drop. This process is repeated until the cube is full, at which point the routine repeats.



    /**
    * PouringRain.h
     *
    * Extention of Routine to display the cube filling up with rain.
     *
    * Program written by Lopuz3
    * Spring 2013
    **/
    
    #ifndef PouringRain_h
    #define PouringRain_h
    
    #define STEP_TIME 40000
    
    
    
    #include "Arduino.h"
    #include "Routine.h"
    
    class PouringRain : public Routine
    {
    	public :
    		PouringRain();
    		void update( unsigned long dt);
    	private :
    		unsigned long timeSinceLastStep;
    		boolean spawnDrop;
    		byte xCurrent;
    		byte yCurrent;
    		byte zCurrent;
     };
    #endif
    

    /**
    * PouringRain.cpp
     *
    * Extention of Routine to display the cube filling up with rain.
     *
    * Program written by Lopuz3
    * Spring 2013
    **/
    
    #include "Arduino.h"
    #include "PouringRain.h"
    
    PouringRain :: PouringRain()
    {
    	timeSinceLastStep = 0 ;
    	spawnDrop = true ;
     }
    
    void PouringRain :: update( unsigned long dt)
    {
    	timeSinceLastStep += dt;
    	
    	if (timeSinceLastStep > STEP_TIME)
    	{
    		if (spawnDrop)
    		{
    			byte lit = 0 ;
    			
    			for ( byte x = 0 ; x < CUBE_SIZE; x ++ )
    			{
    				for ( byte y = 0 ; y < CUBE_SIZE; y ++ )
    				{	
    					if (cubeModel[x][y][CUBE_SIZE - 1 ])
    					{
    						lit ++ ;
    						
    					 }
    				 }
    			 }
    			if (lit == CUBE_SIZE * CUBE_SIZE)
    			{
    				for (byte x = 0 ; x < CUBE_SIZE ; x ++ )
    				{
    					for (byte y = 0 ; y < CUBE_SIZE ; y ++ )
    					{
    						for (byte z = 0 ; z < CUBE_SIZE ; z ++ )
    						{
    							cubeModel[x][y][z] = false ;
    						 }
    					 }
    				 }
    				return ;
    			 }
    			byte randomIndex = random(CUBE_SIZE * CUBE_SIZE - lit);
    			
    			byte unlit = 0 ;
    			
    			for ( byte x = 0 ; x < CUBE_SIZE; x ++ )
    			{
    				for ( byte y = 0 ; y < CUBE_SIZE; y ++ )
    				{
    					if ( ! cubeModel[x][y][CUBE_SIZE - 1 ])
    					{
    						if (randomIndex == unlit)
    						{
    							cubeModel[x][y][CUBE_SIZE - 1 ] = true ;
    							xCurrent = x;
    							yCurrent = y;
    							zCurrent = CUBE_SIZE - 1 ;
    							spawnDrop = false ;
    						 }
    						unlit ++ ;
    					 }
    				 }
    			 }
    		 }
    		else
    		{
    			if (cubeModel[xCurrent][yCurrent][zCurrent - 1 ] || zCurrent == 0 )
    			{
    				spawnDrop = true ;
    			 }
    			else
    			{
    				cubeModel[xCurrent][yCurrent][zCurrent] = false ;
    				zCurrent -- ;
    				cubeModel[xCurrent][yCurrent][zCurrent] = true ;
    			 }
    		 }	
    		timeSinceLastStep -= STEP_TIME;
    	 }
     }	
    

Step 24: BouncingBall

  1. Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    This is a physics simulation of a ball bouncing inside the cube.

    To make this easier, I defined a particle class that simulates physics within some bounds. You initialize the particle with some radius, position, and velocity and tell it whether or not it should bounce. You can also apply acceleration and air resistance to the particle.

    This routine just creates a particle with radius 2 at a random position with random velocity, and takes snapshots of its position as it bounces about.



    /**
    * BouncingBall.h
     *
    * Extention of Routine to display a bouncing ball.
     *
    * Program written by Lopuz3
    * Spring 2013
    **/
    
    #ifndef BouncingBall_h
    #define BouncingBall_h
    
    #include "Arduino.h"
    #include "Routine.h"
    #include "Particle.h"
    
    class BouncingBall : public Routine
    {
    	public :
    		BouncingBall();		
    		~ BouncingBall();
    		void update( unsigned long dt);
    	private :
    		Particle * ball;
     };
    #endif
    

    /**
    * BouncingBall.cpp
     *
    * Extention of Routine to display a bouncing ball.
     *
    * Program written by Lopuz3
    * Spring 2013
    **/
    
    #include "Arduino.h"
    #include "BouncingBall.h"
    
    BouncingBall :: BouncingBall()
    {
    	ball = new Particle(random(CUBE_SIZE), random(CUBE_SIZE), CUBE_SIZE - 1 - 1 , random( 3 , 9 ), random( 3 , 9 ), 0 , true , 2 , CUBE_SIZE);
     }
    
    void BouncingBall :: update( unsigned long dt)
    {
    	float timeChange = 1.0 * dt / 1000000 ;
    	ball -> accelerateZ( - 15 , timeChange);
    	ball -> move(timeChange);
    	for (byte x = 0 ; x < CUBE_SIZE ; x ++ )
    	{
    		for (byte y = 0 ; y < CUBE_SIZE ; y ++ )
    		{
    			for (byte z = 0 ; z < CUBE_SIZE ; z ++ )
    			{
    				cubeModel[x][y][z] = false ;
    			 }
    		 }
    	 }
    	
    	for (byte x = 0 ; x < CUBE_SIZE ; x ++ )
    	{
    		for (byte y = 0 ; y < CUBE_SIZE ; y ++ )
    		{
    			for (byte z = 0 ; z < CUBE_SIZE ; z ++ )
    			{
    				cubeModel[x][y][z] = ball -> pointIsInSphere(x, y, z);
    			 }
    		 }
    	 }
     }	
    
    BouncingBall ::~ BouncingBall()
    {
    	delete ball;
     }
    

    /**
    * Particle.h
     *
    * Class to calculate the motion of a particle moving through space.
     *
    * Program written by Lopuz3
    * Spring 2013
    **/
    
    #ifndef Particle_h
    #define Particle_h
    
    #include "Arduino.h"
    
    class Particle
    {
    	public :
    		Particle( float x, float y, float z, float vX, float vY, float vZ, boolean bounces, float radius, int cubeSize);
    		Particle();
    		void move( float dt);
    		void accelerateZ( float aZ, float dt);
    		void accelerate( float aX, float aY, float aZ, float dt);
    		void drag( float coef, float dt);
    		int getRoundedX();
    		int getRoundedY();
    		int getRoundedZ();
    		boolean pointIsInSphere(byte x, byte y, byte z);
    	private :
    		float _x, _y, _z, _vX, _vY, _vZ;
    		float _radius;
    		boolean _bounces;
    		int _cubeSize;
     };
    #endif
    

Step 25: Firework

  1. Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    Self-Contained 7x7x7 LED Cube

    This time we use the flexibility of the particle class to simulate a firework!

    A particle is sent up in the center of the cube. When it gets to z=4, the particle is replaced with a random number of other particles. The particles are sent out with large, random velocities but are subject to a large amount of drag, just like in a real firework.

    These particles slide down the sides of the cube, disappearing just before they reach the ground.

    Then the process repeats with another firework.

    It's neat that you can run something this complicated just off an Arduino.



    /**
    * Firework.h
     *
    * Extention of Routine to simulate a firework.
     *
    * Program written by Lopuz3
    * Spring 2013
    **/
    
    #ifndef Firework_h
    #define Firework_h
    
    #include "Arduino.h"
    #include "Routine.h"
    #include "Particle.h"
    
    class Firework : public Routine
    {
    	public :
    		Firework();		
    		~ Firework();
    		void update( unsigned long dt);
    	private :
    		boolean exploded;
    		int numDebris;
    		Particle * rocket;
    		Particle * debris;
     };
    #endif
    

    /**
    * Firework.cpp
     *
    * Extention of Routine to simulate a firework.
     *
    * Program written by Lopuz3
    * Spring 2013
    **/
    
    #include "Arduino.h"
    #include "Firework.h"
    
    Firework :: Firework()
    {
    	exploded = false ;
    	rocket = new Particle(CUBE_SIZE / 2 , CUBE_SIZE / 2 , 0 , 0 , 0 , 10 , false , 0 , CUBE_SIZE);
    	debris = new Particle[ 0 ];
     }
    
    void Firework :: update( unsigned long dt)
    {
    	for (byte x = 0 ; x < CUBE_SIZE ; x ++ )
    	{
    		for (byte y = 0 ; y < CUBE_SIZE ; y ++ )
    		{
    			for (byte z = 0 ; z < CUBE_SIZE ; z ++ )
    			{
    				cubeModel[x][y][z] = false ;
    			 }
    		 }
    	 }
    	float timeChange = 1.0 * dt / 1000000 ;
    	if ( ! exploded)
    	{
    		rocket -> move(timeChange);
    		if (rocket -> getRoundedZ() >= 4 )
    		{
    			delete [] debris;
    			exploded = true ;
    			numDebris = random( 30 , 40 );
    			debris = new Particle[numDebris];
    			for (byte i = 0 ; i < numDebris ; i ++ )
    			{
    				debris[i] = Particle(CUBE_SIZE / 2 , CUBE_SIZE / 2 , 4 , random( - 10 , 11 ), random( - 10 , 11 ), random( 0 , 21 ), false , 0 , CUBE_SIZE);
    			 }
    		 }
    		cubeModel[rocket -> getRoundedX()][rocket -> getRoundedY()][rocket -> getRoundedZ()] = true ;
    	 }
    	else
    	{
    		byte visableCount = 0 ;
    		for (byte i = 0 ; i < numDebris ; i ++ )
    		{
    			debris[i].accelerateZ( - 15 , timeChange);
    			debris[i].drag( 0.05 , timeChange);
    			debris[i].move(timeChange);
    			if (debris[i].getRoundedZ() > 0 )
    			{
    				visableCount ++ ;
    				cubeModel[debris[i].getRoundedX()][debris[i].getRoundedY()][debris[i].getRoundedZ()] = true ;
    			 }
    		 }
    		if ( ! visableCount)
    		{
    			exploded = false ;
    			delete rocket;
    			rocket = new Particle(CUBE_SIZE / 2 , CUBE_SIZE / 2 , 0 , 0 , 0 , 10 , false , 0 , CUBE_SIZE);
    		 }
    	 }
     }	
    
    Firework ::~ Firework()
    {
    	delete rocket;
    	delete [] debris;
     }
    

Step 26: Emission Spectrum

  1. Self-Contained 7x7x7 LED Cube
    That's it for the actual construction and programming of the cube. You now have a fully functioning and self-contained LED cube that can be powered from a wall outlet!

    Out of interest, I performed one test on the LEDs in the cube. Using an emission spectrometer, I measured the intensity of the light being emitted by the blue LEDs at different wavelengths in an otherwise darkened room. The above is the graph of that data. The peak of 468 nm is a function of the bandgap of the LED and is consistant with zinc selenide, indium gallium nitride, and other common blue LED semiconductor materials.

    We've confirmed that the LEDs are indeed blue!

    Seriously, though, I hope you enjoyed reading about my cube and might be inspired to build one of your own. The 3D visual effects are even more amazing when not confined to to a 2D video.

    Again, I would really appreciate your vote for the contests I've entered. If you enjoyed reading, please click on the orange ribbon in the upper right-hand corner.