Lektion 10 - Arrays / würfeln von 1-6

  • Hallo zusammen


    Für Osterwünsche bin ich wohl etwas zu spät. Ich hoffe aber, dass ihr alle schöne Tage erleben durftet.

    Bei dieser Gelegenheit möchte ich mich bei allen bedanken, die dieses Forum durch ihre Beiträge am Leben erhalten. Besonders freut mich der freundliche und respektvolle Umgangston.


    Die hier verwendete Forensoftware ist etwas veraltet und ich sollte dringend ein Update durchführen. Leider ist es ein grosser Sprung, so dass dabei auch etwas schief gehen könnte. Es wird sicher einen kleinen Unterbruch geben, da die Datenbankstruktur ändert und neue PHP und MySQL Versionen zum Einsatz kommen.. Ich werde das aber frühzeitig ankündigen.


    Gruss

    René

  • Danke, für die netten Osterglückwünsche. Ich wünsche Dir und Deiner Familie ebenfalls schöne Ostertage.
    Das gleiche gilt natürlich auch für René, der diese Plattform zur Verfügung stellt, sowie an alle die sich im Forum aufhalten.


    Gruß

    Hans

  • Das mach schon deshalb wenig Sinn, weil die meiste "Arbeit" in meinem Programmbeispiel in der Ansteuerung der LEDs steckt. Das Würfeln selber wird in "getRandom()" erledigt. Das ist der kleinste Teil.

  • Wenn ich die Würfelaugen für einen Würfel aus dem Sketch von Kai auslesen könnte und in z.B. an Variable int Zahl übergebe, Dann könnte ich doch auch unten stehendes Beispiel von Kai benutzen.

    So könnte es dann fortgesetzt werden


    Ich kann es aber nicht.

  • Das Display ist leider defekt. Jetzt bleibt das Display dunkel. Ich habe das Display sicherheitshalber zum testen auch an einen UNO angeschlossen.

    Erstmalig ist bei mir ein neues Display von AZ-D defekt.

  • Hallo Franz,


    ich finde, der Würfel ist gut geworden. Deine Enkel werden sich sicherlich darüber freuen.


    Ich kenne mich zwar ein wenig mit Arduino aus, kann aber bezüglich der Streifen nichts dazu beitragen. Es ist schon ein wenig seltsam,

    da die Streifen beim Testaufbau nicht vorhanden waren.


    Gruß

    Hans

  • Ich habe dem Würfel mehr eine organische Form gegeben. Siehe Bilder. Das ist mit SketchUp nicht so einfach und war mal wieder eine schöne Übung.

    Der Würfel ist 48 x 48mm.


    001.JPG   002.JPG  003.JPG


    Beim dritten Bild sind die unteren runden weißen Flächen streifig. Beim ersten Bild sind das die Buchstaben t und e.

    Woran kann das liegen? Als der Testaufbau am UNO angeschlossen war, hatte das Bild keinen Rahmen und es waren keine Streifen zu sehen.

    Eigenartig.

    Grüße, Franz

  • Zumindest ist mein untenstehendes Beispiel dahingehend schlecht designed, dass die Würfelklasse die Ausgabe über LEDs fest verdrahtet hat. Eigentlich müsste es noch ein Interface geben, welches das Würfeln und die Ausgabe des Würfelergebnisses trennt und eine Schnittstelle zur Ausgabe (LEDs, OLED usw.) darstellt.

  • Kai, es ist mir doch klar, dass es Dir nicht um Spielereien ging, sondern um spezielle Lösungsansätze bei der Programmierung.


    Deshalb auch mein Hinweis, wenn man den Würfel als Spielwürfel nutzen möchte.

    Bei fast allen Programmierbeispielen werden als Hardware LED's und Taster eingesetzt. Ich dachte, bei diesem Beispiel könnte man auch mal abweichen.

    Den funduino Würfel wollte ich mal mit Display und Gehäuse für meine Enkel basteln und habe mich deshalb gefreut, dass hier schon das Thema würfeln behandelt wurde.

  • Zumindest ist der „funduino“ Würfel wesentlich simpler. Und die Programmierung desselben, würde ich mir nicht als Vorbild nehmen


    Es geht hier auch gar nicht um originell oder nicht originell. Es geht um Lösungsansätze und ums lernen.

    Sich mit bestimmten Problematiken beschäftigen und verschiedene Varianten durchspielen. So lerne ich…

    andere ja möglicherweise such.

  • Hallo zusammen,


    ich habe auch mal mit René's Aufgabe herumgespielt und versucht elektronische Würfel zu "bauen" die ohne die delay() Anweisung auskommen. So kann LED animiert, nicht blockierend gewürfelt werden. Der Ansatz ist C++ OOP mäßig.


    Das Programm besteht im Wesentlichen aus drei Klassen. Zuerst einer Buttonklasse, welche das entprellte Abfragen eines Tasters erledigt. Eine Timerklasse die den Umgang mit millis() erleichtert. Diese ist notwendig um ein "nicht blockierndes" Würfeln (ohne delay) zu ermöglichen. Zu Guter Letzt gibt es eine Würfelklasse, welche den Würfelvorgang abbildet.


    Durch das nicht blockierende Würfeln ist es möglich, dass mehrere LED Würfel quasi gleichzeitig animiert dargestellt werden können. In einer For-Schleife mit der delay() Anweisung wäre das unmöglich. Bei einem Würfel ist das egal. Wenn man aber z.B. ein elektronisches Kniffel Spiel erstellen möchte, welches fünf Würfeln benötigt, wäre es doch ziemlich störend, wenn nur ein Würfel nach dem anderen seine Würfelsequenz "abfahren" würde.


    Durch den (notwendigen) Verzicht auf eine For-Schleife mit delay(), ist es bei dieser Implementierung erforderlich, nach jedem Würfelvorgang den/die Würfel mit der Methode <objektname>.rollReset(); zurückzusetzen. Dabei wird ein interner Zähler der für die LED Animation benötigt wird, wieder auf Null zurück gesetzt.


    Das Beispiel ist für zwei Würfel ausgelegt. Die Würfelobjekte sind in einem Array abgelegt. Durch den OOP Ansatz ist das Beispiel im Prinzip (genug Pins vorausgesetzt) mit wenig Programmieraufwand um Würfel erweiterbar. Im Prinzip muss nur das Array um weitere Würfelobjekte erweitert werden.


    Es ist auch gut vorstellbar, das Ganze mit Portexpandern zu betreiben. Dafür ist aber etwas Umbau notwendig.


    Für Vorschläge, wie man das Würfelobjekt optimaler aufbauen kann bin ich offen und würde mich darüber freuen... :)


    Hier gibt es auch eine WokWi Simulation der zwei Würfel: https://wokwi.com/projects/359113191790579713


    Nicht wundern, das "random" funktioniert in der Simulation nicht wirklich. Bei einem echten Aufbau sollten die gewürfelten Werte wesentlich zufälliger sein als in der Simulation (dort sind sie es überhaupt nicht bzw. allenfalls der erste Wert). Das Programm startet mit einer Würfelanimation. Die Leds werden aber wieder gelöscht wenn sie beendet ist. Im Anschluss löst ein Tasterdruck einen Würfelvorgang aus und die Augenzahl wird am Ende durch die LEDs angezeigt.

  • Ok, unter Zuhilfenahme von Arrays ist das Programm um einiges kürzer.

    Was mich etwas gestört hat, war die sehr langsame Ausgabe der Würfelaugen, über die "zeige-Funktion", beim würfeln. Das war gefühlt 1 Sekunde und man hätte das Ergebnis beeinflussen können. Die Stelle am Code hab ich etwas angepasst. Es gibt jetzt eine eigene "wuerfeln-Funktion". Dort lasse ich die LEDs wahllos blinken und der "random-delay" greift auch wieder.




    Video:

    https://www.dropbox.com/s/mbfyjfl14m08jgi/IMG_2503.mov?dl=0

  • for each Konstrukte gibt es in C nicht. Man müsste das etwas mühsam nachbilden.


    In deinem einfachen Fall wäre das kein Problem. Ich verwende hier der Bequemlichkeit halber das String - Objekt. Reine C - Programmierer würden hier eher mit CHAR - Arrays arbeiten. Dann ist aber die kombinierte Ausgabe innerhalb der Schleife wesentlich komplizierter.



    Gruss

    René

  • Danke für eure Antworten. Das hab ich mir soweit auch schon gedacht.

    Wenn ich auf Arbeit mit der Powershell, von Windows,

    Scripte programmiere, gibt es die Möglichkeit Variablen in einer Schleife zu kombinieren.


    pasted-from-clipboard.png


    Gibt es sowas auf dem Arduino auch?


    Grüße


    Rayko

  • Zitat

    Beim initialisieren der Eingänge „pinMode(LED1, OUTPUT);“ gibt es da eine Möglichkeit mit einer Schleife zu arbeiten und die Ziffer hinter LED durch eine Variable zu ersetzen (auch in der Start-Funktion). Sodass beim durchlaufen der Schleife die Ports LED1, LED2, LED3... angesprochen werden? Oder könnte man das über ein Array lösen? Wie verbinde ich dann aber die Variable mit dem entsprechenden Port?


    LED1..LED7 sind Variablennamen bzw. Konstanten, die letztendlich auch nur Zahlen enthalten. Von daher kann pinMode ohne weiteres per Schleife aufgerufen werden. LED1..LED7 sind dazu nicht notwendig, sondern es wird der Zählerwert einer Schleife verwendet, der bei jedem Schleifendurchlauf, eine um eins erhöhte Pinnummer repräsentiert. Es ist nicht notwendig die Ziffer hinter LED durch eine Variable zu ersetzen. Es geht ja nicht darum einen Textstring zu bearbeiten. Die Konstanten LEDx werden u.a. der besseren Lesbarkeit des Quellcodes wegen angelegt.


    Code
    1. // pinmode auf die Pins 2 bis 8
    2. for (byte i=2;i<9;++i) {
    3. pinMode(i, OUTPUT);
    4. }


    Natürlich kann man die Pinnummern auch in einem Array abspeichern und damit die Pins schalten. Der Zählerwert der Schleife ist dann der Index auf die Arrayposition, in der die Pinnummer gespeichert ist. Im Falle eines Arrays können auch Pins berücksichtigt werden, die nicht aufeinanderfolgend sind.


    Code
    1. // pinmode auf die Pins 2 bis 8
    2. byte LED[8] = {2,3,8,7,4,6,5};
    3. for (byte i=0;i<7;++i) {
    4. pinMode(LED[i], OUTPUT);
    5. }

    Gruß Kai

  • Hallo Rayko,


    dein Weg ist korrekt, er erfordert einfach etwas unnötige Tipparbeit.


    Da die LEDs an aufeinanderfolgenen Pins angeschlossen sind, könnte mit einer Schleife gearbeitet werden. Damit liessen sich setup() und start() vereinfachen.


    Sobald die Pins nicht mehr lückenlos nacheinender kommen, geht das mit der Schleife nicht mehr direkt. In diesem Fall muss eine Umsetzung von LED-Nummer zu Pin-Nummer mit Hilfe eines Arrays gemacht werden. Ein einfaches Beispiel mit 5 LEDs findest du im Lösungsvideo. Eine Stufe weiter geht dann Lektion 11.


    Gruss

    René