suche Altenative zu delay();

Hallo Zusammen, ich hänge schon wieder.

ich möchte in sehr schneller Abfolge mehrere Ports schalten und abfragen und in einem 2 Sekunden-Takt ein LCD aktualisieren.

Nun dachte ich mir, ich lasse die Endlosschleife (loop()) einfach immer durchlaufen. Bei jedem Durchlauf erhöhe ich einen Zähler. Wenn der Zähler einen bestimmten Grenzwert überschritten hat, rufe ich eine Funktion (für die notwendigne Aktionen) auf und setze den Zähler auf 0 zurück.

Wie häufig wird die loop-Schleife pro Sekunde durchlaufen, mit welchen Werten muss ich arbeiten?

Oder gibt es hier andere Ansätze für die Umsetzung?

Danke im Voraus

suche Altenative zu delay();

Die findest Du in millis()
http://playground.arduino.cc/Learning/BlinkWithoutDelay_de
Grüße Uwe

Hallo,
wurde schon mehrmals (auch heute) besprochen.
Das geht mit millis().
Die Durchläufe der loop zählen ist viel zu ungenau. Das hängt ja von deinem Code ab,
wie oft die loop pro Sekunde durchlaufen wird.
Such mal nach millis(), da ist alles erklärt.
gruß
Bernward

ahhhhhhhhhhhhhh! Uwe war schneller :slight_smile:

Danke,
hätte ich gewust, das es millis() heißt, hätte ich's gesucht und gefunden.

Hatte mir extra das Buch "C programming for Arduino" gekauft. Mal ein Buch ohne Sketche Vordergrund, sondern mit der Programmierung im Vordergrund. Aber von millis() steht nix drin.

Wer kennt mal ein umfassendes Werk, in dem solche Tricks stehen?

Habs gerade gefunden:
Time
millis()
micros()
delay()
delayMicroseconds()

Ich bin schon blind :slight_smile:

maverick1509:
ahhhhhhhhhhhhhh! Uwe war schneller :slight_smile:

tschuldige :.

mcGeorge:
Ich bin schon blind :slight_smile:

Nein, es hatte sich nur vor Deiner Nase versteckt. :wink:
Du kennst ja die Abwandlung des Murphys-Gesetzes zu der Fehler-Suche? Du kannst so lange wie Du willst Fehler suchen, ein anderer findet Dir einen in 5 Sekunden.
Grüße Uwe

mcGeorge:
Oder gibt es hier andere Ansätze für die Umsetzung?

Die millis() Funktion ist ja schon genannt worden. Aber millis() taktet tausendmal pro Sekunde hoch, aus der Funktion mußt Du noch einen sauberen und langsameren Takt ableiten, was durch eine Ganzzahldivision möglich ist.

So erhöht sich der Wert von "millis()/500" alle 500 Millisekunden, also jede halbe Sekunde.
Der Wert von "millis()/3000" erhöht sich alle drei Sekunden.

Für exakte Taktung mache ich mir immer eine Funktion, die sich intern den alten Taktwert merkt, beliebig oft aufgerufen werden kann, aber immer nur bei einer Änderung des Wertes "true" zurückliefert, so dass dann bestimmte Aktionen gestartet werden können.

Codebeispiel mit einem Halbsekundentakt und einem Dreisekundentakt als Demo anbei.

Die loop-Funktion muß man für genau getaktete Funktionen natürlich immer auf maximaler Drehzahl laufen lassen, d.h. keine delays verwenden!

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

boolean halbSekundenTakt()
// liefert true falls seit dem letzten Aufruf die Halbsekunde gewechselt hat
{
  static long alterWert;
  long halbeSekunden=millis()/500;
  if (halbeSekunden!=alterWert)
  {
    alterWert=halbeSekunden;
    return(true);  
  }
  else return(false);
}

boolean dreiSekundenTakt()
// liefert true falls seit dem letzten Aufruf ein neues 3-sec-Intervall begonnen hat
{
  static long alterWert;
  long dreiSekunden=millis()/3000;
  if (dreiSekunden!=alterWert)
  {
    alterWert=dreiSekunden;
    return(true);  
  }
  else return(false);
}



void loop() 
{
  if (halbSekundenTakt())
  {
    Serial.print("1/2 sec Tick ");
    Serial.println(millis());
  }  
  if (dreiSekundenTakt())
  {
    Serial.print("Jetzt sind 3 Sekunden um! ");
    Serial.println(millis());
  }  
  // Rest des loop-Codes hier
}

Der üblichere und deutlich weniger rechenintensive Weg wäre, statt einer Division einfach eine Subtraktion zu nehmen. Der Code der Halbsekundentakt-Funktion sähe dann so aus:

  static long alterWert;
  if (milllis() - alterWert > 500)
  {
    alterWert=millis();
    return(true);  
  }
  else return(false);

Analog für andere Taktungen.