Impuls ausgeben ohne delay ??

Hallo,

bin gerade am tüfteln wie man ab besen einen Impuls ausgeben kann, sagen wir mal 1 oder mehrere sec. lang ohne den ganzen Sketch mit einem delay aufzuhalten. Am liebsten hätte ich gerne eine Funktion die man kurz mal aufruft.

void pulse() {
  digitalWrite(3,HIGH);
  delay (1000);
  digitalWrite(3,LOW);
}

Ich habe das auch schon mit millis probiert - war aber auch nicht besser weil er genauso erst nach Ablauf der Impulszeit zurückkehrt.

Bevor ich jetzt mit einem Timerinterrupt anfange und den Impuls aus ISR Durchläufen erzeuge frage ich ob es dazu nicht eine einfachere Lösung gibt...

Christian

Das BlinkWithoutDelay-Beispiel zeigt Dir, wie Du eine solche Funktion realisieren kannst. Du musst natürlich Zustandsvariablen haben, damit Du weisst, in welchem State Du Dich gerade befindest, das kann im einfachsten Fall aber die gespeicherte millis()-Zeit sein.

Hallo,

ich habe so etwas probiert:

void puls () {
  long saveMillis = millis();
  digitalWrite(3,HIGH);
  while (millis() - saveMillis < 1000) {
  }
  digitalWrite(3,LOW);
}

... aber dann bleibt er so lange im While gefangen bis die Zeit um ist. Das im prinzip selbe geht auch mit "if" :~ =(
Christian

hi,

versuch's mal mit einem if statt while und den pfeil in die andere richtung...

gruß stefan

EDIT: natürlich mußt Du die logik ändern, damit nicht jedesmal die ersten zwei zeilen auch abgearbeitet werden.

Ich habe an sowas gedacht:

void loop() {
  static uint32_t saved_millis() = 0;
  if (pulse_trigger_event) {
    saved_millis = millis();
    digitalWrite(PIN, HIGH);
  }
  if (saved_millis && millis() - saved_millis >= 1000) {
    saved_millis = 0;
    digitalWrite(PIN, LOW);
  }
}

Ist bei längeren Laufzeiten nicht so schön, weil theoretisch millis() zufällig gerade 0 sein könnte, aber das kannst Du mit einer zweiten Variable wenn nötig korrigieren.

Hallo,

ja, so geht das, Danke. Ist aber bei genauer Betrachtung auch nicht perfekt. Wenn die Hauptroutine (aus welchem Grund auch immer) mal einen kleinen Augenblick benötigt dann verzögert sich der Impuls entsprechend.
In vielen Fällen ist das sicher egal, aber präzise ist das nicht wirklich, vor allem wenn nicht jeder loop() Durchlauf gleich lange dauert. :~

Christian

Was ist schon perfekt? Genau damit keine Zyklen so viel länger brauchen vermeidet man ja das delay. Wenn Dein Arduino mit 16MHz läuft, dann kann er pro ms 16 000 Befehle abarbeiten. Das ist schonmal relativ viel an Code. Das heißt nur wenn Du darüber kommst wird es ungenau. Oder Du baust was mit delay oder while ein, dann dauert es auch. Da muss man dann schon vorsichtig sein. Wenn es genauer werden soll, dann muss man sich mit den Timern des ATMegas persönlich auseinandersetzen und evtl. was mit Interupts basteln. Aber für die meisten Anwendungen sollte millis() hinreichend genau sein.

Wenn die Hauptroutine (aus welchem Grund auch immer) mal einen kleinen Augenblick benötigt dann verzögert sich der Impuls entsprechend.

Wenn sie nur einen kleinen Augenblick benötigt, dann ist das kein Problem. Sollte der kleine Augenblick länger als eine Millisekunde sein, dann ist er nicht mehr klein und die Programmierung sollte überdacht werden. Wenn Du Impulse im Sub-Millisekunden-Bereich brauchst, dann solltest Du die mit der Hardware erzeugen und Dich dafür in die Programmierung der Timer- bzw. PWM-Module einlesen.