Umsetzung Das Spiel Der Heiße Draht

Hallo,

Ich bin Neu in dem Thema Sketches. Ich möchte gerne einen Heißen Draht bauen wo eine Sicherung drin ist um nicht zu Betrügen. (Ich weiß es gibt immer einen weg dazu)

Ich habe das Problem das ich in meiner Holzplatte einen Startkontakt (Draht) der auf Pin5 liegt. mein eigentlicher Heiße Draht liegt auf Pin4 und mein Zielkontakt liegt auf Pin6. Die Schlaufe die dem Heißen Draht entlang geführt werden muss liegt auf Masse.

Mein Ziel ist es das wenn man den Arduino mit Strom versorgt die Rote LED (Pin2) an ist und die Pins 4+6 ohne Funktion sind. erst wenn ich mit der Schlaufe den Startkontakt berühre, Soll die Grüne LED (Pin 3) angehen und der Pin 4 vom Heißen Draht und der Pin 6 aktiv werden. Der Startkontakt ist inaktiv. Sollte der Spieler einen Fehler machen, Geht die Rote LED wieder an und es ertönt ein Piepton (Lautsprecher Pin 12) und der Pin 4 und 6 ist wieder inaktiv. so das es von vorne beginnt. Sollte der Spieler es schaffen ohne Fehler durch zu kommen und den Zielkontakt berühren soll ein Servo betätigt werden.

Wie gesagt, Ich habe den Code im Internet gefunden und wollte ihn Anpassen.

Aktuell sieht mein Code wie folgt aus:

#include <Bounce2.h>
//Taster
#define BTN1 4 // Heißerdraht
#define BTN2 5 // Startkontakt
#define BTN3 6 // Zielkontakt

//Anzeige für den Kontakt
#define redLED 2    // Rote LED
#define greenLED 3  // Grüne LED
#define BUZZER 12   // Lautsprecher

Bounce btn1Bouncer = Bounce(BTN1, 100);
Bounce btn2Bouncer = Bounce(BTN2, 100);
void setup() {
  pinMode(BTN1, INPUT);
  pinMode(BTN2, INPUT);
  pinMode(BTN3, INPUT);
  pinMode(redLED, OUTPUT);
  pinMode(greenLED, OUTPUT);
  pinMode(BUZZER, OUTPUT);

  digitalWrite(BTN1, HIGH);
  digitalWrite(BTN2, HIGH);
  digitalWrite(redLED, HIGH);
  digitalWrite(greenLED, LOW);
}
void loop() {
  digitalWrite(redLED, HIGH);
  btn2Bouncer.update();
  //Wenn der Kontakt geschlossen ist,
  //also ein Wechsel von LOW auf HIGH stattgefunden hat
  //dann...
  digitalWrite(greenLED, HIGH);
  if (btn2Bouncer.rose()) {
    digitalWrite(redLED, LOW);   //Rote LED aus
    digitalWrite(greenLED, HIGH);  // Grüne LED an
  } 
  btn1Bouncer.update();
  //Wenn der Kontakt geschlossen ist,
  //also ein Wechsel von LOW auf HIGH stattgefunden hat
  //dann...
  digitalWrite(greenLED, LOW);
  if (btn1Bouncer.rose()) {
    digitalWrite(redLED, HIGH);   //LED aktivieren
    delay (500);
    digitalWrite(greenLED, LOW);  // Grüne LED aus
    tone(BUZZER, 900); // Ton aktivieren, in einer Frequenz 900 Hz
    delay(350); // Kleine Pause von 350ms
    noTone(BUZZER); //Ton deaktivieren   
  }
}

Wieso inaktiv, was soll das bedeuten?

Ein Automat (state machine) würde vom Zustand Warten beim Berühren des Startkontakts in Gestartet übergehen. Dann meim Berühren des Drahts in Zustand Fehler oder beim Berühren des Zielkontakts in Gewonnen. Aus beiden Zuständen kommt man wieder raus durch Berühren des Startkontakts.

Sorry für die unklare Beschreibung.

Ich möchte das man eben den Startkontakt berührt und dann das Speil beginnt. Wenn man ihn berührt soll er wieder zum Anfang springen, so das man ihn erst wieder aktivieren muss.

Heißer Draht Spiel ohne zu betrügen - YouTube In diesem Video ist die Schaltung und Erklärung was ich meine. Leider ist hier das Programm Ardublock genutzt wurden und ich bekomme die Blöcke nicht entschlüsselt.

"Das fertige Programm wird dann in die Arduino IDE hochgeladen und übersetzt, so dass es wie ein "richtiges Arduino-Programm" weiter verwendet werden kann."

Also abspeichern und mit der IDE öffnen.

Ich bekomme nicht alle Blöcke nachgebaut. Zum Beispiel ist dort der INPUT_PULLUP ein gebaut diesen Block gibt es aber in der Neuen Version nicht oder ich finde ihn nicht.

Schau Dir mal pinMode an.

Gruß Tommy

In meinem Code oder in Ardublock ?

Bei der Arduino Befehlsreferenz auf die @Tommy56 verlinkt hat. Dort steht geschrieben wie es geht.

Das ist eine Schrittkette mit Resetmöglichkeit.

Die Schrittkette wäre:
Start

  • Schritt 0 - > Wartezustand
    rote LED an
    gruene LED aus
    Draht inaktiv
    Schlaufe inaktiv
    StartButton aktiv
    Zielbutton inaktiv
  • Schritt 1 -> StartKontakt auslösen
    rote LED aus
    grüne LED an
    StartButton inaktiv
    ZielButton aktiv
    heisser Draht aktiv
    Schlaufe aktiv
  • Schritt 2
    Abfrage Schlaufe / Draht -> Bei Berührung Abbruch mit Beep und Start bei Schritt 0
    Abfrage auf Zielbutton -> nächster Schritt
  • Schritt 3
    Servo auslösen
    Ende

Willste das mal komplett ohne Ardublock basteln? Ich denke, das geht schneller und effizienter.
PS: Ich versteh noch nicht, warum Du da einen debouncer brauchst, wenn Du immer auf das Ereignis reagieren musst. :wink:

Je nach Wunsch :wink:

So am Rande die ganze Programmierung im Ardublock muss man auch lernen, also besser ist sofort alles über die IDE machen und dabei Lernen wie und was macht dein Arduino, ist aber nur meine Meinung

const byte heisserDraht = 4; // Heißerdraht
const byte startKontakt = 5; // Startkontakt
const byte zielKontakt = 6; // Zielkontakt

//Anzeige für den Kontakt
const byte redLED = 2;    // Rote LED
const byte greenLED = 3; // Grüne LED
const byte buzzer = 12;  // Lautsprecher

enum {warten, aktiv, erfolg, error};
byte zustand = warten;
void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start...."));
  pinMode(heisserDraht, INPUT_PULLUP);
  pinMode(startKontakt, INPUT_PULLUP);
  pinMode(zielKontakt, INPUT_PULLUP);
  pinMode(redLED, OUTPUT);
  pinMode(greenLED, OUTPUT);
  pinMode(buzzer, OUTPUT);
}

void loop()
{
  switch (zustand)
  {
    case warten:
      noTone(buzzer); //Ton deaktivieren
      digitalWrite(redLED, HIGH);
      digitalWrite(greenLED, LOW);
      if (digitalRead(startKontakt) == LOW)
      {
        digitalWrite(redLED, LOW);
        digitalWrite(greenLED, HIGH);
        zustand = aktiv;
      }
      break;
    case aktiv:
      if (digitalRead(zielKontakt) == LOW)
      {
        Serial.println(F("Zielkontakt ausgelöst"));
        zustand = erfolg;
      }
      if (digitalRead(heisserDraht) == LOW)
      {
        Serial.println(F("Draht berührt"));
        zustand = error;
      }
      break;
    case erfolg:
      for (byte b = 0; b < 5; b++)
      {
        digitalWrite(greenLED, LOW);
        digitalWrite(redLED, HIGH);
        delay(500);
        digitalWrite(greenLED, HIGH);
        digitalWrite(redLED, LOW);
        delay(500);
      }
      zustand = warten;
      break;
    case error:
      tone(buzzer, 900); // Ton aktivieren, in einer Frequenz 900 Hz
      delay(350); // Kleine Pause von 350ms
      noTone(buzzer); //Ton deaktivieren
      zustand = warten;
      break;
  }
}

compiliert. Keine weiteren Erklärungen. Kann man sowas auch in Ardublock importieren?

Moin

Ich habe den Code as dem Netz. Diesen wollte ich anpassen auf meine Bedürfnisse.

Er ist m.E. nicht sinnvoll.
Das debouncen brauchst Du, wenn Du zum Beispiel auf das drücken und loslassen einer Taste reagieren musst.

In Deinem Fall musst Du nur auf das erste auslösen reagieren.
Dazu ist mit den vielen if-Abfragen das gegenseitige Verriegeln notwendig, was zu weiteren Abfragebedingungen führt.
Ich habe Dir oben einen Kurzcode geschrieben, der durch die Anwendung von switch/case immer nur eine Aktion überwacht und darauf reagieren soll.

Kannst mal testen, ob der das tut, was Du willst?

Vielen Dank für deine Erläuterung. Sobald ich zuhause bin werde ich es machen und eine Rückmeldung geben.

Vielen Dank schonmal im Voraus

Gerne.
Ich lern auch was neues: Ardublock kam mir bisher nicht auf den Rechner...

HA:) Ich kann schon mal helfen.
Die aktuelle Version habe ich von hier: letsgoING / ArduBlock · GitLab
Da scheint auch die Entwicklung weiterzugehen, wenn man github liest.
Wenn Du die hast, ist es Version 2.2. und Du hast unten am unteren Bildrand einen Button PRO - da verstecken sich dann weitere auswählbare Elemente.

Aber ich bin damit auch noch nicht warm ;(

Also ich werd nicht warm mit dem Ardublock :frowning_with_open_mouth:
Und aus dem Video werd ich nicht schlau, warum da noch ne zweite Variable benötigt wird und die zudem alle analog sind.

Zum Ardublock:
Es gibt kein switch case, das macht es unnötig kompliziert.
Das nur mit if zu bauen ist anstrengend und das mitdenken bei der Blockplatzierung kommt noch dazu.

Mein Block sähe so aus:

Daraus erwächst dann folgender Code:

/**
 * file:	Heisser Draht mit if
 * author:	Name oder Kuerzel
 * 
 * description:
 * Kurzbeschreibung Programmfunktion
 * 
 * date:	23.07.2022
 * version:	0.1
 */

bool spiel = false;

void setup() {
  Serial.begin(115200);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  Serial.print("Start... ");
  Serial.println();

  pinMode(12, OUTPUT);
  digitalWrite( 2 , HIGH );

  digitalWrite( 3 , LOW );

}

void loop() {
  if (( ( ( spiel == false ) && ( digitalRead(5) == false ) ) && ( ( digitalRead(4) == true ) && ( digitalRead(6) == true ) ) )) {
    spiel = true;
    digitalWrite( 2 , LOW );
    digitalWrite( 3 , HIGH );
    Serial.print("spiel freigegeben ");
    Serial.println();
  }
  if (( spiel == true )) {
    if (( digitalRead(4) == false )) {
      digitalWrite( 2 , HIGH );
      digitalWrite( 3 , LOW );
      spiel = false;
      Serial.print("verloren ");
      Serial.println();
      tone(12, 900, 350);
    }
    if (( digitalRead(6) == false )) {
      spiel = false;
      Serial.print("gewonnen ");
      Serial.println();
      for (int i = 0; i < 5; i++) {
        digitalWrite( 2 , HIGH );
        digitalWrite( 3 , LOW );
        delay( 500 );
        digitalWrite( 2 , LOW );
        digitalWrite( 3 , HIGH );
        delay( 500 );
      }
    }
  }
}

Davon abgesehen, das im ersten if mit den ganzen Bedingungen ein Klammerpaar zuviel ist, sind da Unmengen Leerzeichen insgesamt zuviel und es gibt keine Möglichkeit, die PinNummern mit einer Bezeichnung zu versehen. Das ein Serial.println(" text ") in zwei Zeilen aufgeteilt werden muss, erschliesst sich nicht - das war früher wohl anders.

Es war ein netter Ausflug, aber ich bin ein Tastaturmensch.
In der Zeit, wo ich das zusammengeschoben habe, schreib ich nen PAP, setze den als Doku fertig und bau den Code. Bei größeren Projekten werd ich mich vermutlich verlaufen.

Trotzdem: Danke für den Hinweis dazu.
Ich hab den Blockcode unten angehangen, wenn Du wirklich damit arbeiten willst....
a1.zip (3,6 KB)

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.