LCD mit Interrupt aktualisieren

Hallo,
ich möchte die LCD-Anzeige in der Interrupt-Routine Aktualisieren.
Leider vertragen sich Interrupt und LCD nicht.
Ich habe auch schon alle 5 Timer durchprobiert. (Mega 2560)

#include <TimeLib.h>
#include <LiquidCrystal_I2C.h>


LiquidCrystal_I2C lcd(0x27, 20, 4); 

void setup()
{
Serial.begin(9600);
lcd.begin();
setSyncProvider(getTime);                       //Routiene die die Zeit synchronisiert

  noInterrupts();           // Alle Interrupts temporär abschalten
  TCCR3A = 0;
  TCCR3B = 0;
  TCNT3 = 0;                // Register mit 0 initialisieren
  OCR3A = 31250;            // Output Compare Register vorbelegen 
  TCCR3B |= (1 << CS12);    // 256 als Prescale-Wert spezifizieren
  TIMSK3 |= (1 << OCIE1A);  // Timer Compare Interrupt aktivieren
  interrupts();             // alle Interrupts scharf schalten
}

ISR(TIMER3_COMPA_vect)        
{
  TCNT3 = 0;                // Register mit 0 initialisieren   
  Print();
}

void Print()
{
  Serial.print(hour());
  Serial.print(" ");
  Serial.print(minute());
  Serial.print(" ");
  Serial.print(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year()); 
  Serial.print(" ");
  Serial.println(now());
  
  lcd.print(second());
}

time_t getTime(){
return 1;
}

void loop()
{

Ohne LCD bringt mir das Testprogramm einmal pro Sekunde eine Ausgabe.

Für Hilfe wäre ich dankbar
Daneie

Für sowas braucht man doch keinen Interrupt. Schau dir BlinkWithoutDelay an

Serial.print() hat in ISRs nichts verloren

Hi

Du kannst in einer ISR Nichts aufrufen, was ebenfalls Interrupts benötigt.

Du kannst Dir aber im ISR ein Flag setzen, Welches Du in der loop() auswertest. Wenn's eine Aktualisierung alle Sekunde ist, wäre millis() hier wohl dicke ausreichend - selbst, wenn Da Jemand mit der Stoppuhr mithält, wie lange der Intervall ist.

Du setzt in Deiner ISR den Counter wieder auf Null und rufst dann die Funktion Print() auf. Diese ist eine Ewigkeit unterwegs, um diverse Ausgaben über die Serielle Schnittstelle zu prügeln. Anschließend wird das LCD noch beglückt.

Den ganzen Zinnober kannst Du ohne Probleme in der loop() abhandeln - in diesem Fall sogar ganz ohne Interrupt.

Es sei, Du willst später was ganz Anderes mit den Interrupts machen, daß Das hier nur ein Test dafür ist ;)

Für die Zukunft: ISRs so kurz/schnell wir möglich Änderungen in der ISR müssen volatile declariert sein, damit der µC diese Änderungen auch mitbekommt! Wenn nicht, ein blödes Beispiel: die loop enthält eine leere while(t==1); Endlosschleife. Wenn Du jetzt in der ISR dieses t (klar, muß global sein) auf 0 setzt, bekommt die loop() davon Nichts mit. Der µC ist so schlau, daß Er Variablen, Die Sich nicht ändern, in speziellen Speichern (Registern) behält - Das macht die Sache um einiges schneller, als wenn der µC jedes Mal im Speicher nachschauen muß, ob sich Da was geändert hat. volatile sagt dem Kompiler, daß sich diese Variable auch ohne Sein Zutun ändern kann - z.B. in einem Interrupt, Den der Kompiler so nicht sehen kann.

MfG

Es wurde ja schon alles gesagt, aber warum möchtest du das Display per Interrupt aktualisieren ? Gibt es dafür einen Grund, den wir bisher nicht erkennen können ?

Jetzt einmal blöd gefragt. Wie viel Programm darf man einen Interrupt zumuten?

Die LCD-Aktualisierung dauert doch nur ein paar ms und bis zum nächsten Interrupt ist doch dann noch viel Zeit von der Sekunde über.

daneie: Jetzt einmal blöd gefragt. Wie viel Programm darf man einen Interrupt zumuten?

Die LCD-Aktualisierung dauert doch nur ein paar ms und bis zum nächsten Interrupt ist doch dann noch viel Zeit von der Sekunde über.

Nur warum mit dem Interrupt, das ist doch absolut überflüssig.

Ein Aufruf in der Loop durch einen "Timer" gesteuert, der den Aufruf jede Sek. startet, ist doch simpel.

Z.B. den combie-Timer, weiß grad nicht wie der genau heißt. Google mal hier im Forum. Oder auch SimpleTimer.

HotSystems: Es wurde ja schon alles gesagt, aber warum möchtest du das Display per Interrupt aktualisieren ? Gibt es dafür einen Grund, den wir bisher nicht erkennen können ?

Ich habe bisher mit C-Control gearbeitet (Bewässerung, Heizung, Zugangskontrolle, Alarmanlage, Wintergarten)

Das ist halt super praktisch, du änderst nur die Variable und der Rest passiert im Hintergrund.

Ist das nun so, das eine LCD-Ausgabe im Interrupt bei einen Arduino nicht möglich ist?

daneie: Ich habe bisher mit C-Control gearbeitet (Bewässerung, Heizung, Zugangskontrolle, Alarmanlage, Wintergarten)

Das ist halt super praktisch, du änderst nur die Variable und Rest passiert im Hintergrund.

Ist das nun so, das eine LCD-Ausgabe im Interrupt bei einen Arduino nicht möglich ist?

Richtig und nochmal, du brauchst den nicht. Ohne ist es viel einfacher.....echt.

Allerdings fehlt mir immer noch eine Antwort, warum hier einen Interrupt ?

daneie: Wie viel Programm darf man einen Interrupt zumuten?

Kurz gesagt, so wenig wie nur irgend möglich. Keine Ausgaben, nichts was lange dauert, nichts was selbst einen Interrupt nutzt. In der Regel werden wenige Variablen gesetzt und die Interrupt-Routine beendet.

Wie Dir bereis geschrieben wurde, für das was Du uns bisher über Dein Vorhaben gesagt hast, ist Interrupt der falsche Weg.

Gruß Tommy

HotSystems: Allerdings fehlt mir immer noch eine Antwort, warum hier einen Interrupt ?

Ich finde es halt praktisch und wahrscheinlich aus Gewohnheit.

Aber danke für die Diskussion, ich werde es in Loop einbauen.

Daneie

daneie: Ich finde es halt praktisch und wahrscheinlich aus Gewohnheit.

Aber danke für die Diskussion, ich werde es in Loop einbauen.

Daneie

Ok....das kann ich mal so verstehen. Du wirst aber sehen, es geht anders einfacher und du hast den Interrupt für später und andere Ding frei zur Verfügung.

Hi

Nicht nur, daß Das jetzt ohne Interrupt einfacher ist (im Hintergrund wird 1000 Mal die Sekunde der Wert millis() um 1 erhöht - jupp, Da ist eine Timer-ISR zuständig).

In Deinem Beispiel wäre die Arbeit des Interrupt die eigentliche Arbeit, nämlich das Display aktualisieren. Von der loop() ist nicht viel zu sehen, habe ja noch die Hoffnung, daß sich dort die Werte der Anzeige ändern (warum sollte man Diese sonst aktualisieren, wenn nichte Neues zu sehen ist?).

Interrupt heißt ja Unterbrechung - die eigentliche Aufgabe wird unterbrochen, um etwas zeitlich kritisches schnellst möglich abzuarbeiten - damit danach Zeit für weitere Interrupts ist - also wirklich kritische Zugriffe. Taster abfragen und eine Drei auf's LCD zaubern darf durchaus Mal 100ms länger dauern - davon bekommt der geneigte Nutzer Nichts mit.

Aber Deine Anforderung, irgendwo nur eine Zahl zu ändern und 'der Rest läuft im Hintergrund' - ist hier auch gegeben - du musst halt Alles, was sich im Sketch (sinnvoll) ändern lässt, mit Variablen benutzen. Z.B. Pin-Nummern - wenn später der Taster statt an Pin 3 an Pin 17 angeschlossen werden muß, änderst Du diesen Wert im Sketch, upload, fertig. Ebenso bei irgendwelchen Zeiten - z.B. Display-Intervalle statt 1000 auf 500ms.

Werte, Die konstant sind, bitte auch so deklarieren (damit der Compiler Diese fest verdrahten kann - spart Speicher).

Soll's erst Mal gewesen sein ;)

MfG

Hallo daneie,

daneie: Jetzt einmal blöd gefragt. Wie viel Programm darf man einen Interrupt zumuten? Die LCD-Aktualisierung dauert doch nur ein paar ms und bis zum nächsten Interrupt ist doch dann noch viel Zeit von der Sekunde über.

Ein paar ms sind für einen Interrupt viel zu viel. Du musst bedenken, dass es auch noch andere Interrupts gibt ( z.B. den für die Zeit seit Start: millis() und micros() ), und die sperrst Du dann für mehrere ms aus. Wenn z.B. die LCD-Aktualisierung selbst einen IRQ braucht, damit sie fertig wird, wird's ganz übel. Dann hängt sich das Ganze auf.

daneie: Ich habe bisher mit C-Control gearbeitet (Bewässerung, Heizung, Zugangskontrolle, Alarmanlage, Wintergarten)

Das ist halt super praktisch, du änderst nur die Variable und der Rest passiert im Hintergrund.

Wie meinst Du das mit dem Hintergrund? Ich habe früher auch einiges mit der C-Control gemacht, aber dass da viel 'im Hintergrund' passiert ist wüsste ich nicht. An die Interrupts kam man ja gar nicht direkt ran, das war ein geschlossenes System. Hier ist der Arduino viel flexibler, da er dich nicht von der HW fernhält. Du musst zwar nicht, aber Du kannst bis aufs letzte Bit im Controller zugreifen. Natürlich gibt's bei der C-Control Systemaufrufe, die dir viel Arbeit abnehmen, aber das gibt's beim Arduino mit den Lib's ja auch.