Led bei Tasten druck an und nach Verzögerung aus.

Vielen lieben Dank für eure Hilfe.
Ich habe es nun so gemacht das die Led 5sek an ist und nach dem abschalten 2 sek nichts passiert.
Nun ist es aber so wenn beim einschalten des arduino der Schalter schon HIGH ist, und die Led den durchgehend leuchtet bis der schalter einmal betätigt ist dann funktioniert alles Tadellos.

Wie kann man das Problem Lösen? habe da keinen Ansatz :confused:

const byte butonpin = 9;// Taster schaltet nach GND
const byte led = 10; // uno interne LED
bool butonstat;
bool lastbutonstat; //hilfsmerker für Flanke

void setup() {
  pinMode(butonpin, INPUT_PULLUP);
  pinMode(led, OUTPUT);
}

void loop() {
  butonstat = digitalRead(butonpin);
  //butonstat = !digitalRead(butonpin);// invertiert einlesen

  if (butonstat & !lastbutonstat) { // Flanke erkannt
    lastbutonstat = HIGH; // Flankenmerker setzten
    digitalWrite(led,LOW );
    delay(5000);
    digitalWrite(led, HIGH);
    delay(2000);
  }
  if (!butonstat) lastbutonstat = false; // Flankenmerker zurück
}

Hi

-den ... + dann ??

Wenn, dann: Lese buttonstate im setup ein und setze lastbuttonstate auch auf Diesen.
So muß der Button erst gelöst werden, bevor beim erneuten Drücken die Flanke erkannt wird.

MfG

Hallo,

du musst dir die Zeit merken. Dafür gibts millis. Mit den delays wird das alles unbedienbar, weil blockierend.

Theseus erklärt millis()

GuntherB - BlinkwithoutDelay - Die Nachtwächtererklärung

deins umgebaut wie es verstanden habe, ansonsten millis verstehen und abändern

const byte pinTaster {9};       // Taster schaltet nach GND
const byte pinLed {10};         // uno interne LED

void setup() {
  pinMode(pinTaster, INPUT_PULLUP);
  pinMode(pinLed, OUTPUT);
}

void loop(void) {
  
  bool state = updateTaster(pinTaster);   

  switchLed (pinLed, state, 5000);
}


// ****** Funktionen ******

bool updateTaster (const byte pin)                        
{
  static unsigned long last_ms {0};
  static bool state {HIGH};
  
  unsigned long ms {millis() };
  
  if (ms - last_ms >= 30)
  {
    last_ms = ms;
    state = digitalRead(pin);
  }

  return state;
}


void switchLed (const byte pin, bool stateTaster, const unsigned int zeit)
{
  static unsigned long last_ms {0};  
  unsigned long ms {millis() };
    
  if (!stateTaster)
  {
    last_ms = ms;
    digitalWrite(pin, HIGH);
  }

  if (ms - last_ms >= zeit)
  {
    digitalWrite(pin, LOW);
  }
}

michael_x:
warning: narrowing conversion of '60000l' from 'long int' to 'int' inside { } [-Wnarrowing]
Ist übrigens keine 600001 sondern 60000L und zeigt, dass das Aufweiten entsprechend dem Standard super funktioniert. 60000 wird (beim Uno/Nano/Mega) übrigens auf long und nicht auf unsigned int aufgeweitet.

Ja manche Aussagen beschäftigen mich länger. Ich denke ich weiß jetzt wie es gemeint ist. Die 60.000 werden zuerst als long interpretiert (aufgeweitet :slight_smile: ) dann mit dem Variablentyp int verglichen, dabei wird festgestellt passt nicht rein und die Warnung generiert. :grinning:

@Doc_Arduino
Erst mal vielen dank für deine Hilfe, bin grade dabei deinen Sketch zu verstehen aber er funktioniert in der Praxis nur wie ein Anschaltverzögerung, Weiter habe ich noh nicht durchgeblickt.

Hallo,

bei dir verhält sich mein Bsp. wie eine Einschaltverzögerung? :o Das kann nicht sein, weil es eine Ausschaltverzögerung ist, wie ein Hauslicht. Davon abgesehen. Wie soll es sich denn verhalten?

Sooo, Ich habe da was hinbekommen aber ist es möglich das der sketch nicht wie eine dauerschleife durch läuft sondern nur einmal?

Habe eine Lösung aber Ich habe ein Klammer Problem und sehe den Fehler nicht :confused:

#include <Bounce2.h>
int i = 0;
byte Taster_Heizung = 9;               // Taster an Pin 6 gegen Masse
#define Heizung_Pin 10                 // Schaltpin Heizung ein/aus
#define Heizungeinschaltdauer 4000 // maximale Pumpenlaufzeit
#define INPUTMODE INPUT_PULLUP  // INPUT or INPUT_PULLUP
Bounce debouncer2 = Bounce();        // Instantiate a Bounce object Nr.2 ( Taster Heizung )

void setup()  {
  for (int i = 0; i < 3; i++)
  {
    digitalWrite(Heizung_Pin, LOW);        // Schaltpin Heizung aus
    pinMode(Heizung_Pin, OUTPUT);          // Schaltpin Heizung Ausgang

    // digitalen Eingang mit PullUp aktivieren
    pinMode(Taster_Heizung, INPUT);        // setzt Taster Pin als Eingang
    digitalWrite(Taster_Heizung, HIGH);// und aktiviert dessen PullUp Widerstand
    pinMode(Heizung_Pin, INPUTMODE);

    debouncer2.attach(Taster_Heizung);
    debouncer2.interval(30);             // Entprellzeit 30ms für den Taster

  }   // Ende setup


  void loop(void)
  {
    if (i == 0) {
      i++;
      Heizung_schalten();  // Heizung ein- oder ausschalten mittels Taster
      // Ende loop

    }
    /* ------------------------------------------------------------------------------------------------ */


    void Heizung_schalten () {


    }
    boolean stateChanged_2 = debouncer2.update();
    static boolean state_Heizung = LOW;
    static unsigned long millis_now = 0;
    int state_2 = debouncer2.read();

    // wenn LOW Signal vom Taster erkannt, schalte Heizung ein bzw. mit nächsten HIGH wieder aus
    if ( stateChanged_2 && state_2 == HIGH ) {
      if ( state_Heizung == HIGH ) {
        state_Heizung = LOW;                             // Tasterdruck, Heizung einschalten
        millis_now = millis() + Heizungeinschaltdauer;   // maximale Einschaltdauer setzen
      }
      else {
        state_Heizung = LOW;              // erneuter Tasterdruck, Heizung ausschalten
      }
      digitalWrite(Heizung_Pin, state_Heizung);

    }

    {
         // wenn Heizung läuft, dann nach eingestellter Zeit selbst wieder ausschalten
        if (millis() > millis_now)  {
          digitalWrite(Heizung_Pin, HIGH); // ausschalten nach x sec.
          state_Heizung = HIGH;

        }

Hallo,

das fehlen des Sketches hätte beinahe diplomatische Verwirrungen gestiftet. :slight_smile:

Jetzt muss ich aber ernst werden.
Was macht das globale i? Zudem signed. Für die loop Abfrage nicht sinnvoll.
Du weißt wie schnell die loop durchlaufen wird und damit i inkrementiert?
Das würde deine vorherige Frage erklären.
Lass das i weg.

Habe das Offentsichtliche korrigiert, aber ungetestet.
Edit: noch die überflüssige for in setup entfernt

#include <Bounce2.h>

const byte Taster_Heizung = 9;               // Taster an Pin 6 gegen Masse
const byte Heizung_Pin = 10;                 // Schaltpin Heizung ein/aus
const unsigned int Heizungeinschaltdauer = 4000; // maximale Pumpenlaufzeit

Bounce debouncer2 = Bounce();               // Instantiate a Bounce object Nr.2 ( Taster Heizung )

void setup()
{
    digitalWrite(Heizung_Pin, LOW);         // Schaltpin Heizung aus
    pinMode(Heizung_Pin, OUTPUT);           // Schaltpin Heizung Ausgang

    // digitalen Eingang mit PullUp aktivieren
    pinMode(Taster_Heizung, INPUT);         // setzt Taster Pin als Eingang
    digitalWrite(Taster_Heizung, HIGH);     // und aktiviert dessen PullUp Widerstand
    pinMode(Heizung_Pin, INPUT_PULLUP);

    debouncer2.attach(Taster_Heizung);
    debouncer2.interval(30);                // Entprellzeit 30ms für den Taster
}   // Ende setup


void loop(void)
{
    Heizung_schalten();  // Heizung ein- oder ausschalten mittels Taster
    
} // Ende loop


/* ------------------------------------------------------------------------------------------------ */


void Heizung_schalten ()
{
  bool stateChanged_2 = debouncer2.update();
  static bool state_Heizung = LOW;
  static unsigned long millis_now = 0;
  bool state_2 = debouncer2.read();

  // wenn LOW Signal vom Taster erkannt, schalte Heizung ein bzw. mit nächsten HIGH wieder aus
  if ( stateChanged_2 && state_2 == HIGH )
  {
    if ( state_Heizung == HIGH )
    {
      state_Heizung = LOW;                             // Tasterdruck, Heizung einschalten
      millis_now = millis() + Heizungeinschaltdauer;   // maximale Einschaltdauer setzen
    }
    else
    {
      state_Heizung = LOW;              // erneuter Tasterdruck, Heizung ausschalten
    }
    digitalWrite(Heizung_Pin, state_Heizung);
  }

  // wenn Heizung läuft, dann nach eingestellter Zeit selbst wieder ausschalten
  if (millis() > millis_now)
  {
    digitalWrite(Heizung_Pin, HIGH); // ausschalten nach x sec.
    state_Heizung = HIGH;

  }
}

Au man !

In der Loop wird nur einmal "HeizungSchalten" aufgerufen und dann nie wieder.
Weil du ja nur bei i==0 da rein gehst und dann nie wieder.

In der Funktione Heizungschalten machst du sofort nach { wieder }
das das der Compiler nicht mag ist kein Wunder.

Ulli

@Doc_Arduino Also den überholten Sketch habe Ich getestet leider passiert dort beim betätigen des Schalters gar nichts.

@beeblebrox
Ok bin mir aber nun nicht sicher muss das i==0 nun nach unten in den sketck wenn man es so macht?

Hallo,

ich habe deinen Sketch auch nur soweit korrigiert das er fehlerfrei kompliert. Das bedeutet nicht das er danach funktioniert. Denn ich weiß bis heute nicht was du vor hast. Mein Bsp. der Ausschaltverzögerung hatte leider nicht geholfen.

Wegen dem i. Was soll das denn bewirken? Du erhöhst i von 0 auf 1 und fragst auf Gleichheit 0 ab. Das heißt alles danach wird nie wieder abgearbeitet.

Selbst wenn du auf größer 0 abfragst bringt das nichts.
Dann inkrementierst du in Atmeberaubender Geschwindigkeit i. i ist signed.
https://www.arduino.cc/reference/de/language/variables/data-types/int/
Das heißt wenn i größer 32767 springt es ans negative Ende des Wertebereiches. Nennt sich Überlauf.
Wegen der Abfrage > 0 wird ab dem Zeitpunkt auch nichts nachfolgendes mehr ausgeführt.
Aus meiner Sicht ist i überflüssig wenn du keine Erklärung dafür hast.

Dein Sketch ist so nicht falsch, nur weiß Ich nicht wie ich es am besten ändere so das wenn der Taster nicht mehr gedrückt ist das Relais anschaltet und nach einer gewissen zeit wieder aus. Habe es schon mit millis probiert aber irgendwas mache ich Falsch. Bei mir ist es so wenn der Taster nicht gedrückt ist dann ist das Relais immer aktive.

Hallo,

dann musst du nur die Logik entsprechend abändern.
Wie schaltet dein Taster?
Wie schaltet dein Relais?

Gedacht war das der Taster (Pin 9) im nicht betätigten zustand 60sec.
den Pin 10 ansteuert (Pin 10 Steuert das Relais) nach abfaul der Zeit soll der Pin wieder auf LOW geätzt werden und erst beim nächsten Neustart des Arduino wieder Starten ,wenn der Taster nicht betätigt ist.

Hi

Diese Aussage ist noch nicht Eindeutig.
Gilt dieses 10 Sekunden leuchten NUR beim Einschalten?
Also:
Start
Ist Pin NICHT gedrückt, dann 10 Sekunden leuchten
danach ganz normal den Sketch abarbeiten ...

Spielt danach der Button noch eine Rolle?
Oder anders: WAS willst Du wirklich? Was soll's werden, wenn's groß ist?

Erkläre mir den Ablauf so, wie Du Diesen Deiner Oma erklären würdest.
Wenn Sie Deinen Ausführungen folgen kann, sollten wir hier damit auch keine Probleme haben.
Rubber_duck_debugging
(gibt's auch in Deutsch, dort dann links unten auf DEUTSCH klicken)

MfG

@Diter: Evtl. solltest Du die Fragen, die Dir gestellt werden auch verstehend lesen. Ebenso das, was Du schreibst vor dem Absenden. Das verbessert die Kommunikation.

Wann Deine Zeit abfault und wann Deine Pins auf LOW geätzt werden war jedenfalls nicht gefragt.

Gruß Tommy

Also Ich hoffe es ist so für alle verständlich.

Der Arduino ist eingeschaltet, und wenn nun der Taster betätigt ist dann soll nichts passieren.
Wird der Taster aber nun losgelassen dann soll das Relais (Pin 10) für 60sec eingeschaltet werden.
Wenn nun diese 60sec abgelaufen sind soll es wieder abschalten, und erst wenn der Arduino neu gestartet wird wieder Funktionieren.

Pin9 (der Taster) ist ein Schwimmer der bei zu geringen Wasserstand die Pumpe über Pin10 (das Relais) einschalten soll. Ich hoffe Ich habe es jetzt verständlich erklärt, es war nicht meine Absicht euch zu verwirren oder so, Tut mir leid.

Wenn Du endlich mal die Fragen von Doc_Arduino aus #33 beantworten würdest, könntest Du schon viel weiter sein.

Gruß Tommy

Aber warum soll der Arduino denn immer wieder (und von wem) abgeschaltet werden ?

Ulli