Impuls ausgeben ohne delay

Ich möchte an einem Digitalport einen einmaligen 100ms Impuls ausgeben ohne mit delay den Programmfluß zu unterbrechen.

Das Beispiel "BlinkWithoutDelay" schaltet ja nur im Intervall. :o

bool triggered;
unsigned long previousMillis;

void loop()
{
  if (triggered && (millis() - previousMillis > 100 * 1000UL))
  {
     digitalWrite(13, LOW);
     triggered = false;
  }
}

void trigger()
{
  digitalWrite(13, HIGH);
  triggered = true;
  previousMillis = millis();
}

Wenn du trigger() aufrufst wird die if-Abfrage einmal durchlaufen

1 Like

"Wenn du trigger() aufrufst wird die if-Abfrage einmal durchlaufen"

Hab bestimmt was falsch verstanden aber: ::slight_smile:

Unter "trigger()" ist doch keine if-Abfrage!? LED bleibt auch dauerhaft an...

Ach. Ich Idiot. Ich habe die Zeit aus Versehen auf 100s gestellt. Da kann man warten :-*

Das * 1000UL muss raus. Dann geht es

100 * 1000UL

Das sind 100 Sekunden, aber sonst ist alles richtig.(soweit ich das erkennen kann)
Und ja, ich sehe da eine IF Abfrage.
Und die wird auch nur 1 mal pro Trigger Aufruf durchlaufen.

Wieso verstehst du den Code nicht?
Welche Grundlagen fehlen da noch?
Wie kann man dir da aufs Pferd helfen?

PS:
Teilweise zu spät, aber was solls...
(Der Rest ist sowieso viel wichtiger)

Unter "trigger()" ist doch keine if-Abfrage!? LED bleibt auch dauerhaft an...

die IF Abfrage ist nicht in der Funktion trigger(), sondern in der loop(), die aber nur nach dem Aufruf von trigger(), durchlaufen wird,

Ähhh, was? :grin:

Ich dachte:

Erst wird setup durchlaufen, dann loop. Funktionen nur nach Aufruf der Funktion z.B. aus loop heraus.

Woher soll ich trigger aufrufen wenn nicht aus loop?
loop wird nur nach Aufruf von trigger durchlaufen? Mit welchem Aufruf aus trigger?

Ihr bringt mich ganz schön durcheinander... ::slight_smile:

Du rufst dass da auf wo deinen Impuls auslösen willst. Also z.B. nach einem Tastendruck. Ich habe es dann doch mal mit Serial getestet. Geht genauso. Kann in loop() sein. Kann auch in einer anderen Funktion sein.

loop wird nur nach Aufruf von trigger durchlaufen?

loop() läuft immer. Der millis() Vergleich wird nur gemacht wenn triggered == true

Ihr bringt mich ganz schön durcheinander...

Das ist normal!
Eine Frage des Blickwinkels...
Oder des Standpunkts.

Nö, der Ausgang (LED) wird immer wieder auf HIGH gesetzt. Testsketch dazu:

const byte ledPin = 3;      // LED pin
const byte tasterPin = 2;   // Taster pin
bool triggered;
bool aktTasterZustand;
bool altTasterZustand;
unsigned long previousMillis;

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

void loop()
{
  if (triggered && (millis() - previousMillis > 100))
  {
    digitalWrite(ledPin, LOW);
    triggered = false;
  }
  aktTasterZustand = digitalRead(tasterPin);
  if (aktTasterZustand && !altTasterZustand) {
    trigger();
  }
  altTasterZustand = aktTasterZustand;
}

void trigger()
{
  digitalWrite(ledPin, HIGH);
  triggered = true;
  previousMillis = millis();
}

:confused:

Mein Lösungsansatz:

const byte ledPin = 3;      // LED pin
const byte tasterPin = 2;   // Taster pin
bool oneShot = true;
bool aktTasterZustand;
bool altTasterZustand;
bool trigger;
unsigned long previousMillis;

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

void loop()
{
  if (oneShot) {
    aktTasterZustand = digitalRead(tasterPin);
    if (aktTasterZustand && !altTasterZustand) {
      trigger = true;
      previousMillis = millis();
      digitalWrite(ledPin, HIGH);
    }
    altTasterZustand = aktTasterZustand;
    if (trigger && (millis() - previousMillis > 1000)) {
      digitalWrite(ledPin, LOW);
      oneShot = false;
    }
  }
}

Scheint zu funktionieren :slight_smile:

Dein Taster scheint nicht richtig entprellt zu sein. Das hier geht:

bool triggered;
unsigned long previousMillis;

void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);
}

void loop()
{
  if (Serial.available())
  {
    char c = Serial.read();

    if (c == 'x')
      trigger();
  }

  if (triggered && (millis() - previousMillis > 500))
  {
    digitalWrite(13, LOW);
    triggered = false;
  }
}

void trigger()
{
  digitalWrite(13, HIGH);
  triggered = true;
  previousMillis = millis();
}

500ms statt 100ms damit man es etwas besser sieht. Da sieht man auch dass man nach-triggern kann. Wenn man das verhindern will, dann müsste man die trigger() Funktion noch mit triggered verriegeln.

Serenifly:
Dein Taster scheint nicht richtig entprellt zu sein. Das hier geht:

Der Taster ist ein PIR wegen eines anderen Themas, da sollte nichts prellen.

Serenifly:
Da sieht man auch dass man nach-triggern kann. Wenn man das verhindern will, dann müsste man die trigger() Funktion noch mit triggered verriegeln.

Ich hatte "einmalig" in der Fragestellung so verstanden, daß ein Nachtriggern ausgeschlossen sein soll. Wenn Nachtriggern erlaubt sein soll, dann funktioniert Dein Beispiel wunderbar!

Der Themensteller hat ja nun was zum Aussuchen :slight_smile:

Das Thema wurde gar nicht angesprochen. Gibt Anwendung für beides

Wenn man es nicht will dann einfach so:

void trigger()
{
  if (triggered == false)
  {
    digitalWrite(13, HIGH);
    triggered = true;
    previousMillis = millis();
  }
}

Da braucht man keine extra Variable

Noch nicht ganz, aber so:

bool triggered;
unsigned long previousMillis;

void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);
}

void loop()
{
  if (Serial.available())
  {
    char c = Serial.read();

    if (c == 'x')
      trigger();
  }

  if (triggered && (millis() - previousMillis > 500))
  {
    digitalWrite(13, LOW);
  }
}

void trigger()
{
  if (triggered == false)
  {
    digitalWrite(13, HIGH);
    triggered = true;
    previousMillis = millis();
  }
}

Serenifly:
Da braucht man keine extra Variable

Du hast natürlich meine Schwachstelle entdeckt, der Pokal gehört Dir :grin:

Damit das einmal und nie wieder geht? So wörtlich hatte ich das nicht verstanden :slight_smile:

"Nach-triggern" bei Monoflops bedeutet übrigens dass man innerhalb des Impulses nochmal triggern kann um die Impulsdauer zu verlängern. Eine Anwendung für sowas ist z.B. eine Aktivitätsanzeige. Man triggert ein Monoflop von einer Quelle wie einem Drehzahlmesser. Wenn die Trigger-Impulse innerhalb der Impuls-Zeit kommen, bleibt der Ausgang High. Wenn sie zu langsam kommen fällt der Ausgang auf Low ab.

Ich hatte gehofft, es merkt niemand, da mir keine bessere Formulierung eingefallen war. Der Kontext sollte aber möglicherweise klar machen, was gemeint ist. ::slight_smile:

Ich brauche das um einen Tastendruck zu simulieren.

Also einmal und nie wieder stimmt nicht sondern: Einmal und irgendwann wieder.

Wie denkt ihr? Nachtriggern oder nicht?

Nachtriggern oder nicht?

Woher sollen wir das wissen, welche Auswirkungen diese Entscheidung für dein Projekt hat?

Ich würde denken: Keine.

Weil nach dem simuliertem Tastendruck das "On" eh verriegelt wird und nur durch ein Impuls auf einem anderen Eingang wieder auf "Off" geht...

Beide eurer Vorschläge funktionieren. Und ich hab sie jetzt auch so halbwegs verstanden :grin: .

Danke!!

const byte ledPin = 13;      // LED pin
const byte tasterPin = 2;   // Taster pin
int buttonState = 0;         // variable for reading the pushbutton status
bool triggered;
unsigned long previousMillis;

void setup()
{
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);
  Serial.begin(9600);
  pinMode(13, OUTPUT);
}

void loop()
{
  buttonState = digitalRead(tasterPin);
    if (buttonState == HIGH) {
      trigger();
  }

  if (triggered && (millis() - previousMillis > 500))
  {
    digitalWrite(13, LOW);
    triggered = false;
  }
}

void trigger()
{
  digitalWrite(13, HIGH);
  triggered = true;
  previousMillis = millis();
}

Hab aber die TastenZustandsAbfrage rausgenommen - will ja Variablen sparen.. Und auf L-Impuls umgestellt.

const byte ledPin = 13;      // LED pin
const byte tasterPin = 2;   // Taster pin
int buttonState = 0;         // variable for reading the pushbutton status
bool trigger;
unsigned long previousMillis;

void setup() {
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);
}

void loop()
{
    buttonState = digitalRead(tasterPin);
    if (buttonState == HIGH) {
      trigger = true;
      previousMillis = millis();
      digitalWrite(ledPin, LOW);
    }
    if (trigger && (millis() - previousMillis > 1000)) {
      digitalWrite(ledPin, HIGH);
      //oneShot = true;
    }
}