millis() anstelle von delay()

Programmierung der Arduino UNO, Arduino MEGA, Arduino Nano, ........
Antworten
Benutzeravatar
Admin
Administrator
Beiträge: 342
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

millis() anstelle von delay()

Beitrag von Admin »

Ich habe hier mal ein Programm gemacht, das nur zeigt wie die Zeitkontrolle mit "millis()" funktioniert.

Code: Alles auswählen


// Baudrate fuer Serial Schnittstelle
const int baudSerial = 9600;
// ------Zeitmerker Deklaration ----
unsigned long aktuellezeit = 0;
// ------millis Deklaration 01 -----
unsigned long pausestartzeit01 = 0; // Tastenabfrage von Taster02 300ms aussetzen
const unsigned long pausezeit01 = 1000;
// ------millis Deklaration 02 -----
unsigned long pausestartzeit02 = 0; // Tastenabfrage von Taster02 300ms aussetzen
const unsigned long pausezeit02 = 2000;
// ------millis Deklaration 03 -----
unsigned long pausestartzeit03 = 0; // Tastenabfrage von Taster02 300ms aussetzen
const unsigned long pausezeit03 = 3000;
//-----------------------------------------------------------------------------------
void setup()
{
  // Serial Schnittstelle starten
  Serial.begin(baudSerial);
}
//----------------------------------------------------------------------------------
void loop() {
  // -------aktuelle millis in jedem Loop - Durchgang aktualisieren-----
  aktuellezeit = millis(); // Aktuelle Zeit für alle Millis Aktionen übergeben

//------------------Erste Aktion-------------------------------------------------
  if (aktuellezeit - pausestartzeit01 >= pausezeit01) // Eine Sekunde abgelaufen??
  { 
    //Hier die aktuelle Aktion oder mehr Aktionen einsetzen
    Serial.println(F("1 Sekundentakt"));
    Serial.println(aktuellezeit);
    
    pausestartzeit01 = aktuellezeit; // Neue Pausestartzeit übergeben
  }

//------------------Zweite Aktion-------------------------------------------------
  if (aktuellezeit - pausestartzeit02 >= pausezeit02) // Zwei Sekunden abgelaufen??
  { 
    //Hier die aktuelle Aktion oder mehr Aktionen einsetzen
    Serial.println(F("2 Sekundentakt"));
    Serial.println(aktuellezeit); 
  
    pausestartzeit02 = aktuellezeit; // Neue Pausestartzeit übergeben
  }

//------------------Dritte Aktion-------------------------------------------------
  if (aktuellezeit - pausestartzeit03 >= pausezeit03) // Drei Sekunden abgelaufen??
  { 
    //Hier die aktuelle Aktion oder mehr Aktionen einsetzen
    Serial.println(F("3 Sekundentakt"));
    Serial.println(aktuellezeit);   
 
    pausestartzeit03 = aktuellezeit; // Neue Pausestartzeit übergeben
  }

}
Man kann diesen Grundstock benutzen, um drei Aktionen, bei denen jede für sich, in einem anderen Zeittackt immer wieder laufen sollen, ständig kontrolliert zu wiederholen. Natürlich kann man die Aktionen auch endlos erweitern. Und die Zeiten verändern / anpassen. Hier im Programm ist die einzige Aktion die in diesen Zeittackten stattfinden nur die Serial.println() Ausgabe, dass man sieht wie es abläuft. Der Sekundentakt kommt jede Sekunde, der 2 Sekundentakt alle zwei Sekunden, der 3 Sekundentakt alle drei Sekunden. Da, wo ich immer reingeschrieben habe "//Hier die aktuelle Aktion oder mehr Aktionen einsetzen" schreibt man das rein, was in diesem Zeittakt ablaufen soll. Natürlich darf da auch kein delay() rein, sonst ist alles für´n Arsch. Da kann man Relais einschalten oder ausschalten. LED´s ein oder aus. Daten zu Display´s schicken. Sensoren abfragen. Und vieles mehr. Was man eben in den Zeitabständen machen will.

Die Serial.println() kann man natürlich verschwinden lassen, ausser man will kontrollieren ob alles korrekt abläuft. Die Zeit für die jeweilige Zelle läuft immer wieder neu los, wenn man die "pausestartzeit" an die "aktuellezeit" angleicht. Man kann also z.B. die Zeile "pausestartzeit02 = aktuellezeit;" auch aus der Zelle herausnehmen und wo anders im Loop diese Startzeit aktivieren. Egal wo diese Zeile ausgeführt wird, ab da läuft die Zeit für diese Zelle neu ab, und wird nach Ablauf der zugehörigen "pausezeit" wieder EINMAL ausgeführt.

Benutzeravatar
Admin
Administrator
Beiträge: 342
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: millis() anstelle von delay()

Beitrag von Admin »

Hier habe ich mal die erste Aktion geändert. In dieser ersten Aktion wird ein Taster auf Pin.12 abgefragt ob er gedrückt ist.
Wird er nicht gedrückt, läuft das Programm einfach ohne Stopp durch.
Dann erscheinen im Serial.println() nur der 2 Sekunden Tackt und der 3 Sekunden Tackt.
Wird der Taster gedrückt, kommt im Serial.println() der 200 Millisekundentakt und der Tastermerker mit "1"
Dann wird der Taster 200millis nicht mehr abgefragt.
Wenn dann der Taster wieder gedrückt wird, oder noch immer gedrückt ist, kommt im Serial.println() der 200 Millisekundentakt und der Tastermerker wieder mit "0"
Die zwei und drei Sekunden Impulse werden weiterhin am Serial.println() angezeigt. Unabhängig vom Tastendruck.
Mit jeden weiteren Tastendruck wechselt der Tastenmerker zwischen 0 und 1 und wird immer am Serial.println() angezeigt.
Ausserdem gibt es einen Ausgang LED01 Pin 9. Das zeigt an ob der Tastenmerker HIGHT ist. Das wird in der letzten Programmzeile übergeben.

Hier sieht man, dass der Taster 200millis nicht mehr abgefragt wird, das Programm aber weiter einfach durch läuft. Das einzige, was viele millis benötigt, ist die Serial.println() Ausgabe auf den Bildschirm. Das sind die einzigen Verzögerungen, die man aber in einem funktionierenden Programm nicht mehr im Code hat. Die braucht man ja nur zum Testen, ob das Programm das macht was es soll.

Code: Alles auswählen


// Baudrate fuer Serial Schnittstelle
const int baudSerial = 19200;
// ------Zeitmerker Deklaration ----
unsigned long aktuellezeit = 0;
// ------millis Deklaration 01 -----
unsigned long pausestartzeit01 = 0;
const unsigned long pausezeit01 = 200;
// ------millis Deklaration 02 -----
unsigned long pausestartzeit02 = 0;
const unsigned long pausezeit02 = 2000;
// ------millis Deklaration 03 -----
unsigned long pausestartzeit03 = 0;
const unsigned long pausezeit03 = 3000;
// ---Deklaration für einen Taster -
const byte Taster01 = 12;           // Pin 12 wird Constant als Taster01 bezeichnet
byte Tasterstatus01 = 0;            // Zum Abfragen des Tatsenpins
byte Tastenmerker01 = 0;            // Zum Merken des aktuellen Tastenstatus
//-----AusgangPIN31----------------
const byte LED01 = 9;               // Pin 6 ist für LED
//--------------------------------------------------------------------------------
void setup()
{
  // Serial Schnittstelle starten
  Serial.begin(baudSerial);
  // TasterPin aktivieren
  pinMode(Taster01, INPUT_PULLUP); // Pin 12 fuer Taster01 wird intern auf plus gelegt.
  pinMode(LED01, OUTPUT);          // LED Ausgangspin6
}
//-------------------------------------------------------------------------------
void loop() {
  // ---------------aktuelle millis in jedem Loop - Durchgang übergeben----------
  aktuellezeit = millis(); // Aktuelle Zeit für alle Millis Aktionen übergeben

  //------------------Erste Aktion-------------------------------------------------
  if (aktuellezeit - pausestartzeit01 >= pausezeit01) // 200 MilliSekunde abgelaufen??
  {
    //Hier die aktuelle Aktion oder mehr Aktionen einsetzen
    Tasterstatus01 = digitalRead(Taster01);         // Pin12 von Taster01 abfragen
    if (Tasterstatus01 == LOW)  // Ist Taster01 gedrueckt?
    {
      Tastenmerker01 = !Tastenmerker01;             // Merken dass Taster01 gedrueckt wurde
      pausestartzeit01 = aktuellezeit; // Neue Pausestartzeit übergeben
      Serial.println(F("200 Millisekundentakt"));
      Serial.println(aktuellezeit);
      Serial.println(F("Tastenmerker"));
      Serial.println(Tastenmerker01);
    }
  }
  //------------------Zweite Aktion-------------------------------------------------
  if (aktuellezeit - pausestartzeit02 >= pausezeit02) // Zwei Sekunden abgelaufen??
  {
    //Hier die aktuelle Aktion oder mehr Aktionen einsetzen
    Serial.println(F("2 Sekundentakt"));
    Serial.println(aktuellezeit);

    pausestartzeit02 = aktuellezeit; // Neue Pausestartzeit übergeben
  }

  //------------------Dritte Aktion-------------------------------------------------
  if (aktuellezeit - pausestartzeit03 >= pausezeit03) // Drei Sekunden abgelaufen??
  {
    //Hier die aktuelle Aktion oder mehr Aktionen einsetzen
    Serial.println(F("3 Sekundentakt"));
    Serial.println(aktuellezeit);

    pausestartzeit03 = aktuellezeit; // Neue Pausestartzeit übergeben
  }
digitalWrite (LED01, Tastenmerker01); // Wenn tastenmerker01 ist HIGH, dann LED01 High
}
Ich habe auch auf meiner HP zum Thema Arduino das Thema MIllis ausführlich beschrieben. Wenn bei jemand das berühmte Zehnerl einfach nicht fallen will, dann hilft vielleicht das was ich dort noch zum Thema delay geschrieben habe. Wenn nicht, einfach mal im Forum hier anmelden und nachfragen. Aber bitte nicht per Email nachfragen, da beantworte ich solche Fragen nicht. Es macht mehr Sinn Fragen im Forum zu stellen und zu beantworten, denn diese Antworten kann dann der nächste auf lesen und ich muss nicht die selbe Frage 100x beantworten, wie es bei einer Email der Fall wäre.

Antworten

Zurück zu „Programmierung der 8Bit Controller“

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast