Go Down

Topic: Led bei Tasten druck an und nach Verzögerung aus. (Read 2024 times) previous topic - next topic

Rentner

#15
Nov 25, 2019, 09:55 pm Last Edit: Nov 25, 2019, 10:06 pm by Rentner Reason: code verbessert
Hallo,

basierend auf #13 mit millis(), ist eigendlich ganz einfach  :)

Heinz


Code: [Select]

const byte butonpin = 2;// Taster schaltet nach GND
const byte led = 13; // uno interne LED
bool butonstat;
bool lastbutonstat; //hilfsmerker für Flanke
unsigned long altzeit;

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 = true; // Flankenmerker setzten
    altzeit = millis();   // Zeit starten
    digitalWrite(led, HIGH);
  }
  if (!butonstat) lastbutonstat = false; // Flankenmerker zurück

  if (millis() - altzeit > 5000UL) { // led für 5s ein
    digitalWrite(led, LOW);
  }
 
}





postmaster-ino

@Diter
Drücke in der IDE Mal STRG+T - Das rückt den Code auf Klammer-Ebene ein.
Wenn Du dann mehrere Klammern direkt ganz vorne untereinander hast - oder gaaanz unten steht KEINE Klammer ganz vorne - ist wohl was faul.

Auch sind die ganzen Klammern in und um Deine IFs ... äh ... verwirrend - nicht zwingend für mich, für Dich aber mit Sicherheit!
Auch hat ein ; hinter der IF-Abfrage NICHTS verloren - dort ist die IF nämlich zu Ende - die Klammer drunter hat nur den Zweck, daß der Bereich eben vom Rest abgekapselt ist (eigene lokale Variablen z.B.) - mehr aber nicht.

mfG
Dein Problem, Dein Sketch, Deine Bilder.
Ob ich ohne Diese an Deinem Problem arbeiten will, entscheide aber immer noch ich.
Große Buchstaben? Immer wieder, neben Punkt und Komma, gerne gesehen.

Doc_Arduino

Hallo,

wegen den fehlenden Warnungen. Deshalb sollte man nach dem aktuell möglichen Syntax programmieren.
Bsp.
Code: [Select]

int a {60000};

void setup(void) {
  Serial.begin(250000);
}

void loop(void) {
  Serial.println(a);
}
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

michael_x

Quote
Deshalb sollte man nach dem aktuell möglichen Syntax programmieren.
Danke für den Tip. Ja.

  int delaytime {60000};
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.


Doc_Arduino

Hallo,

wie meinst du das mit "wird aufgeweitet"? Missverständnis? Dein Compiler ändert doch nicht etwa eigenmächtig den Datentyp? Die Warnung lese ich wie folgt. Die 60.000, was eigentlich long ist, wird fälschlicherweise in ein int gepresst was nicht rein paßt. Davor wird man gewarnt. from long to int. Wenn man das testet erhält man auch falsche -5536.
Oder habe ich dich falsch verstanden? Soll ja vorkommen.  ;)
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Diter

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  :smiley-confuse:

Code: [Select]
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
}

postmaster-ino

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
Dein Problem, Dein Sketch, Deine Bilder.
Ob ich ohne Diese an Deinem Problem arbeiten will, entscheide aber immer noch ich.
Große Buchstaben? Immer wieder, neben Punkt und Komma, gerne gesehen.

Doc_Arduino

Hallo,

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

Theseus erklärt millis()
http://forum.arduino.cc/index.php?topic=400102.msg2752141#msg2752141

GuntherB - BlinkwithoutDelay - Die Nachtwächtererklärung
http://forum.arduino.cc/index.php?topic=423688.0

deins umgebaut wie es verstanden habe, ansonsten millis verstehen und abändern
Code: [Select]

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);
  }
}
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Doc_Arduino

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  :) ) dann mit dem Variablentyp int verglichen, dabei wird festgestellt passt nicht rein und die Warnung generiert.   :smiley-lol:
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Diter

@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.

Doc_Arduino

#25
Nov 27, 2019, 10:53 pm Last Edit: Nov 27, 2019, 10:54 pm by Doc_Arduino
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?
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Diter

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

Diter

Habe eine Lösung aber Ich habe ein Klammer Problem und sehe den Fehler nicht :smiley-confuse:
Code: [Select]
#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;

        }

Doc_Arduino

#28
Nov 28, 2019, 09:53 pm Last Edit: Nov 29, 2019, 10:52 am by Doc_Arduino
Hallo,

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

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

Code: [Select]

#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;

  }
}
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

beeblebrox

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

Go Up