Reaktion Spiel programmieren

Hallo Freunde,

Ich muss folgendes PRogramm schreiben:

Sie verfügen über 3 LEDs, die in zufälligen Kombinationen aufleuchten sollen. Jede der Kombinationen
soll dabei gleich wahrscheinlich sein und die Kombinationen sollen jeweils 0,4 Sekunden leuchten.
Drückt der Benutzer zum richtigen Zeitpunkt (während alle LEDs leuchten) auf den Taster,
erreicht er das nächste Level. Drückt der Benutzer zu einem anderen Zeitpunkt, hat er verloren
und das Spiel beginnt wieder auf dem Anfangslevel. Mit jedem Levelaufstieg verringert sich die
Aufleuchtzeit der Kombinationen um 0,05 Sekunden. Sie dürfen Integer-Variablen verwenden.

Kann mir einer weiterhelfen?

Vielleicht nicht, aber vielleicht eine Hilfestellung geben, da ich garkeine Ahnung habe. Hier habe ich schonmal was gemacht:

int ranNum;
int ranDel;
#define STATE_led0 0

void setup() {
randomSeed(analogRead(0));
current_state = STATE_led0; 

// 3 LEDs als Output konfiguieren
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);

// Taste als Input konfiguieren
pinMode(5, INPUT);
}

void loop() { 
    switch(current_state) 
    {
    //Generiert eine zufaellige Zahl zwischen 2 und 5
    ranNum=random(2,5);
    // Generiert Delays
    ranDel=random(400);
    //LEDs einschalten
    digitalWrite(ranNum, HIGH);
    delay(ranDel);
    //LEDs ausschalten
    digitalWrite(ranNum, LOW); 
    } 
    
}

Was leider nicht funkt.

the-dark-knight:
Hallo Freunde,

Ich muss folgendes PRogramm schreiben:

the-dark-knight:
Kann mir einer weiterhelfen?

Das hört sich nach stark nach einer Hausaufgabe an. Wenn du das aufbekommen hast, solltest du das mit den Unterrichtsstoff auch selber hinbekommen. Ich sehe keinen Ansatz deinerseits. Liege ich somit richtig, dass du nur einen doofen suchst, der deine Hausaufgaben macht??

the-dark-knight:
Sie verfügen über 3 LEDs, die in zufälligen Kombinationen aufleuchten sollen. Jede der Kombinationen
soll dabei gleich wahrscheinlich sein und die Kombinationen sollen jeweils 0,4 Sekunden leuchten.

random nutzten (0 - 3), entspricht den möglichen Zahlen 0, 1 und 2

the-dark-knight:
Drückt der Benutzer zum richtigen Zeitpunkt (während alle LEDs leuchten) auf den Taster,
erreicht er das nächste Level. Drückt der Benutzer zu einem anderen Zeitpunkt, hat er verloren
und das Spiel beginnt wieder auf dem Anfangslevel.

Mach ne einfache Kontrollstruktur mit if else
Wenn Led leuchtet und Taster richtig gedrückt wird, inkrementiere eine Zahl mit 1.
Wenn Led leuchtet und falscher Taster gedrückt oder Zeit überschritten, gehe zurück auf Start.

the-dark-knight:
Mit jedem Levelaufstieg verringert sich die
Aufleuchtzeit der Kombinationen um 0,05 Sekunden.

timeout Zeit einfach aus der Stufe berechnen. timeout = max_time - (stufe-1*50)

the-dark-knight:
Sie dürfen Integer-Variablen verwenden.

Was sonst:D?

Edit, da der TO den Sketch angehangen hat. Lerne mit millis() anstatt delays umzugehen. Zu finden unter blinkwithoutdelay

Der Ansatz ist aber weit weg von dem, was du machen musst! Funktionen in C/Arduino nicht bekannt?

Du musst millis() verwenden. Siehe BlinkWithoutDelay Beispiel.

Sonst kannst du während des Blinkens nicht auf Tastendrücke reagieren.

Danke Leute! Das ist kein Schulstoff, sondern Uni. In der Vorlesung wurde nur gesagt, wir sollen diese Seite nutzen.

Was für eine Fachrichtung soll die Uni haben? Kunst?

Vorab solltest du dich mit den Basics auseinandersetzen, unteranderem die Verwendung von Timern -> millis().

PseudoCode

  1. Muster ausgeben und Zeit merken(millis())

  2. Alle Taster einlesen

  3. Wenn Taster gedrückt und Muster passend, dann von vorne mit nächster Stufe
    Wenn Taster grückt und Muster nicht passend, dann auf Stufe 1 wieder starten
    Wenn kein Taster gedrückt und aktuelle Zeit - gemerkte Zeit größer Timeout, dann auf Stufe 1 wieder anfangen

Die Timout Zeit kannst du dauerhaft berechnen wie bereits oben auch geschrieben (Timeout = Max. Zeit - (aktuelle Stufe - 1 * Zeitanpassung (50ms))

Mit "diese Seite" ist bestimmt www.arduino.cc gemeint.
Stimmt, da gibt es Tonnen von Material unter "Learning"
BlinkWithoutDelay ist schon das Minimum, wie weit du die Beispiele verstehen solltest.

Dein Code fängt mit dem Problem an, dass die Variable current_state nicht definiert ist. Das wird dir der Compiler schon gesagt haben. --> "Sie dürfen Integer Variable benutzen" :stuck_out_tongue:

Die einzige Stelle, wo sie verwendet wird

   switch(current_state)

macht übrigens auch (noch) keinen Sinn und da im Code kein Kommentar ist, kann man also auch nicht raten, was sie eigentlich soll..

Neben Arduino-spezifischem solltest du auch Grundlagen der Programmierung allgemein lernen.
Wenn du ein bisschen Java kennst, ist das besser als nichts, aber der Arduino wird in C / C++ programmiert.

Das ist Computer- u. Kommunikationswissenschaften, Fachrichtung Eingebettete Systeme. Könnt Ihr mir vielleicht ein gutes Tutorial empfehlen? Könnt Ihr wenigstens die strings nennen, die ich da benutzen muss, ausser dieses milli() jetzt.

Wenn es ein Studium ist, dann währen in erster Hinsicht die großen Programmierschinken deine erste Anlaufstellen.

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial
Rheinwerk Computing :: C von A bis Z (als Buch ebenfalls zu empfehlen!)

Was verstehst du unter strings? Kenne ich nur als Zeichenfolge einzelner Buchstaben (chars) mit abschließender 0.

Was du brauchst, sind einfache Basic Kenntnisse in C. Das kann dir die Arduino Software auch nicht abnehmen. Um den ganzen Portregisterkram, was eigentlich auch noch dazu gehört brauchst du dich dank der IDE nicht mehr kümmern.

sschultewolter:
Wenn es ein Studium ist, dann währen in erster Hinsicht die großen Programmierschinken deine erste Anlaufstellen.

AVR-GCC-Tutorial – Mikrocontroller.net
Rheinwerk Computing :: C von A bis Z (als Buch ebenfalls zu empfehlen!)

Was verstehst du unter strings? Kenne ich nur als Zeichenfolge einzelner Buchstaben (chars) mit abschließender 0.

Was du brauchst, sind einfache Basic Kenntnisse in C. Das kann dir die Arduino Software auch nicht abnehmen. Um den ganzen Portregisterkram, was eigentlich auch noch dazu gehört brauchst du dich dank der IDE nicht mehr kümmern.

Ja also in C habe ich leider keine Kenntnisse. Könntest du vielleicht so Grundgerüst mal zeigen?

sschultewolter:
Rheinwerk Computing :: C von A bis Z (als Buch ebenfalls zu empfehlen!)

Manche Leute werden hier mit dem Löffel gefüttert, zugegeben. Aber als künftiger Experte für
"Computer- u. Kommunikationswissenschaften, Fachrichtung Eingebettete Systeme" trauen wir dir mehr zu.

Hallo,

muß auch mal was sagen zum Studierenden.

Ich habe einen Neffen, der geht jetzt in die 12. Klasse und der wird auch bald studieren. Der hat vorher schon am Rechner diverse kleine Dinge programmiert. Dann hab ich ihm einen Raspberry geschenkt. Er hatte Spass daran. Dann hatte er eine große Idee und hat sich dazu einen Arduino Uno gekauft. Die beiden unterhalten sich über XBee. Das wird eine Wetterstation bzw. ist schon eine und ist fast fertig. Programmiertechnisch hat der mich schon lange eingeholt. Ich hatte ihm nur paar Bücher gegeben. Das nenn ich Selbststudium. Das einzige wobei ich ihm helfe sind die elektrischen Sachen mit Transistorschaltungen, Beschaltung von den beiden µC usw. Die Fragen dazu nehmen aber auch ab.

the-dark-knight:
Ja also in C habe ich leider keine Kenntnisse. Könntest du vielleicht so Grundgerüst mal zeigen?

In welcher Programmiersprache hast Du Kenntnisse?
In Deinem Studium wird es doch sowas wie einen Grundkurs geben, in dem Du IRGENDEINE Programmiersprache systematisch kennengelernt hast?

Vom Grundgerüst her gibt es für Mikrocontroller-Programme zwei Arten von Programmen. Diese sind in diesem Tutorial hier beschrieben:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Grunds.C3.A4tzlicher_Programmaufbau_eines_.C2.B5C-Programms

Der Programmtyp "Sequentieller Programmablauf" bedient sich dabei des EVA-Prinzips:

Ein Arduino-Programm besteht dabei aus mindestens zwei Funktionen "setup" (wird einmal beim Programmstart ausgeführt) und "loop" (wird ständig immer wieder ausgeführt). Mit Umsetzung des EVA-Prinzips kommen mindestens drei selbst zu schreibende Funktionen für Eingabe, Verarbeitung und Ausgabe dazu, wenn Du das Programm vernünftig in übersichtliche Funktionsblöcke strukturieren möchtest.

Ein "nacktes" Programmgrundgerüst, mit dem Du auf einem Arduino quasi "alles mögliche" programmieren kannst, sieht daher ungefähr so aus:

// Hier alle benötigten "globalen" Variablen und ggf. Unterfunktionen deklarieren

void eingabe()
{
  // Eingabefunktion zum Abfragen von Eingängen
}

void verarbeitung()
{
  // Funktion verarbeitet Eingangsdaten zu Ausgangsdaten
}


void ausgabe()
{
  // Ausgabefunktion zum Setzen von Ausgängen und zur Ausgabe
  // von Daten auf Ausgabegeräten
}


void setup() 
{
  // Beim Programmstart hier alle Variablen und 
  // die verwendete Hardware initialisieren
}

void loop() 
{ // Programmablauf nach dem EVA-Prinzip
  eingabe();
  verarbeitung();
  ausgabe(); 
}

Und je nachdem, was im Programm ablaufen soll, wäre es dann die Aufgabe:

  • geeignete Datenstrukturen/Variablen zu deklarieren
  • und die Funktionen mit sinnvollem Code zu befüllen

Für interaktive Programme kannst Du die Verwendung der Funktion "delay" praktisch komplett streichen. Die Funktion "delay" blockiert Deine Programmausführung für die angegebene Zeit. Und die Blockierung der Programmausführung ist absolut kontraproduktiv, wenn ein Programm schnell auf irgendwelche Eingaben reagieren können soll.

Wie lang das längste delay() in Deinem Programm dauern darf, kannst Du Dir anhand der geforderten Reaktionszeit ausrechnen. Mal angenommen, das Programm soll innerhalb einer hundertel Sekunde (=10 Millisekunden) reagieren können, dann darf die Summe der verwendeten delay()-Aufrufe beim gesamten Durchlaufen der loop-Funktion (Eingabe, Verarbeitung, Ausgabe) nur weniger als 10 Millisekunden betragen. So dass die gesamte loop-Funktion mindestens 100 mal pro Sekunde durchläuft bzw. eine Ausführung der loop-Funktion nur höchstens 10 Millisekunden dauert. Je schneller die loop-Funktion, desto reaktionsschneller agiert das Programm auf neue Eingaben wie z.B. das Drücken eines Tasters.

Die Programmlogik deines Spiels braucht weit unter 1 ms für einen loop-Durchlauf.

desto reaktionsschneller agiert das Programm auf neue Eingaben wie z.B. das Drücken eines Tasters.

Wobei Taster nun ein sehr interessantes Beispiel sind, denn ganz ohne delay ist ein µController viel zu schnell für einen mechanischen, prellenden Taster.

Bei deinem Reaktionstest-Spiel sind jurs' 10ms ein guter Wert um das Taster-Prellen zu ignorieren und schnell genug zu bleiben.

Die nächst größere Zeit in deinen Anforderungen sind 50ms als Unterschied der Blinkzeit je Level.

Ich verstehe die Aufgabe übrigens so, dass die Frequenz, mit der neue LED-Muster angezeigt werden, nicht von einer Zufallszahl abhängt, sondern fest am aktuellen Level hängt.