Tastersignal (von HIGH auf LOW) erst auswerten wenn das Türsignal anliegt. (Anfänger)

Hallo alle zusammen!

Ich bin absoluter Anfänger wenn es um Programmierung geht. Ich habe auch versucht mit Google nach meiner Frage zu suchen wusste aber nicht wonach ich genau suchen muss um meine Frage zu beantworten. Vermutlich ist meine Frage für die meisten hier absolutes Basiswissen.

Frage:
Ich habe u.a. eine Tür welche mit einem Endlagenschalter geprüft wird ob sie offen (Signal HIGH) oder geschlossen (Signal LOW) ist. Und ich habe einen Starttaster den ich mit INPUT_PULLUP abfrage. Nun soll es so sein das ich will das der Starttaster nur dann auslöst wenn die Tür geschlossen ist. Aber er darf nicht auslösen wenn man den Starttaster betätigt und dann die Tür schließt. Außerdem soll man den Starttaster noch 2 Sekunden gedrückt halten bevor das eigentliche Programm startet.
Mit einer einfachen if Auswertung ist es ja nicht getan, da ja dann der Starttaster auch auslöst wenn er erst gedrückt wird und dann die Tür geschlossen wird.
Kann mir jemand sagen wie ich das umsetzen kann?

Hardware:
Ich benutze ein Arduino Mega
Starttaster ist an A0
Endlagenschalter der Tür ist auf D8
Außerdem habe ich 2x 7-Segmentanzeigen mit je 5 Anzeigen verbaut die mir zwei Zeiten anzeigen (habe ich schon zum laufen bekommen dank eines sehr guten Videotutorials).

Hallo greendragon1

Poste den Sketch, gut formatiert, mit Kommentaren und in so genannten Code-Tags "</>" und einen Schaltplan um zu sehen, wie wir helfen können.

Auch wenn du das noch nicht weißt, aber du möchtest einen "endlichen Automaten" bauen.

Ich habe dafür noch keinen Code geschrieben, da ich nicht weiß wie ich das umsetzen kann.

@combie : Was bitte soll ein "endlicher Automat" sein?

Ist Dein Google defekt?

Gruß Tommy

Dann nehme einen Stift und zeichne einen Programmablaufplan.

Ein endlicher Automat, ist ein Automat, welcher eine endliche Anzahl Zustände kennt.
Eine Zustandsmaschine

@greendragon1

doch eigentlich schon. Aber mit einer State Machine wird es klarer. Außerdem verirrst du dich nicht in If else Verschachtelungen und ist leichter erweiterbar.

du beschreibst 3 Zustände:
dabei gibts von jedem Zustand bestimmte Übergangsmöglichkeiten in einen anderen Zustand.

Ist die Darstellung korrekt?
wenn ja - poste ein Grundgerüst für deinen Sketch mit allen Pin Definitionen und dem Setup.
dann kann man dir weiterhelfen.

wenn nicht: korrigiere das Bild oder deine Aussagen.

Vielen dank für das Bild. Ich habe nämlich bis dahin nicht gewusst was paulpaulson mit dem EVA Prinzip und Programmablaufplan von mir wollte (Auch nach dem ich mir den Wiki Eintrag angesehen hatte)

Ja wenn ich das richtig verstanden habe ist das Bild korrekt.
Wichtig ist mir das wenn der Starttaster (Port A0) gedrückt wird (wechsel von HIGH zu LOW) bevor die Tür geschlossen wird (Port D8 auf HIGH ist) das Folgeprogramm nicht startet. Nur wenn die Tür geschlossen ist (Port D8 auf LOW ist) soll das Folgeprogramm starten wenn der Taster 2 Sekunden gedrückt wird (Port A0 von HIGH zu LOW wechselt).
Das Folgeprogramm darf auf keinen fall starten wenn der Starttaster (A0) gedrückt gehalten wird und dann die Tür geschlossen wird.
Ich bin noch nicht zuhause weshalb ich grad nicht mehr Posten kann.


Mir ist klar das meine Frage vermutlich für die meisten hier zum Grundlagenwissen gehört. Ich bin aber noch ganz am Anfang was das Programmieren angeht. So habe ich 2 Abende damit zugebracht in dem Programm welches ich aus einem Videotutorial habe einen Fehler zu finden der mit dem Multiplexing meiner 7-Segmentanzeigen zu tun hatte. Den Fehler habe ich auch nur deshalb bemerkt weil an einem anderen Port wo eine weiter LED dran war immer mal wieder ein kurzes Signal anlag. Und das habe ich erst festgestellt als ich den Serialmonitor angeschalten und mir den Port ausgeben lassen habe.

Unterwegs kann man Wokwi nutzen:

Das ist kein Port. Nur ein Pin.
Soviel dann zur Berichtigung.

Vielleicht suchst Du sowas - ohne Garantie und ohne doppelten Boden.

// Forensketch bedingter Start
// https://forum.arduino.cc/t/tastersignal-von-high-auf-low-erst-auswerten-wenn-das-tursignal-anliegt-anfanger
// kompiliert fehler- und warnungsfrei

#include <Streaming.h>     // https://github.com/janelia-arduino/Streaming

//#define DEBUG              // Wenn aktiviert, werden Zwischenwerte ausgegeben

#ifdef DEBUG
#define DBG_PRINTLN(...) Serial << __VA_ARGS__ << endl
#else
#define DBG_PRINTLN(...)
#endif

constexpr byte endlagenSchalterPin {8};
constexpr byte tasterPin {A0};
constexpr byte anzeigePin {LED_BUILTIN};
uint32_t startTime;
enum STATE {waitButton, waitOpen, waitClose};
byte state = waitClose;
void setup()
{
  Serial.begin(115200);
#if (defined(ARDUINO_AVR_MEGA) || defined(ARDUINO_AVR_MEGA2650)) // https://github.com/arduino/Arduino/issues/10764
  delay(300);
#endif
  Serial << (F("\r\nStart...\r\n")) << endl;
  DBG_PRINTLN(__FILE__);
  DBG_PRINTLN( __TIMESTAMP__);
  pinMode(endlagenSchalterPin, INPUT);
  pinMode(tasterPin, INPUT_PULLUP);
  pinMode(anzeigePin, OUTPUT);
  if (digitalRead(endlagenSchalterPin) == HIGH)
  { state = STATE::waitClose; }
}

void  loop()
{
  stateMachine();
}

void stateMachine()
{
  switch (state)
  {
    case waitButton:
      digitalWrite(anzeigePin, LOW);
      if (digitalRead(endlagenSchalterPin))           // Tür offen?
      {
        Serial << F("Tür unbefugt geöffnet") << endl;
        state = STATE::waitClose;
      }
      else if (!digitalRead(tasterPin))               // Taste gedrückt?
      {
        startTime = millis();
        Serial << F("Öffner ausgelöst bei ") << startTime << endl;
        state = STATE::waitOpen;
      }
      break;
    case waitOpen:
      if (!digitalRead(tasterPin))                    // Taste noch immer gedrückt?
      {
        if (millis() - startTime > 2000)              // Zeit abgelaufen?
        {
          digitalWrite(anzeigePin, HIGH);
          Serial << F("geöffnet bei ") << millis() << endl;
          state = STATE::waitClose;
        }
      }
      else                                            // zu früh losgelassen
      {
        Serial << F("Taster zu früh losgelassen") << endl;
        state = STATE::waitButton;
      }
      break;
    case waitClose:
      if (digitalRead(tasterPin) &&                   // taste losgelassen UND
          !digitalRead(endlagenSchalterPin))          // Tür geschlosen?
      {
        Serial << F("Tür ist zu und Taste losgelassen") << endl;
        state = STATE::waitButton;
      }
      break;
  }
}

Vielen Dank für den Code. Ich hab ihn mir jetzt eine Weile angesehen und er gib mir viele neue Ansätze wie man das Programmieren kann. So finde ich den Befehl "switch" sehr interessant. Alles an dem Code habe ich noch nicht verstanden. So z.B. das du die Pins mit "constexpr" definierst. Ich konnte den Befehl auf der Arduinoseite "Sprach-Referenz" nicht finden. Genau wie den Befehl "enum" in Zeile 19 für "state" welche du in "switch" benutzt hast.

Leider funktioniert der Code noch nicht so wie erhofft. Der "endlagenSchalterPin {8}" wechselt andauernd von HIGH auf LOW und zurück wenn der Schalter aus ist. Ist der Schalter betätigt bleibt er auf LOW.

Ich versuche mal weiter ob ich selber herrausfinde wo der Fehler liegt.

Hier wird dir geholfen:

https://www.learncpp.com/

korrigiere mal nach

pinMode(endlagenSchalterPin, INPUT_PULLUP);

Gruß Tommy

Die zeigt nur einen winzigen Ausschnitt, von dem was möglich ist.
evtl. möchtest du eins dieser schönen, dicken und modernen C++ Grundlagenbücher lesen

Alternativ:
https://en.cppreference.com/w/cpp/language/switch

Vielen dank, aber meine Englischkenntnisse sind nicht sonderlich gut. In vielen Fällen kann ich mir zwar mit DeepL.com helfen, aber wenn es sich vermeiden lässt versuche ich deutschsprachig zu bleiben.

Dann wirst Du in der Programmierung meist schlechte Karten haben (zumindest online). Da bleiben dann nur die Bücher (z.B. dieses).
Achtung: Da geht es um die Sprache C++, Arduino wird dort nicht erwähnt.

Gruß Tommy

Och, nicht aufgeben.

Übung macht den Meister.
Der Sprachumfang ist relativ gering gehalten, wie das so bei technischen Sachen ist.

Ja, Danke. Das hat geholfen. Funktioniert zwar noch immer nicht ganz so wie ich mir das Vorstelle, aber ich will mal schauen ob ich das jetzt selber hinbekomme.

Ich danke allen die mir hier soweit geholfen haben.