INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Wie setze ich Verzögerungen richtig ein?
18.12.2019, 14:37
Beitrag #9
RE: Wie setze ich Verzögerungen richtig ein?
(18.12.2019 14:21)MicroBahner schrieb:  
(18.12.2019 13:36)hotsystems schrieb:  Für eine derartige Anwendung einen Interrupt zu missbrauchen, ist für einen "Anfänger" ein ganz schlechter Vorschlag.
Nicht nur für einen "Anfänger" Wink .

Das stimmt auch wiederum.

Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. Cool
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
18.12.2019, 17:28
Beitrag #10
RE: Wie setze ich Verzögerungen richtig ein?
Was ist daran "Missbrauch"?

Ich würde mir vom Timer z. B. im Sekundentakt einen Interrupt erzeugen lassen. In der ISR zähle ich dann mit einen Zähler jeweils 60 Sekunden und setze so alle Minute ein Flag (boolsche Variable). Abhängig von diesem Flag führe ich in der Loop was aus und setze dann das Flag zurück. Genau so ist das auch in dem Beispiel beschrieben.

Und wenn ich dann noch was habe, was mit einer anderen Zykluszeit laufen soll, dann gibt es eben einen zweiten Zähler und ein zweites Flag. Die ISR muss nur möglichst kurz sein und darf z. B. nicht Serial.print benutzen.

Übersichtlicher geht es nicht. Klar, es funktioniert auch mit der zyklischen Abfrage der millis(),

Gruß
GuaAck
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
18.12.2019, 18:28
Beitrag #11
RE: Wie setze ich Verzögerungen richtig ein?
(18.12.2019 17:28)GuaAck schrieb:  Was ist daran "Missbrauch"?
....

Ok, evtl. ist der Ausdruck etwas hart gewählt, aber ich sehe das einfach so:
Dinge die regelmäßig abgearbeitet werden, sollten keinen Interrupt belegen.
Den möchte ich für zufällige Aktionen "frei" halten. Auch weil ein Interrupt eben nicht einfach zu bedienen ist. Schon garnicht von "Anfängern".

Aber letztendlich muss das jeder selbst wissen, eine Empfehlung würde ich jedenfalls nicht geben.

Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. Cool
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
18.12.2019, 19:23
Beitrag #12
RE: Wie setze ich Verzögerungen richtig ein?
Volle Zustimmung, wenn Timer oder Interrupts knapp werden, dann sind andere Lösungen gefragt. Und man kann natürlich auch viel falsch machen, weil man vielleicht vergisst, dass der Interrupt an jeder Stelle der Loop dazwischen hauen kann. Bei der Lösung mit millis() geht alles schon der Reihe nach. Das ist wohl am Anfang übersichtlicher.

Viele Grüße
GuaAck
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
18.12.2019, 23:01
Beitrag #13
RE: Wie setze ich Verzögerungen richtig ein?
Ich tendiere zur einfachen Milli Lösung:

Code:
#include <Wire.h>
#include <LiquidCrystal_I2C.h> ; // NewLiquidCrystal_1.5.1
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

const byte DisplayPin = 12;          // DigitalPin 12 Taster Pin zum Display einschalten
unsigned long Backlightzeit;         // Backlight Ausschaltzeit

void setup(void) {

  lcd.backlight();      // Backlight on
  lcd.noBacklight();    // Backlight off

  lcd.begin(20, 4);     // LCD Start Zeichen 20 4 Zeilen
  lcd.clear();          // LCD Löschen

  pinMode(DisplayPin, INPUT_PULLUP);        // Taster mit Pullup Widerstand Display DigitalPin 12 Eingang
}

void Display_Backlight_on_off() {

  /* Start Display Backlight Zeitgesteuert ausschalten */

  if (digitalRead(DisplayPin) == LOW)
  {
    //   PIN12  Taster gedrückt
    Backlightzeit = millis() + 60000; // Zeit(90sec.) für Backlight-Einschalten berechnen und in Variable speichern
    digitalWrite; lcd.backlight();    // Nach Zeitablauf deaktivieren des Backlight
  }
  else
  {
    //   PIN12     Taster losgelassen

    if (millis() >= Backlightzeit)
    {
      //      Zeit zum Ausschalten erreicht

      digitalWrite; lcd.noBacklight();
    }
  }
}

void loop(void) {

  /* Funktionen Definition im LOOP*/
  Display_Backlight_on_off();
  
}
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
19.12.2019, 01:12 (Dieser Beitrag wurde zuletzt bearbeitet: 19.12.2019 01:23 von Franz54.)
Beitrag #14
RE: Wie setze ich Verzögerungen richtig ein?
Interrupte brauche ich bei extrem Zeitkritischen Auslösungen. Z.B. Eine Lichtschranke signalisiert, dass sie von etwas unterbrochen wurde, und ich muss innerhalb von ein paar Millionstel Sekunden mit ewas darauf reagieren. Dann macht es Sinn die normale Abarbeitung im Loop durch den Interrupt zu unterbrechen, und sofort diese schnelle Reaktion auszulösen. Wenn ich einige Hunderstel Sekunden Zeit habe, dann reicht es locker im Loop zu reagieren wenn der gut organisiert ist, also ohne delay´s, ohne ewige Displayausgaben, sowie ohne langsamme Serial.print Ausgaben.

Ich habe mir vor langer Zeit mal zum Test einen Frequenzzähler mit nem Uno gemacht. Der hat locker rel. genau bis ich glaube etwa 20.000 Hz gezählt, und alles nur im Loop. Und ich bin alles andere als ein Künstler auf dem Gebiet C und C++. Ich bin eher ein Anfänger.

Ist also keine hohe Kunst. Wenn ich immer lese dass man einen Interrupt bemüht, weil man z.B. mit einer Taste eine LED rel. zügig einschalten will, da bekomme ich nen Krampf im Hirm. Confused Ich habe extra mal vor kurzen das Thema eröffnet "Millis statt Delays" weil ich immer kotzen könnte, wenn ich lese "hilfe meine Tastenabfrage funktioniert nicht", und dann hat er 1000 Delays im Loop, und wundert sich dass das Programm Minutenlang nur noch pennt und keine Tasten mehr abfragt. Und dann kommt der Weisheit letzter Schluss, man nimmt nen Interrupt weil der auch delays unterbricht. Und dann nageln die in die Interrupte auch noch delay rein weils so schön ist. Mannnnnnnooooooooooman Leute. Angry

https://www.youtube.com/watch?v=Fnzn85oWM_Q
Hier was zum Thema Deutsche Politik Angry
Und hier zum Thema richtige Politik Big Grin
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
19.12.2019, 15:35 (Dieser Beitrag wurde zuletzt bearbeitet: 19.12.2019 15:41 von MicroBahner.)
Beitrag #15
RE: Wie setze ich Verzögerungen richtig ein?
(18.12.2019 17:28)GuaAck schrieb:  Ich würde mir vom Timer z. B. im Sekundentakt einen Interrupt erzeugen lassen. In der ISR zähle ich dann mit einen Zähler jeweils 60 Sekunden und setze so alle Minute ein Flag (boolsche Variable). Abhängig von diesem Flag führe ich in der Loop was aus und setze dann das Flag zurück. Genau so ist das auch in dem Beispiel beschrieben.
Warum willst Du die millis nachbauen? Denn die machen letztendlich genau das gleiche. Per Interrupt einen Zähler hochzählen. Nur eben im Millisekundentakt und ohne Rücksetzen. Aber das Prinzip ist genau das gleiche. Das muss man nicht 2x machen.

Wenn Du es etwas übersichtlicher haben willst, und dich die direkte Hantierung mit millis() stört, kannst Du eine Klasse drumrumbauen. So habe ich das in meinen MobaTools gemacht ( der EggTimer ). Kannst Du in den Sourcen (MobaTools.h und MobaTools.cpp ) nachschauen. Du kannst es auch gerne rauskopieren, ist nicht viel. Oder Du installierst die MobaTools. Sie sind so geschrieben, das nur eingebunden wird, was auch gebraucht wird. Wenn Du also nur den Eggtimer nutzt, wird nicht viel Flash gebraucht.

Das Ganze mit einem eigenen Timerinterrupt nochmal nachzubauen ist jedenfalls reine Ressourcenverschwendung.

Gruß, Franz-Peter
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
19.12.2019, 23:47
Beitrag #16
RE: Wie setze ich Verzögerungen richtig ein?
Liebe Arduino-Fans,

ich wollte da ja keine Grundsatzdiskussion lostreten und hatte diesen vielen Widerspruch auch nicht erwartet. Ich gebe mich also geschlagen: Die Lösung mit millis() ist auf jeden Fall leichter zu durchschauen. Interrupts erfordern eben doch Grundkenntnisse über die Abläufe im Mikroprozessor, die man für die übliche Programmierung in C bzw. C++ nicht braucht. Und wenn man Interrups für wichtigere Zwecke nutzt, dann ist auch millis() besser. Die Anmerkungen von Franz haben mir gut gefallen, wir alle könnten das wohl mit eigenen Erfahrung zu Fragen in Foren ergänzen.

In einem Punkt gebe ich aber nicht nach: Ich finde die Timer-Lösung schöner als die millis(); und über Geschmack kann man glücklicherweise nicht streiten.

Schöne und geruhsame Weihnachtstage,
GuaAck
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  Wie die HW-Seriellen des Mega richtig einsetzen? DO3GE 2 450 02.12.2019 14:53
Letzter Beitrag: DO3GE
Question Programm läuft nicht richtig CMeeep 22 2.426 04.07.2019 21:58
Letzter Beitrag: Franz54
  Unterroutinenaufruf- wie gehts richtig? Telefonmann 12 1.530 04.05.2019 13:51
Letzter Beitrag: MicroBahner
  [includes]Wie gebe ich den Pfad der .h-Datei richtig an ManniP 6 980 28.04.2019 09:29
Letzter Beitrag: Fips
  HttpBasicAuth richtig einbinden Matroks12 2 950 18.03.2019 11:01
Letzter Beitrag: Bitklopfer
  Timer Richtig dastellen Harlekin 5 1.008 04.02.2019 12:54
Letzter Beitrag: Tommy56
  Problem mit Displayanzeige LCD2004 bzw. nicht Richtig magnum1795 39 4.963 18.12.2018 08:15
Letzter Beitrag: magnum1795
  Rotaryencoder funktioniert nicht richtig 123clever 19 4.324 20.02.2018 22:22
Letzter Beitrag: rpt007
Question Rechnen in C - Was ist denn nun richtig? Stephan_56 17 4.645 27.03.2016 11:31
Letzter Beitrag: ardu_arne
  LCD schreibt mal richtig,mal Krickel? malsehen 14 2.948 21.03.2016 09:21
Letzter Beitrag: hotsystems

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste