LED LEuchtdauer

möglicherweise reden wir aneinander vorbei.

im Code steht:

digitalWrite(ledPin, HIGH);
previousMillis = millis(); // Einschaltzeit "merken"

du fragtest

Warum ? Ist die Einschaltzeit nicht die Zeit wo ich den Taster betätige ?

die blaue Zeile schaltet den Taster ein.
die rote Zeile merkt sich unmittelbar danach die Zeit.
Das sind zwei Anweisungen.
Gleichzeitig, oder "auf einmal" geht nicht.
Die blaue Zeile merkt sich keine Zeit.
Daher brauchst du die rote auch.
Verständlich?

odi77:
Nur bei dem 02 kenn ich mich gar nicht aus wüsste nicht wo ich da Parameter ändern muss das ich da was zum laufen bekomme.

Eigentlich musst Du nur die Pinnummern am Amfang anpassen. Aber ich habe gesehen, dass Du nicht den eingebauten PullUp Widerstand verwendest, sondern mit einem externen PullDown arbeitest.

Aber im Prinzip ist es dasselbe wie der Sketch von noiasca, nur dass man sich nicht direkt mit millis() rumschlagen muss:

#include <MobaTools.h>

const int buttonPin = 12;
const int ledPin = 2;

MoToTimer Blinkzeit1;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT);
}

void loop() {
  if (digitalRead(buttonPin) == HIGH) {
    digitalWrite(ledPin, HIGH);
    Blinkzeit1.setTime( 60000L );
  }

  if ( Blinkzeit1.expired() ) 
  {
    digitalWrite(ledPin, LOW);
  }
}

@ noiasca

Sie merkt sich die Zeit wann ich den Schalter betätigt habe und ab da läuft dann die vorgegebene Zeit ? Ist die vorgegebene Zeit die Zeit die es sich merkt oder um welche Zeit geht's da ?Ich glaub da blick ich nicht ganz durch mehr, war jetzt alles schon bissi viel. Entschuldigung...

@Microbahner

Soweit so gut, funktioniert auch problemlos. Was ich nicht verstehe ist allerdings warum es mit Blinkzeit angegeben ist, es blinkt ja nix.

Eine Frage hab ich jetzt zusätzlich noch. Wenn jetzt zb was schief läuft sagen wir mal mit einem Servo das wo was hängt oder so. Kann ich den Taster auch ZUSÄTZLICH damit belegen das er bei neuer Betätigung das Zeitprogramm unterbricht ?

jein.

geh den Code Schrittweise durch, der Controller machts auch nicht anders.

der loop läuft
if (digitalRead(buttonPin) == HIGH) {

ist der erste if true, werden die blaue und rote Zeile ausgeführt.

millis sagen wir hat zu dem Zeitpunkt den wert 2000 also steht in previousMillis auch 2000.

Dann komm es zum zweiten if

millis wird vieleicht schon auf 2002 stehen,

if (millis() - previousMillis > 60 * 1000UL && digitalRead(ledPin) == HIGH) // wenn Zeit abgelaufen und die

(2002 - 2000 > 60 * 1000UL)

also
(2 > 60000)
nein ist nicht. Daher wird der if nicht ausgeführt.

Wir kommen ans ende von loop.
Daher beginnt es wieder von vorne:

erster grüner If ... der Taster ist nicht gedrückt, der Controller geht also drüber
zweiter if

millis hat jetzt etwa 2015
also

if (2015-2000 > 60000)

nein ist immer noch nicht erfüllt.
Zum Ende von loop.
Wieder an den Anfang von loop.
erster If
Zweiter if
etc

Das passiert viele tausende male.
Bis millis mindestens 62.001 ist

ab dann wird diese Bedinung true:
if (62001- 2000 > 60000)

ausrechnen:
60001 > 60000
Bingo! der if ist erfüllt.
JETZT nach 60001 Millisekunden, gehen wir in den zweiten If und schalten die LED aus.
"Systemzeit" ist also 62001, eingeschaltet haben wir um 2000. Also passt. Nach einer Wartezeit von 60 Sekunden haben wir die LED ausgeschaltet.

So, jetzt erfindest einen neuen Zeitstempel wann du die Taste drückst und spielst es selber 60TSD mal durch

odi77:
Was ich nicht verstehe ist allerdings warum es mit Blinkzeit angegeben ist, es blinkt ja nix.

Namen sind Schall und Rauch :wink: . Wenn Du immer wieder den Taster drückst blinkt es ja 8) .
Du kannst es ja einfach anders benennen.

odi77:
Eine Frage hab ich jetzt zusätzlich noch. Wenn jetzt zb was schief läuft sagen wir mal mit einem Servo das wo was hängt oder so. Kann ich den Taster auch ZUSÄTZLICH damit belegen das er bei neuer Betätigung das Zeitprogramm unterbricht ?

Du meinst, wenn Du drückst während die Zeit läuft, dass dann die Led vorzeitig ausgeht?

@ noiasca

Okee Dankeschön, jetzt raucht mir der Kopf aber ich werd schon dahinterkommen. Fürn Anfang ist das schon ganz schön harter Stoff haha...

@MicroBahner

Verstehe, weil es ja jedesmal auslöst wenn ich drücke kann man es als blinken definieren.

Ja als so eine Art Schutzabschaltung. Sollte dann aber wieder ganz normal laufen bei neuerlicher Betätigung. Aber ich denke mal das würde jetzt den Rahmen sprengen, bin so froh schon über das was ich jetzt schon von euch an Hilfe bekommen habe.

Wie gesagt, sieh Dir den „endlichen Automaten“ als Strickmuster an. Gleichzeitig ablaufende Dinge sind damit gut in den Griff zu bekommen.

Gruß

Gregor

Werd mal schauen was ich darüber finde, Dankeschön.

odi77:
Ja als so eine Art Schutzabschaltung. Sollte dann aber wieder ganz normal laufen bei neuerlicher Betätigung.

Dann wird es ein wenig komplizierter, da Du dann eine Flankenerkennung am Taster brauchst. Und dann must Du ihn auch entprellen. Das könnte dann so aussehen:

#include <MobaTools.h>

const int buttonPin = 12;
const int ledPin = 2;

MoToTimer Blinkzeit1;
bool buttonState = false;       // zur Flankenerkennung

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT);
}

void loop() {
  //Flankenerkennung am Taster
  bool buttonEdge = false; // wird nur im Moment des Drückens true
  if ( digitalRead(buttonPin) == HIGH && buttonState == LOW ) {
    buttonState = HIGH;
    buttonEdge = HIGH;
  } else if ( digitalRead(buttonPin) == LOW ) {
    buttonState = LOW;
  }
  delay(20); // zum Entprellen - hier ganz einfach mit einem kleinen delay realisiert


  if ( buttonEdge ) {
    // Taster wurde gedrückt
    if ( Blinkzeit1.running() ) {
      // Zeit läuft, abbrechen
      Blinkzeit1.stop();
      digitalWrite(ledPin, LOW);
    } else {
      // Zeit läuft nicht, neu starten
      digitalWrite(ledPin, HIGH);
      Blinkzeit1.setTime( 60000L );
    }
  }


  if ( Blinkzeit1.expired() ) {
    digitalWrite(ledPin, LOW);
  }

}

odi77:
Werd mal schauen was ich darüber finde, Dankeschön.

Meine Lieblingslinks dazu:
Die Nachtwächter-Erklärung
Eine Anleitung von agmue (auch hier im Forum)
Mein Gesabbel zum Thema

und wenn Du's eher trocken magst:

Gruß

Gregor

@MicroBahner

Funktioniert einwandfrei, muss aller ehrlich sein das ich den Sketch nicht ganz verstehe. Wie kann ein einfaches delay zum entprellen dienen. Hab mir dazu einige Videos schon angesehen aber da war das wesentlich komplizierter.
Bin es bis dato gewohnt also die paar Tage in denen ich das jetzt mache das ich mit delay eine Laufzeit definiere. Woher weiß nun das Programm das gerade dieses delay als entprellen dient ?

@ gregorss

Fein fein da hab ich einiges zum lesen und lernen, Dankeschön.

Um einen mechanischen Taster zu entprellen, musst Du nur dafür sorgen, dass Du ihn nicht zu häufig abfragst. Wenn die Durchlaufzeit deines loop() nicht sehr kritisch ist, reicht es also aus, einfach die Durchlaufzeit etwas zu verzögern. Das macht das delay(20). Damit wird der Taster nur noch alle 20ms abgefragt, und das reicht zum Entprellen.
Edit: es ist deshalb auch vollkommen egal, wo das delay(20) im loop steht ( Ok, nicht in einer if-Abfrage :wink: ). Hauptsache die Durchlaufzeit wird größer.
Ist die loop-Zeit kritisch, und du kannst dir da keine 20ms Umlaufzeit leisten, wird es komplizierter, denn dann musst Du dafür sorgen, dass der Taster nicht mehr in jedem loop-Durchlauf abgefragt wird.

denn dann musst Du dafür sorgen, dass der Taster nicht mehr in jedem loop-Durchlauf abgefragt wird.

Oder eben die Entprellung "anders" bauen, so dass sie das überlebt.

@combie & MicroBahner

Wohl ein Thema mit dem ich mich noch ausführlicher beschäftigen werde bzw muss. Ist ja generell sehr vielfältig denk aber das ich mich für die paar Tage schon ganz gut schlage. Ist ja auch ne feine Sache u d interessant. Allein heute Sitz ich schon seit 0700 dran.

Na dann erstmal weiterhin viel Spaß. Arduino und Modellbahn passen jedenfalls sehr gut zusammen 8)

Gute Morgen, eine Frage hat mich in der Nacht noch ein wenig beschäftiget. Bei meiner Modellbahn hab ich dann ja mehrere solcher Tasteraktionen, wie schaffe ich es da jetzt auch mehrere Sketches gleichzeitig am arduino am laufen zu haben. Bis jetzt hab ich ja immer nur einen hochgeladen.

du kannst nur "einen" Sketch hochladen.

Du kannst mit viel Wissen aber all deine Sketches zu einem großen Monster zusammenfügen und dann am Arduino laden.

so wie es bei Franz-Peter aufgebaut ist, sollte es ein leichtes sein, weitere Taster, weitere LEDs hinzuzufügen.

Ich würde es an deiner Stelle dennoch noch zu Fuß machen um Sicherheit mit dem Umgang von millis() zu bekommen.

zunächst mal alles was zusammengehört in eine eigene Funktion geben

/*
  by noiasca
*/

const int buttonPin = 12;
const int ledPin = 2;

void handleButtonAndLed()              // eine zusammenfassende Funktion die den Button ausliest und gegebenenfalls die LED abschaltet
{
  static uint32_t previousMillis = 0;  // du brauchst eine unsigned integer Variable mit 32bit/4Byte, weil millis() auch so groß werden kann.
  if (digitalRead(buttonPin) == HIGH) {
    digitalWrite(ledPin, HIGH);
    previousMillis = millis();   // Einschaltzeit "merken"
  }
  if (millis() - previousMillis > 60 * 1000UL && digitalRead(ledPin) == HIGH)  // wenn Zeit abgelaufen und die LED leuchtet
  {
    digitalWrite(ledPin, LOW);
  }
}

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT);
}

void loop() {
  handleButtonAndLed(); // den handle so oft wie möglich im loop aufrufen. 
}

Wenn die Logik für die anderen Tasten/LEDs gleich ist, könnte man daraus eine Klasse machen, und dann ist es nur mehr eine Frage von Pin's hinzunehmen und genießen. Wenn du das mit der Funktion verstanden hast, gib bescheid, dann zeige ich dir den nächsten Schritt.

@noisca,
Dann werde ich wohl noch ein paar Monate brauchen um meine Funktionen so steuern können wie ich sie gerne hätte. Macht aber nix will ja auch was lernen dabei. Wie gestern aber schon angemerkt ist das doch schon ganz harter Stoff für jemanden der absolut keine Ahnung hat/hatte von sowas haha

paar Monate ist doch nichts, wie lange hast für deine Bahn gebraucht?