Anfänger will eine Art "Senso" bauen..

Hallo,

ich würde gerne etwas in der Art von Senso bauen.

Es geht mir nicht darum genau das nachzubauen. Eine konkrete andere (zeitabhängigere) Idee ist bereits vorhanden.

Nach ca. einem halben Jahr Tutorials durcharbeiten bin ich nun jedoch leider an dem Punkt, wo es mir sehr schwer fällt, mich festzulegen welchen Weg ich einschlagen soll.

Konkreter gesagt fängt mein Problem schon damit an, ob der Starttaster des "Spiels" über ein Reset oder über einen anderweitig geschlossenen Kontakt realisiert werden soll.

Ich habe große Defizite was den grundsätzlichen Aufbau eines (für mich) solch komplexen Projekts angeht.

Einzelne Tutorials mit kleinen Problemstellungen konnte ich immer gut lösen.

Hat mir evtl. jmd. einen Tipp/Link zu einem ähnlichen Projekt, damit ich mich anhand des Codes ein wenig mit dessen Aufbau beschäftigen kann?

Weiss irgendwie nicht wirklich, wo ich da ansetzen soll..

Wäre mir u.U. echt eine große Hilfe! :slight_smile:

Gruß Chris

Einen Starttaster über den Reset realisieren ist grundlegend falsch. Der Microcontroller führt beim Einschalten einen Reset aus und so würd das Spiel immer nach dem Einschalten beginnen.
Grüße Uwe

Das wäre aus meiner Sicht jetzt nicht das Verkehrteste, aber ich bin auf der anderen Seite auch nicht wirklich scharf drauf, dass es dann letzten Endes so läuft.

Ich möchte mich auch eigentlich gar nicht auf das Startknopfproblem festlegen.

Wie bereits geschrieben habe ich ein grundsätzliches Problem bei der Realisierung dieses Projekts.

Trotzdem vielen Dank für Deine Antwort! :slight_smile:

Gruß Chris

PIN_LED[0]=10
PIN_LED[1]=11
PIN_LED[2]=12
PIN_LED[3]=13

char[] "01232212210131"
level=1

loop{
  blink(level)
  
  warte auf eingabe{
    eingabe{ 
      richtig:level++;
      falsch:level=1; char array neu
    }
  }
}

blink{
  for(int i=1; i<level; i++){
    lampe PIN_LED[ char[i] ] leuchten lassen
    delay(500)
    lampe aus
    delay(500)
  }
}

Etwas pseudocode ohne viel steuerkrams :wink: Die eingabeschleife sollte wohl solange laufen, bis
Tastenanschläge==Level ist oder eine bestimmte Zeit zum Taste drücken abgelaufen ist,
dann sollte die Auswertung erfolgen. Eigentlich ganz easy zu realisieren :slight_smile:

Hey, vielen Dank!!

Werd mir das "codetechnisch" genauer angucken und dann gegebenenfalls Rückfragen stellen. :fearful:

Gruß Chris

Hallo,

hab mir das jetzt mal angeguckt. Hat mir vom Verständnis her auf jeden Fall schonmal was gebracht.

Würdet Ihr den "Startknopf" über einen programmierten Counter oder über einen Interrupt realisieren?

Ein Interrupt müsste "besser" sein, da somit ein bereits laufendes Spiel besser unterbrochen werden könnte, oder?

Weiss noch nicht so richtig, was da der sinnvollere Weg ist.

Gruß Chris

Ein Programm ist stets in einer Schleife die die Tasten abfragt, kontrolliert ob die Zeit für des Tastendrücken verstrichen ist (millis() nicht delay()) und die LED ansteuert.
In dieser Schleife kannst Du ruhig auch den Startknopf einlesen und gegebenenfalls das Spiel beenden.
Grüße Uwe

im Buch von:

Erik Bartmann: Die elektronische Welt mit Ardunio entdecken.

Projekt 26: Der Sound und mehr.

Da steht genau dein Projekt drin. Komplette Liste der Bauteile, Schaltplan, kompletter Code.

Einfacher gehts nicht. Ich liebe das Buch.

Hallo,

so, der blutige Anfänger hat es mittlerweile geschafft sein Ziel in so weit zu erreichen, dass er zunächst einmal damit leben kann. :stuck_out_tongue_closed_eyes:

Hier der Code:

#include <Bounce.h>

int knopf_A =  3;                                            // Alle Knöpfe über 10kOhm Pulldowns (Widerstand an GND)
int knopf_B =  5;
int start   =  2;

Bounce knopf_A_Bouncer = Bounce( knopf_A,5 );                // 5 ms Bouncing für "Knopf_A"
Bounce knopf_B_Bouncer = Bounce( knopf_B,5 );                // 5 ms Bouncing für "Knopf_B"
Bounce start_Bouncer = Bounce( start,5 );                    // 5 ms Bouncing für "Start"

int val_A;                                                   // Variable Zustand Knopf_A
int zustand_knopf_A;                                         // Speicherplatz Zustand Knopf_A
int zaehler_knopf_A;                                         // Zählt die Anschläge an Knopf_A
byte sz_knopf_A=0;

int val_B;
int zustand_knopf_B;
int zaehler_knopf_B;
byte sz_knopf_B=0;

int val_start;
int zustand_start;
int zaehler_start;

int LED_A   =  7;
unsigned long LED_A_zeit = 0;
int LED_B   =  4;

int piezo   =  8;                                            // Piezolautsprecher über 100Ohm Widerstand

byte phase = 1;                                              // Phase ausf "2" setzen ("1" = Startphase, "2" = Spielphase, "3" = Endphase)

int zufallsarray[4];                                         // Ein Array mit vier Stellen
int i;                               
boolean zufallszahl;                                         // Eine zufällige Zahl (0 oder 1)

unsigned long schleifenzeit = millis();                      // Schleifenzeit
int schleifenzaehler = 0;                                    // Zähler, der festhält, wie oft die Schleife durchlaufen wurde.

boolean erfolg=true;                                        // Knopfüberwachung bzgl. korrekter Eingabe

/***********************************************************************************************************/

void setup()
{
  pinMode(start,INPUT);                                      // Definition der Aus- und Eingänge
  pinMode(knopf_A,INPUT);
  pinMode(LED_A,OUTPUT);
  pinMode(knopf_B,INPUT);
  pinMode(LED_B,OUTPUT);

  digitalWrite(LED_A, LOW);                                  // LED_A und LED_B ausschalten bei einem RESET
  digitalWrite(LED_B, LOW);
  
  Serial.begin(9600);

  randomSeed(analogRead(0));                                 // Einmalige Erzeugung der Saat
}

void loop()
{

/********************************************************************************************************************************************************************
  
                                                             // Testroutine

             Serial.print("knopf_A: ");                     
             
             Serial.print(zustand_knopf_A);
             Serial.print("  ");
             Serial.print(zaehler_knopf_A);
             Serial.print("    knopf_B: ");
             
             Serial.print(zustand_knopf_B);
             Serial.print("  ");
             Serial.print(zaehler_knopf_B);
             Serial.print("    knopf_S: ");
             
             Serial.print(zustand_start);
             Serial.print("  ");
             Serial.print(zaehler_start);

Serial.println();
//delay(100);

/***********************************************************************   Hauptschleife   *********************************************************************************************/

while (phase ==1){
  start_Bouncer.update ( );
val_start = start_Bouncer.read();                     
  if (val_start != zustand_start)                     
  if (val_start == HIGH)                            
    {
      zaehler_start++;
      noTone(piezo);
      phase=2;
      schleifenzeit=zufallszahl;                                                    // Erste Wahl der Zufallszahl für ein neues Spiel.
      tone(piezo, 311, 75);
      delay(500);
    }
      zustand_start = val_start;
}

if (phase == 2 && millis()>schleifenzeit+1000- (schleifenzaehler*8))                // Formel für die ansteigende Geschwindigleit der Schleife
  {
      schleifenzeit = millis();                                                     // Erfassung der aktuellen Schleifenzeit
      schleifenzaehler++;                                                           // Erhöhung des Schleifenzählers um "1"
      erfolg=true;                                                                  // Erfolgszähler resetten
      phase=9;                                                                      // Phasenangabe auf eine nicht zugeordnete Phase setzen
      noTone(piezo);
      tone(piezo, 162, 75);
      zufallszahl=random(0,2);                                                      // Ermittlung der schleifenzugehörigen Zufallszahl
      zufallsarray[i]=zufallszahl;
      sz_knopf_A=0;                                                                 // Schleifenknopfzähler auf "0" zurücksetzen
      sz_knopf_B=0;

      digitalWrite(LED_A,LOW);                                                      // Lampe ausschalten
      digitalWrite(LED_B,LOW);                                                      // Lampe ausschalten

      Serial.print("Schleifenzufallszahl: ");
      Serial.print(zufallsarray[i]);
      
      Serial.print("   Schleifenzaehler: ");
      Serial.print(schleifenzaehler);
      
      Serial.print("   Schleifenzeit: ");
      Serial.println(schleifenzeit);        
      
      if(zufallszahl%2==0)                                                          // Je nach Zufallszahl entspr. LED einschalten
      {
        digitalWrite(LED_A,HIGH);
      }
      else
      {
        digitalWrite(LED_B,HIGH);
      }
  }
else if (phase == 9 && millis()>schleifenzeit+1000 /*- (schleifenzaehler*8)*/){     // Wenn kein Knopf während der o.a. Schleife gedrückt wurde, wird Phase 3 aktiviert.
  phase=3;
}

/***************************************************************************   Knopfabfragen   ***********************************************************************************************************/
     
knopf_A_Bouncer.update ( );
val_A = knopf_A_Bouncer.read();                                                // Bouncerrückgabewert für Knopf_A wird in "val_A" gespeichert
  if (val_A != zustand_knopf_A && val_A == HIGH) {                             // (Nur) wenn der eingelesene Bouncerrückgabewert "val" nicht mehr dem "Zustand Knopf_A" entspricht und dieser "HIGH" ist..                                  
    zaehler_knopf_A++;                                                         // Zähler für Knopf_A um eins erhöhen.  
    sz_knopf_A++;                                                              // Schleifenknopfzähler ebenfalls erhöhen
      if (sz_knopf_A>1 || zufallszahl == 1){                                   // Wenn Schleifenknopfähler größer als ein wird, oder die Zufallszahl "1" enztspricht..
        erfolg=false;}                                                         // .."erfolg" auf "false" setzen (Spiel verloren)..
        else {
          digitalWrite(LED_A,LOW);                                             // ..ansonsten wird LED_A ausgeschaltet..
          tone(piezo, 311, 75);
          phase=2;}                                                            // ..und Phasenwert "2" gesetzt um ein fortlaufen des Spiels zu gewährleisten.
   }
zustand_knopf_A = val_A;                                                       // Speichern des neuen Zustands in "val_A"     

knopf_B_Bouncer.update ( );
val_B = knopf_B_Bouncer.read();                       
  if (val_B != zustand_knopf_B && val_B == HIGH) {                       
    zaehler_knopf_B++;                              
    sz_knopf_B++;
      if (sz_knopf_B>1 || zufallszahl == 0){
        erfolg=false;}
        else {
          digitalWrite(LED_B,LOW);
          tone(piezo, 311, 75);
          phase=2;}
   }
zustand_knopf_B = val_B;               
    
if(erfolg == false || phase == 3){                                               // Wenn ein falscher Knopf gedrückt wurde oder Phase 3 erreicht ist (siehe weiter oben)..
  tone(piezo, 123, 1000);
  digitalWrite(LED_A,HIGH);                                                      // Lampe einschalten
  digitalWrite(LED_B,HIGH);                                                      
  delay(1000);
  digitalWrite(LED_A,LOW);                                                       // Lampe ausschalten
  digitalWrite(LED_B,LOW);
  schleifenzaehler=0;
  phase=1;
    }
     
}

Nun zu meinen sich daraus ergebenden Fragen:

  1. Hätte ich den Code anders strukturieren sollen um mit weniger Aufwand zum Ziel zu kommen?
  2. Wie streue ich den Zufall "zufälliger", sprich nicht so viele Wiederholungen pro aufgeleuchtete Taste?
  3. Gibt es Ideen bzgl. eines "Zählers"?
  4. Gibt es sonstige Verbesserungsvorschläge?

Danke.

Gruß Chris

IMG_1628-H.264.mov (1.04 MB)