ws2122:game_of_light

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
ws2122:game_of_light [2022/04/10 18:17] – [Ergebnis] olethws2122:game_of_light [2022/04/10 20:34] (aktuell) – [Ergebnis] laraw
Zeile 10: Zeile 10:
   * Zellen mit genau 3 Nachbarn werden lebendig   * Zellen mit genau 3 Nachbarn werden lebendig
   * Zellen mit mehr als 3 Nachbarn sterben (an "Überbevölkerung")   * Zellen mit mehr als 3 Nachbarn sterben (an "Überbevölkerung")
 +
 +Durch diese Regeln gibt es bestimmte Muster, die statisch sind, wie z.B. 
 +{{ws2122:conway_stable2.png?100}}
 +und Muster, die periodisch wiederkehren, die wichtigsten darunter sind wohl die Glider  
 +{{ws2122:conway_glider.png?40}} \\
 +Daraus lassen sich faszinierende, komplexe Strukturen bauen, wie zum Beispiel [[https://www.youtube.com/watch?v=xP5-iIeKXE8&list=LL&index=17|hier]] oder [[https://www.youtube.com/watch?v=C2vgICfQawE&t=187s|hier]]. 
  
 <!-- wie viel noch zu stabilen Zuständen und Mustern? --> <!-- wie viel noch zu stabilen Zuständen und Mustern? -->
Zeile 31: Zeile 37:
 **Welcher Sensor?**: Um die Interaktivität zu gewährleisten, also direkt am Feld verschiedene Anfangsbedingungen einstellen zu können, brauchen wir eine Art Knopf. Ein simpler Druckknopf in jeder Zelle schien uns zu unhandlich, gerade bei größeren Feldern, deswegen haben wir uns letztendlich für eine Lösung mit einer Hall-Sonde (Magnetsensor) in jeder Zelle entschieden, sodass man den Lebensstatus der Zelle durch Berührung mit einem "Zauberstab" <!-- Link zu design Zauberstab --> (fancy Stab mit Magnet an der Spitze) geändert werden kann. Weitere Ideen, die wir vor allem auf Grund der Störanfälligkeit durch äußere Einflüsse verworfen haben, waren ein Kapazitätsberührungssensor und weiter Berührungssensoren, die über die Erschütterung einer kleinen Feder ausgelöst werden. **Welcher Sensor?**: Um die Interaktivität zu gewährleisten, also direkt am Feld verschiedene Anfangsbedingungen einstellen zu können, brauchen wir eine Art Knopf. Ein simpler Druckknopf in jeder Zelle schien uns zu unhandlich, gerade bei größeren Feldern, deswegen haben wir uns letztendlich für eine Lösung mit einer Hall-Sonde (Magnetsensor) in jeder Zelle entschieden, sodass man den Lebensstatus der Zelle durch Berührung mit einem "Zauberstab" <!-- Link zu design Zauberstab --> (fancy Stab mit Magnet an der Spitze) geändert werden kann. Weitere Ideen, die wir vor allem auf Grund der Störanfälligkeit durch äußere Einflüsse verworfen haben, waren ein Kapazitätsberührungssensor und weiter Berührungssensoren, die über die Erschütterung einer kleinen Feder ausgelöst werden.
 ===Zelldesign=== ===Zelldesign===
 +{{ :ws2122:schematic.png?nolink&300|}}
 Jede Zelle besteht aus einem 3D-gedruckten Zellkörper <!-- Link -->, der so gestaltet ist, dass man die Zellen einfach ineinander schieben kann und somit ein solides Feld erhält. darin müssen die Hall-Sonde, eine LED, ein Arduino Nano und einiges an Kabeln Platz finden, deswegen haben wir die Zellkörper 7cm tief gedruckt. \\ Jede Zelle besteht aus einem 3D-gedruckten Zellkörper <!-- Link -->, der so gestaltet ist, dass man die Zellen einfach ineinander schieben kann und somit ein solides Feld erhält. darin müssen die Hall-Sonde, eine LED, ein Arduino Nano und einiges an Kabeln Platz finden, deswegen haben wir die Zellkörper 7cm tief gedruckt. \\
-Die LED und die Hall-Sonde werden im ebenfalls 3D-gedruckten Deckel befestigt (s. Bild, das noch eingefügt werden muss), damit das Licht von außen gut sichtbar ist und alle Zellen einheitlich leuchten und ebenso einheitlich auf den Magneten reagieren. Außerdem gibt es Aussparungen für die Steckverbindungen der Kabel, die die Kommunikation der Zellen ermöglicht, im Deckel, sodass diese gut sichtbar sind und auch im zusammengesteckten Zustand leicht geändert werden können. Dies hat sowohl den praktischen Grund, dass es wohl die einfachst mögliche Lösung der Kommunikation ist, als auch pädagogische, denn so kann man im laufenden Betrieb eine Verbindung unterbrechen und darüber demonstrieren, wie die Zellen einander "sehen".+Die LED und die Hall-Sonde werden im ebenfalls 3D-gedruckten Deckel befestigt (s. Bild rechts), damit das Licht von außen gut sichtbar ist und alle Zellen einheitlich leuchten und ebenso einheitlich auf den Magneten reagieren. Außerdem gibt es Aussparungen für die Steckverbindungen der Kabel, die die Kommunikation der Zellen ermöglicht, im Deckel, sodass diese gut sichtbar sind und auch im zusammengesteckten Zustand leicht geändert werden können. Dies hat sowohl den praktischen Grund, dass es wohl die einfachst mögliche Lösung der Kommunikation ist, als auch pädagogische, denn so kann man im laufenden Betrieb eine Verbindung unterbrechen und darüber demonstrieren, wie die Zellen einander "sehen".
 Abgedeckt ist die 3d-gedruckte Deckelrahmenkonstruktion mit milchigem Acrylglas, das mit dem Laser-Cutter geschnitten wurde.  Abgedeckt ist die 3d-gedruckte Deckelrahmenkonstruktion mit milchigem Acrylglas, das mit dem Laser-Cutter geschnitten wurde. 
-Die Rückseite ist mit einem ebenfalls 3D-gedruckten Deckel verschlossen, in dem Aussparungen für die Stromverbindung (und Taktgebung?) sind.\\+Die Rückseite ist mit einem ebenfalls 3D-gedruckten Deckel verschlossen, in dem Aussparungen für die Stromverbindung (und Taktgebung) sind.\\
 Die 3D-gedruckten Teile wurden mit einem SLA-Drucker gedruckt, da dieser an sich genauer drucken kann als ein FDM-Drucker. Dadurch, dass die Teile nach dem Drucken aber gehärtet werden müssen, besteht bei unseren recht dünnen Wänden eine Neigung zum Neigen. Deswegen drucken wir die Teile doch lieber mit einem FDM-Drucker. Die 3D-gedruckten Teile wurden mit einem SLA-Drucker gedruckt, da dieser an sich genauer drucken kann als ein FDM-Drucker. Dadurch, dass die Teile nach dem Drucken aber gehärtet werden müssen, besteht bei unseren recht dünnen Wänden eine Neigung zum Neigen. Deswegen drucken wir die Teile doch lieber mit einem FDM-Drucker.
 ===Software=== ===Software===
Zeile 49: Zeile 56:
   - Nachbarn zählen (nach "Uhr")   - Nachbarn zählen (nach "Uhr")
   - je nach Anzahl der Nachbarn über eigenen Lebensstatus entscheiden   - je nach Anzahl der Nachbarn über eigenen Lebensstatus entscheiden
-Für Details und Code des Taktgebers siehe den __ordentlich__[[https://www.labprepare.tu-berlin.de/wiki/doku.php?id=ws2122:game_of_light#code| auskommentierten Code]].+Für Details und Code des Taktgebers siehe den __ordentlich__[[https://www.labprepare.tu-berlin.de/wiki/doku.php?id=ws2122:game_of_light#code| auskommentierten Code]].\\ 
 +\\ 
 +**Tipp:** Speist man mehreren verbundenen Arduinos nur über eine Verbindung zum Laptop, so kann es passieren, dass die Stromstärke zu gering ist und merkwürdiges, unerklärliches Verhalten entsteht, also die Stromversorgung besser über ein Netzteil regeln.
 ====Ergebnis==== ====Ergebnis====
-Die Fertige Zelle sieht am ende wie folgt aus{{ :ws2122:aussenansicht.jpeg?nolink&200|}}+Die fertige Zelle sieht am Ende wie folgt aus: \\ 
 +{{ :ws2122:aussenansicht.jpeg?nolink&200  |}}\\ 
 + 
 +Im Idealfall sollten deutlich kürzere Kabel verwendet werden, die dann an den Arduino gelötet werden, damit die Zellkörper nicht so vollgestopft werden. Darauf haben wir bis jetzt allerdings verzichtet, damit alle Materialien wiederverwendet werden können.\\ 
 +\\ 
 +{{ :ws2122:Innenansicht.jpeg?200 |}} 
 +\\  
 + 
 + 
 +Ein komplettes 3x3 Feld konnten wir noch nicht testen, da dafür noch Materialien fehlen, aber ein Test auf einem Steckbrett hat gezeigt, dass alles grundsätzlich funktioniert, wie es soll.\\
  
-Im Idealfall sollten deutlich kürzere Kabel verwendet werden, die dann an den Arduino gelötet werden, damit die Zellkörper nicht so vollgestopft werden. Darauf haben wir bis jetzt allerdings verzichtet damit alle Materialien wieder verwendet werden können. +{{ :ws2122:minitest.jpeg?nolink&300 |}}
-{{ :ws2122:Innenansicht.jpeg?nolink&200|}} +
-Ein komplettes 3x3 Feld konnten wir noch nicht testen, da dafür noch Materialien fehlen aber ein Test auf einem Steckbrett hat gezeigt das alles grundsätzlich funktioniert, wie es soll. +
-{{ :ws2122:minitest.jpeg?nolink&200|}}+
 <!-- Bilder und Videos einfügen --> <!-- Bilder und Videos einfügen -->
  
Zeile 78: Zeile 93:
  
 ====Code==== ====Code====
-Jeder Arduino nano der in eine Zelle Verbaut ist benötigt folgenden Code: +Jeder Arduino nanoder in eine Zelle verbaut istbenötigt folgenden Code: 
 <file php CellGenome.ino> <file php CellGenome.ino>
-#define LED 11                      //LED/STATUS pin dieser zelle. Gesteuert durch interne Logik +#define LED 11                      //LED/STATUS pin dieser Zelle. Gesteuert durch interne Logik 
-#define sensorPIN A4                //pin zur Senor auswerung+#define sensorPIN A4                //pin zur Senor-Auswerung
 #define sensorVALUE analogRead(A4)  //sensor wert #define sensorVALUE analogRead(A4)  //sensor wert
-#define stepPIN A5                  //pin zur koordinierung. Gestteuert durch externe Logik+#define stepPIN A5                  //pin zur koordinierung. Gesteuert durch externe Logik
  
-#define readPIN (stepSTATE+3)%8+2   //formel zur berechnung der Pins an den die Nachbarcellen gelesen werden +#define readPIN (stepSTATE+3)%8+2   //formel zur berechnung der Pinsan denen die Nachbarzellen gelesen werden 
-#define writePIN stepSTATE+1        //formel zur berechnung der Pins an den Nachbarcelen angeschrieben werden+#define writePIN stepSTATE+1        //formel zur berechnung der Pinsan denen Nachbarzelen angeschrieben werden
  
 #define stepINPUT digitalRead(A5) #define stepINPUT digitalRead(A5)
-int stepSTATE = 0;                  //extern angegebener Counter für den Lese/Schreibe cyclus+int stepSTATE = 0;                  //extern angegebener Counter für den Lese/Schreibe Zyklus
 boolean stepTOGGLE = false;         //toggle für den stepSTATE boolean stepTOGGLE = false;         //toggle für den stepSTATE
-int jobSTATE = 0;                   //interner counter für den Lese/Schreibe cyclus+int jobSTATE = 0;                   //interner counter für den Lese/Schreibe Zyklus
  
 boolean liveSTATE = false;          //"Lebens"status dieser Zelle boolean liveSTATE = false;          //"Lebens"status dieser Zelle
-int liveNEIGHBOUR = 0;              //Anzahl der "Lebenden" Nachbar cellen+int liveNEIGHBOUR = 0;              //Anzahl der "Lebenden" Nachbar Zellen
  
 const int threshold = 450;          //Grenzwert ab dem der Sensor anschlagen soll const int threshold = 450;          //Grenzwert ab dem der Sensor anschlagen soll
Zeile 103: Zeile 118:
   pinMode(LED, OUTPUT);             //LED Pin   pinMode(LED, OUTPUT);             //LED Pin
   pinMode(sensorPIN, INPUT);        //Pin wo die hall-sonde ausgelesen wird   pinMode(sensorPIN, INPUT);        //Pin wo die hall-sonde ausgelesen wird
-  pinMode(stepPIN, INPUT);          //Pin wo durch der Lese/schreibe cyclus reinkommt+  pinMode(stepPIN, INPUT);          //Pin wo durch der Lese/schreibe Zyklus reinkommt
   pinMode(12, OUTPUT);   pinMode(12, OUTPUT);
   pinMode(12, LOW);   pinMode(12, LOW);
Zeile 114: Zeile 129:
      
   if(stepTOGGLE == false && stepINPUT == true){               //wurde bis jetzt noch kein genarationsimpuls regestriert, geht aber grad einer ein   if(stepTOGGLE == false && stepINPUT == true){               //wurde bis jetzt noch kein genarationsimpuls regestriert, geht aber grad einer ein
-    stepTOGGLE = true;                                        //wird vermekt das ein impuls eingeht +    stepTOGGLE = true;                                        //wird vermerkt das ein impuls eingeht 
-    stepSTATE += 1;                                           //und eine genaration hochgegangen+    stepSTATE += 1;                                           //und eine Generation hochgegangen
     }     }
-  if(stepTOGGLE == true && stepINPUT == false){               //ist vermerkt das ein Impuls registriegt wurde, liegt aber keiner an+  if(stepTOGGLE == true && stepINPUT == false){               //ist vermerkt das ein Impuls registriert wurde, liegt aber keiner an
     stepTOGGLE = false;                                       //wird dies vermerkt     stepTOGGLE = false;                                       //wird dies vermerkt
     }     }
          
-  if (stepSTATE == 0){                                       //geht die Celle nicht die genarationen durch, kann mit dem magneten der status geändert werden:+  if (stepSTATE == 0){                                       //geht die Zelle nicht die genarationen durch, kann mit dem magneten der status geändert werden:
     if (sensorVALUE <= threshold && sensorTOGGLE == false){  //Ist der Magnet nah genug dran und wars bis jetzt aber noch nicht     if (sensorVALUE <= threshold && sensorTOGGLE == false){  //Ist der Magnet nah genug dran und wars bis jetzt aber noch nicht
-      sensorTOGGLE = true;                                   //wird vermerkt das der Magnet nahgenug dran ist+      sensorTOGGLE = true;                                   //wird vermerkt das der Magnet nah genug dran ist
       liveSTATE = !liveSTATE;                                //der Lebenstatus geändert       liveSTATE = !liveSTATE;                                //der Lebenstatus geändert
       Serial.println(sensorVALUE);       Serial.println(sensorVALUE);
Zeile 138: Zeile 153:
     }     }
     pinMode(writePIN,OUTPUT);                                               //es wird der Erste pin in der folge als out-put definiert     pinMode(writePIN,OUTPUT);                                               //es wird der Erste pin in der folge als out-put definiert
-    digitalWrite(writePIN,liveSTATE);                                       //und darüber der lebensstatus an den entsprechenden nachbarn vermittelt+    digitalWrite(writePIN,liveSTATE);                                       //und darüber der lebensstatus an den entsprechenden Nachbarn vermittelt
     pinMode(readPIN, OUTPUT);     pinMode(readPIN, OUTPUT);
     digitalWrite(readPIN,LOW);                                              //der entsprechend gegenüberliegende pin wird resetet,     digitalWrite(readPIN,LOW);                                              //der entsprechend gegenüberliegende pin wird resetet,
     pinMode(readPIN,INPUT);                                                 //als input definiert     pinMode(readPIN,INPUT);                                                 //als input definiert
-    liveNEIGHBOUR += digitalRead(readPIN);                                  //und sofern dort eine Lebende nachbarcelle entdeckt wird, wird dies vermerkt+    liveNEIGHBOUR += digitalRead(readPIN);                                  //und sofern dort eine lebende nachbarzelle entdeckt wird, wird dies vermerkt
     jobSTATE++;                                                             //es wird vermerkt das der erste schritt fertig ist     jobSTATE++;                                                             //es wird vermerkt das der erste schritt fertig ist
     Serial.print(liveNEIGHBOUR);     Serial.print(liveNEIGHBOUR);
Zeile 152: Zeile 167:
   else if (stepSTATE ==9 && jobSTATE == stepSTATE - 1){     //wenn angefordert und fertig mit Job 2 werden die Regeln angewendet:   else if (stepSTATE ==9 && jobSTATE == stepSTATE - 1){     //wenn angefordert und fertig mit Job 2 werden die Regeln angewendet:
     if (liveSTATE == false && liveNEIGHBOUR == 3){          //tote Zelle mit genau drei Lebenden Nachbarn      if (liveSTATE == false && liveNEIGHBOUR == 3){          //tote Zelle mit genau drei Lebenden Nachbarn 
-      liveSTATE = true;                                     //wird Lebendig+      liveSTATE = true;                                     //wird lebendig
     }     }
-    else if (liveSTATE == true && liveNEIGHBOUR < 2){       //Lebende Celle mit weniger als zwei Lebenden Nachbarn+    else if (liveSTATE == true && liveNEIGHBOUR < 2){       //Lebende Zelle mit weniger als zwei Lebenden Nachbarn
       liveSTATE = false;                                    //Stirbt       liveSTATE = false;                                    //Stirbt
     }     }
-    else if (liveSTATE == true && liveNEIGHBOUR > 3){       //Lebende Celle mit mehr als 3 Lebenden Nachbarn+    else if (liveSTATE == true && liveNEIGHBOUR > 3){       //Lebende Zelle mit mehr als 3 Lebenden Nachbarn
       liveSTATE = false;                                    //Stirbt       liveSTATE = false;                                    //Stirbt
     }     }
Zeile 175: Zeile 190:
 <file php controllpanell.ino> <file php controllpanell.ino>
 #define button 8                                  //Der druckknopf für's schritweise fortschreiten der Genarationen wird an diesen Pin angeschlossen #define button 8                                  //Der druckknopf für's schritweise fortschreiten der Genarationen wird an diesen Pin angeschlossen
-#define Switch 7                                  //Der Kippschalter mit dem zwischen "Manuell" und "Automatisch" gewechselt werden kann wird an diesen Pin angeschlossen+#define Switch 7                                  //Der Kippschaltermit dem zwischen "Manuell" und "Automatisch" gewechselt werden kannwird an diesen Pin angeschlossenangeschlossen
 #define PulseOut A5                               //Output Pin für die Pulse #define PulseOut A5                               //Output Pin für die Pulse
 #define Delay 5                                  //verzögerung zwischen den einzelnen Pulsen (ein Genarationswechsel braucht 16*Delay millisekunden) #define Delay 5                                  //verzögerung zwischen den einzelnen Pulsen (ein Genarationswechsel braucht 16*Delay millisekunden)
  
-boolean stepTOGGLE = false;                       //toggle mit dem ein Knopfdruck eine funktion Bloß einmal ausführt, bis der knopf das nächste mal gedrückt wird+boolean stepTOGGLE = false;                       //toggle mit dem ein Knopfdruck eine funktion bloß einmal ausführt, bis der knopf das nächste mal gedrückt wird
  
 void setup() { void setup() {
Zeile 189: Zeile 204:
  
 void loop() { void loop() {
-  if(digitalRead(Switch)== true){                //wenn der Schalter umgelekt ist+  if(digitalRead(Switch)== true){                //wenn der Schalter umgelegt ist
     for (int i = 1; i <= 9; i++ ){               //wird acht mal     for (int i = 1; i <= 9; i++ ){               //wird acht mal
       digitalWrite(PulseOut,HIGH);               //der Takt pin an,                      digitalWrite(PulseOut,HIGH);               //der Takt pin an,               
  • ws2122/game_of_light.1649607437.txt.gz
  • Zuletzt geändert: 2022/04/10 18:17
  • von oleth