Pages: [1]   Go Down
Author Topic: LCD Display - mehrere Anzeigen nacheinander  (Read 1261 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
God Member
*****
Karma: 6
Posts: 705
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
da ich nich alle Infos auf ein 4x20er display bekomme, springe ich zwischen 2 anzeigen hin und her.
Leider bin ich noch nicht ganz glücklich, vor allem mit dem clear passt das  nicht immer (teilweise werden werte nich komplett gecleaned).
Ich mach das aktuell mit nem millis() ablauf, ist das schon der sinnvollste weg?

Hier mal der code:
Code:
void lcd1() {
  if (millis() - lcdmillis <= 5000) {
    ///erste Anzeige
    ///den ganzen display inhalt hab ich mal der ÜBersicht wegen weggelassen
  }
else if (millis() - lcdmillis > 5000 && millis() - lcdmillis <= 5500) { 
  lcd.clear();
  }
else if (millis() - lcdmillis > 5500 && millis() - lcdmillis <= 12500) {
   ///zweite Anzeige
   ///den ganzen display inhalt hab ich mal der ÜBersicht wegen weggelassen 
  }     
else if (millis() - lcdmillis >= 12500) {
    lcdmillis=millis();
    lcd.clear();
  }
}

Vielleicht hat ja jemand nen sinnvolleren ansatz

Gruß
Logged

Offline Offline
Sr. Member
****
Karma: 8
Posts: 359
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,
ich benutze auch ein 4x20 Display bei meiner Heizungssteuerung
und scrolle per Taster durch bis zu 12 Menues,
unter anderem kann ich auch über zwei Taster das Uhrmodul DS1307 einstellen und ändern.
Positionierst du nach dem lcd.clear auch den cursor wieder z.B. mit lcd.setCursor(0,0)?
Probleme gibt es eigentlich nur, wenn man aus Versehen versucht, mehr als 20 Zeichen in eine
Zeile zu schreiben, dann wirft das Display einiges durcheinander.
Ansonsten hab ich noch keine Probleme gehabt, vielleicht erklärst du mal,
was genau passiert.
Gruß
Logged

Offline Offline
God Member
*****
Karma: 6
Posts: 705
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
mir ist eingefallen, dass ich das Problem mit dem Clear nur dann habe, wenn ich per Taster eine void lcd2() aufrufe. Dann wird teilweise noch inhalt von void lcd1() angezeigt. Das hab ich hier leider nicht eingefügt.

Generell würde mich aber interessieren, ob das so wie ich das mache der klassische Weg ist. Muss ich zwischen den beiden ANzeigen (erste Anzeige / zweite ANzeige) wirklich so mit einem eigenem milli() Bereich arbeiten während dem der LCD gecleared wird? Oder gibt es andere Möglichkeiten.
Ist die millis() Implementierung der einzige Weg? (klar, kann auch mit delay() arbeiten, aber das sollte man ja tunlichst vermeiden).

EIgentlich geht es mir aktuell darum, dass ich versuchen möchte Step by Step mein Programm zu optimieren, da es recht umfangreich geworden ist, an bestimmten Stellen abstürzt (die URsache versuche ich auch zu finden) und sicherlich bei mir als Anfänger noch recht ordentlich Optimierungspotnzial ist. Mit dem LCD fange ich da erst mal an.

GRuß
Logged

Offline Offline
Sr. Member
****
Karma: 8
Posts: 359
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

was willst du genau machen, ich mache beides, entweder per Tastendruck zwischen verschiedenen Anzeigen hin und her springen oder aber mit millis() nach einer vorgegebenen Zeit automatisch wechseln. Beides geht. Ist mir echt ein Rätsel, warum bei dir nach einem clear noch etwas aus einer anderen Prozedur angezeigt wird, dafür müsste man mehr vom Code sehen.
Logged

Offline Offline
God Member
*****
Karma: 6
Posts: 705
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, d.h. aber dass ich so wie oben bereits eingefügt habe der einzige und sinnvollste Weg ist? (also mit millis und für das Clearing eine eigene elseif Notwendigkeit)
Mir kam das umständlich vor aber wenns nicht anders geht ist diese Frage natürlich geklärt smiley

Das mit dem Clear schau ich mir noch mal an, hab den Code jetzt nicht hier.
Logged

Offline Offline
Sr. Member
****
Karma: 8
Posts: 359
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hab mir dein Script noch mal angeschaut, die 500ms Verzögerung sind meiner Meinung nach überflüssig.
Zwischen 5000ms und 5500ms löscht du das Display, das kannst du weglassen, einfach das lcd.clear vor jede
Ausgabe sollte reichen
Logged

NRW
Offline Offline
Sr. Member
****
Karma: 2
Posts: 372
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ich wechsle meine Anzeige nur nach Knopfdruck und ob gut oder nicht nur zur vollen Sekunde.
Da mein Display jede Sekunde aktualisiert wird.

Aber du brachst auf keine fall einen extra zweig für den clear
Einfach in jedem zweig ein clear mit nem delay von 10 reicht.
Allerdings wird dein Display zumindest so wie es aussieht (kommt drauf an was dein Programm sonst so macht)
jedesmal neu beschrieben.

Das wollte ich vermeiden als ich das mit dem Sekundentakt gemacht habe.
Ich hatte festgestellt wenn du dem Display zu schnell hintereinander Daten zu schiebst das es sich verschluckt.
Logged

Offline Offline
God Member
*****
Karma: 6
Posts: 705
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Muethos,
kannst du mir mal deinen Codeausschnitt für das LCD zeigen?
VIelleicht kann ich mir da was abgucken zwecks optimierung.

Gruß
THorsten
Logged

NRW
Offline Offline
Sr. Member
****
Karma: 2
Posts: 372
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hmm das ist nicht so einfach.

Also meine Anzeigen und Funktionen liegen in einem eigenem Tab:
Code:
// ##################################### mainScreen #####################################
void mainScreen(){
  clearLCD();
  goTo(1);
  LCD.print(weekdayNames[weekday()-1]);
  goTo(12);
  lcdDigits(temp);
  LCD.print('"');
  goTo(16);
  LCD.print("KW:");
  lcdDigits(WN);
  goTo(22);
  lcdDigits(day());
  LCD.print(".");
  lcdDigits((month()));
  LCD.print(".");
  LCD.print(year());
}

// #################################### statusScreen ##################################
void statusScreen(){
  clearLCD();
  if (DCF77Status==1){
    goTo(0);
    LCD.print("Sync laeuft");
    goTo(16);
    LCD.print("Versuche:  ");
    lcdDigits(DCF77versuche);
    LCD.print("/");
    lcdDigits(maxVersuche);
  }
  if (DCF77Status==0 && DCF77Abbruch==0){
    goTo(0);
    LCD.print("Sync erfolgreich");
    goTo(16);
    LCD.print("Strom aus!");
  }
  if (DCF77Status==0 && DCF77Abbruch==1){
    goTo(0);
    LCD.print("Sync Fehler!");
    goTo(16);
    LCD.print("Abgebrochen");
  }
  if (DCF77Status==0 && DCF77Abbruch==2){
    goTo(0);
    LCD.print("Sync Fehler!");
    goTo(16);
    LCD.print("Datenmuell");
  }
}

// #################################### discoScreen ###################################
void discoScreen(){
  clearLCD();
  goTo(2);
  LCD.print("Disco-Modus");
 
 if (discomode==0){
      goTo(20);
      LCD.print("auto (");
      LCD.print(randiscomode);
      LCD.print(")");
 }else{
   goTo(20);
  LCD.print("Modus: ");
  LCD.print(discomode);
 
  }
}


// ######################## 0 vor einstelligen Ziffern einfügen ########################
void lcdDigits(int digits){
  // Einstellige Werte mit führender Null versehen
  if(digits < 10) {
    LCD.print("0");
  }
  LCD.print(digits);
}

// ###################### Displayfunktionen ##########################
void selectLineOne(){  //puts the cursor at line 0 char 0.
   LCD.print(0xFE, BYTE);   //command flag
   LCD.print(128, BYTE);    //position
}
void selectLineTwo(){  //puts the cursor at line 0 char 0.
   LCD.print(0xFE, BYTE);   //command flag
   LCD.print(192, BYTE);    //position
}
void goTo(int position) { //position = line 1: 0-15, line 2: 16-31, 31+ defaults back to 0
  if (position<16){ LCD.print(0xFE, BYTE);   //command flag
              LCD.print((position+128), BYTE);    //position
}else if (position<32){LCD.print(0xFE, BYTE);   //command flag
              LCD.print((position+48+128), BYTE);    //position
} else { goTo(0); }
}

void clearLCD(){
   LCD.print(0xFE, BYTE);   //command flag
   LCD.print(0x01, BYTE);   //clear command.
}
void backlightOn(){  //turns on the backlight
    LCD.print(0x7C, BYTE);   //command flag for backlight stuff
    LCD.print(157, BYTE);    //light level.
}
void backlightOff(){  //turns off the backlight
    LCD.print(0x7C, BYTE);   //command flag for backlight stuff
    LCD.print(128, BYTE);     //light level for off.
}
void serCommand(){   //a general function to call the command flag for issuing all other commands   
  LCD.print(0xFE, BYTE);
}

Und aufgerufen wird immer durch den kram:
Code:
// ################## serLCD initialisieren ###############################
SoftwareSerial LCD = SoftwareSerial(0, txPin);   // init mit txPin (rx wird nicht benötigt)
...
pinMode(txPin, OUTPUT);                // serLCD PIN als OUTPUT einrichten
  LCD.begin(9600);                       // Serielle Übertragung zum LCD starten
  delay(100);
  clearLCD();                            // LCD löschen
  delay(100);
  backlightOn();                         // Hintergrund anschalten
  delay(100);
...

Hierdurch:
Code:
attachInterrupt(1, secTakt, FALLING);  // Pin3 Sekunden Interrupt
und im zusammenhang mit:
Code:
void secTakt() {
  Takt = 1;                       // Setze Takt auf 1 damit Auswertung weiss es ist eine Sekunde rum
}
und:
Code:
if (Takt == 1){
    //                                    // in die einzelnen Zeitfunktionen springen
    if (previousTime[0]!=hour()) newHour();
    if (previousTime[1]!=minute()) newMinute();
    if (previousTime[2]!=second()) newSecond();
    if (previousTime[3]!=day()) newDay();
    if (previousTime[4]!=month()) newMonth();
    if (previousTime[5]!=year()) newYear();
    //                                   // Letze Zeit setzen als neuen vergleichswert
    previousTime[0] = hour();
    previousTime[1] = minute();
    previousTime[2] = second();
    previousTime[3] = day();
    previousTime[4] = month();
    previousTime[5] = year();
    Takt = 0;
  }
wird dies aufgerufen:
Code:
void newSecond(){
 
   tempRead();
 
  if (ButtonValue == 1){
    // Button Auswertung mit lang und kurz drücken
  }
   switch(screen) {
    case 1:                        // Hauptanzeige
      mainScreen();
      if (DCF77Status == 0){
        rainbowSecond();
      }
      break;
    case 2:                        // Statusanzeige
      statusScreen();
      if (DCF77Status == 0){
        rainbowSecond();
      }
      break;
    case 3:                        // Disco
      discoScreen();
      // rainbowDisco wird im loop aufgerufen (Sekundentakt reicht nicht
     
      break;
    default:
      mainScreen();
      if (DCF77Status == 0){
        rainbowSecond();
      }
      screen= 1;
      break;
  }
}

Schau mal ob es dir was bringt.
Logged

Offline Offline
God Member
*****
Karma: 6
Posts: 705
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
ist schon komplett anders proigrammiert als bei mir, denke so komplex muss ich das gar nicht machen.
Aber ich finde die Idee gut, das LCD nur jede Sek aufzurufen. Würde das s o machen, dass nach Ablauf von einer Sekunde das LCD neu geladen wird. Allerdings will ich 3 Sek ANzeige 1 und dann 3 Sek Anzeige 2 anzeigen lassen. Meine Idee:
Code:
if (millis() - lcdmillis > 1000 && lcd==0) {  
    lcd1();  //die Void in der die Anzeigedetails1 stehen
    lcd=1;  //Prüf Variabel
    lcdmillis=millis();
    }
    if (millis() - lcdmillis > 1000 && lcd==1) {  
    lcd1();
    lcd=2;
    lcdmillis=millis();
    }
    if (millis() - lcdmillis > 1000 && lcd==2) {  
    lcd1();
    lcd=3;
    lcdmillis=millis();
    }
    if (millis() - lcdmillis > 1000 && lcd==3) {  
    lcd2();
    lcd=4;
    lcdmillis=millis();
    }
        if (millis() - lcdmillis > 1000 && lcd==4) {  
    lcd2();
    lcd=5;
    lcdmillis=millis();
    }
        if (millis() - lcdmillis > 1000 && lcd==5) {  
    lcd2();
    lcd=0;
    lcdmillis=millis();
    }

Das wird vermutlich funktinoieren, aber ich frag mich grad ob das nicht einfacher geht? Mir fällt leider nix ein.
« Last Edit: May 19, 2011, 01:32:13 pm by currymuetze » Logged

Offline Offline
God Member
*****
Karma: 6
Posts: 705
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

grad mal etwas verbessert, gehtsnoch einfacher?
Code:
    if (millis() - lcdmillis > 1000 && (lcdcheck==0 || lcdcheck==1 || lcdcheck==2)) { 
    lcd1();
    lcdcheck=+1;
    lcdmillis=millis();
    }
    if (millis() - lcdmillis > 1000 && (lcdcheck==3 || lcdcheck==4 || lcdcheck==5)) { 
    lcd2();
    lcdcheck=+1;
    lcdmillis=millis();
    }
    if (lcdcheck==6) lcdcheck=0;
  }
Logged

Offline Offline
Sr. Member
****
Karma: 8
Posts: 359
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

vielleicht ein wenig  smiley

 if (millis() - lcdmillis > 1000) {
   if (lcdcheck < 3){
    lcd1();
    lcdcheck++;
    lcdmillis=millis();
   }  
   else{
    lcd2();
    lcdcheck++;
    lcdmillis=millis();
   }
   if (lcdcheck==6) lcdcheck=0;
  }
« Last Edit: May 20, 2011, 05:27:26 am by maverick1509 » Logged

Pages: [1]   Go Up
Jump to: