PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : lcd.clear Display flackern



StephanG90
07.08.2024, 14:55
Hallo,
ich habe ein Projekt wo verschiedene Informationen auf einem per I2C Bus angeschlossenen 16x2 Display angezeigt werden sollen.
Ich habe teilweise das Problem, das wenn die Anzeige wechselt, vorhergehende Informationen noch zu sehen sind.
Ich wollte das ganze durch lcd.clear lösen, allerdings flackert dann immer das Display.

Gelöst habe ich das Aktuell damit, das ich bei einem anzeigen Wechsel einfach nicht verwendete stellen durch ein Leerzeichen ersetze. Das funktioniert auch. Ist das eine Lösung die auch so angewandt wird oder gibt es da etwas eleganteres bzw. professionelleres?

Als Beispiel habe ich mal einen Teil aus dem Programm Kopiert:



void lueftersteuerung(int a) // Lüftersteuerung, ON/ OFF je nach Temperatur, ON bei Fehler DHT11
{
int relais_status = 0;
int fehler = 0;
if(result == 0 && temperature >= 25)
{
digitalWrite(relais, HIGH);
relais_status = 1;
}
else if(result == 0 && temperature < 25)
{
digitalWrite(relais, LOW);
relais_status = 0;
}
else if(result != 0)
{
digitalWrite(relais, HIGH);
fehler = 1;
}

if(a == 4 && relais_status == 1 && fehler == 0)
{
lcd.setCursor(0, 0);
lcd.print("Luefter:");
lcd.setCursor(0, 1);
lcd.print("ON ");
}
else if(a == 4 && relais_status == 0 && fehler == 0)
{
lcd.setCursor(0, 0);
lcd.print("Luefter:");
lcd.setCursor(0, 1);
lcd.print("OFF ");
}
else if(a == 4 && fehler == 1)
{
lcd.setCursor(0, 0);
lcd.print("Luefter:");
lcd.setCursor(0, 1);
lcd.print("ON mit Fehler");
}

}


Wenn ich in dem Beispiel den DHT11 Sensor abziehe, schaltet sich der Lüfter ein und im Menüpunkt Lüftersteuerung im Display kommt ON mit Fehler. Stecke ich DHT11 wieder an, schaltet die Anzeige auf ON, füge ich hier bei ON allerdings nicht die ganzen Leerzeichen ein, bleibt "mit Fehler" stehen.

Danke im voraus

Rabenauge
09.08.2024, 07:50
Warum ldc.clear() nicht richtig funktioniert, kann ich dir nicht sagen. Möglicherweise liegts an der Bibliothek, die du verwendest.

Aber ansonsten macht man das so, ja. Der Sinn von lcd.setCursor() ist es ja eben, dass nicht jedes Mal das ganze Display neu beschrieben werden muss. Wenn du willst, kannst du deine Vorgehensweise noch verfeinern, indem du nur die Stellen, die auch wirklich mit was beschrieben sind, mit Leerzeichen füllst. Das ist noch was schneller- wirst du praktisch aber kaum merken.

Übrigens: meistens haben die Controller der LCD-Displays die Möglichkeit, eigene Zeichen zu definieren (ich glaube, bis zu acht, ist ewig her dass ich mit so nem Ding hantiert hatte), so dass man auch öüä anzeigen kann.

oberallgeier
09.08.2024, 09:42
.. per I2C Bus angeschlossenen 16x2 Display .. allerdings flackert dann immer das Display..

.. Übrigens: meistens haben die Controller der LCD-Displays die Möglichkeit, eigene Zeichen zu definieren ..
Grüß Dich Stephan. Mit den I²C-Displays habe ich wenig (schlechte?) Erfahrung. Meine Displays schließe ich immer mit einem (für mich standardisierten) 10pol-Kabel an. Den Vorschlag von Sly - NUR partiell zu löschen vor schreiben - habe ich vielfach installiert. Meist reicht es mir ab einer angesteuerten Position des Cursors den Zeilenrest zu löschen - soweit ich das im KOpf habe, kann man beruhigt über die Zeile rausschreiben. Wozu? Weil man dann nur eine komplette Leerzeile als "Löschbefehl" ab aktueller Cursorposition senden muss. Der Überhang geht ins Leere .. ;-) soweit ich mich erinnere.

Zu Sonderzeichen und so hilft Dir vielleicht ein Ausschnitt aus einer meiner üblichen C-Bibliotheken weiter. Für mich selber tricky (im Programmieren) sind die Sonderzeichen wie z.B. µ, © oder ein schräges ↕ ...


/* >> NUR AUSSCHNITT ohne Gewähr © oberallgeier
Stand ..\C5_Ronny-5_etc\ALCo\ALCo_kalij.c
================================================== ============================ =
...
void LCD_SZ1 (void) ; // LCD-Sonderzeichen, Satz 1 Balken
void LCD_SZ2 (void) ; // LCD-Sonderzeichen, Satz 2 Grosse Ziffern
void LCD_SZ3 (void) ; // Generiere LCD-Sonderzeichen, Satz 1 Balken hori
void LCD_SZ4 (void) ; // LCD-So-zeichn, RETURN, auf, ab à la pololu, ±
================================================== ============================ =
*** Versionsgeschichte:
x04 21Sep22 1122 ~com~+~kal~ korrigiert wegen Start- und End-Stellung, siehe LOG
...
================================================== ============================= =
*** Aufgabenstellung : Software RJjr, ArmLiController/Servobetrieb, ATmega1284p
Original: ...\C5_Ronny-5_etc\ALCo\ALCo_kalij.c, eigentlich aber
D:\D_pro-fils\compu_MC\C7\ALCo\ALCo\ALCokalij.c x41 25Mar19 1204 ~kal~:...
================================================== ============================ */


// FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP =
/* == Funktionsprototypen Kalibrierung/Startwerte, LDC-Routinen
...
void LCD_SZ1(void) ; // Generiere LCD-Sonderzeichen, Satz 1 = Balken
void LCD_SZ2(void) ; // LCD-Sonderzeichen, Satz 2 = große Ziffern
void LCD_SZ3(void) ; // Generiere LCD-Sonderzeichen, Satz 1 Balken hori
void LCD_SZ4(void) ; // LCD-Sonderzeichen: RET à la pololu, ©, etc
// FP FP FP FP FP FP FP FP FP FP FP FP FP ******************************* */




// ================================================== =========================== =
// Generierung von LCD-Sonderzeichen für DEM162xx, Satz 1 = Balken vertikal
// ================================================== =========================== =
void LCD_SZ1(void) // Generiere LCD-Sonderzeichen, Satz 1 = Balken
{ // vertikal, 7 Zeichen
// - - - - - - - - - - - - - - - -

// Es folgen LCD-Daten für den Balken 1 bis 7 Pixelreihen hoch
// der "Balken8" ist DEM-Code 255, der leere Balken ist DEM-Code 254
uint8_t LCD_c_1[8] = // LCD-Character 1, unterste Linie
{ 0, 0, 0, 0, 0, 0, 0, 31 };
lcd_generatechar(LCD_GC_CHAR1, LCD_c_1);

uint8_t LCD_c_2[8] = // LCD-Character 2
{ 0, 0, 0, 0, 0, 0, 31, 31 };
lcd_generatechar(LCD_GC_CHAR2, LCD_c_2);

uint8_t LCD_c_3[8] = // LCD-Character 3
{ 0, 0, 0, 0, 0, 31, 31, 31 };
lcd_generatechar(LCD_GC_CHAR3, LCD_c_3);

uint8_t LCD_c_4[8] = // LCD-Character 4
{ 0, 0, 0, 0, 31, 31, 31, 31 };
lcd_generatechar(LCD_GC_CHAR4, LCD_c_4);

uint8_t LCD_c_5[8] = // LCD-Character 5
{ 0, 0, 0, 31, 31, 31, 31, 31 };
lcd_generatechar(LCD_GC_CHAR5, LCD_c_5);

uint8_t LCD_c_6[8] = // LCD-Character 6
{ 0, 0, 31, 31, 31, 31, 31, 31 };
lcd_generatechar(LCD_GC_CHAR6, LCD_c_6);

uint8_t LCD_c_7[8] = // LCD-Character 7
{ 0, 31, 31, 31, 31, 31, 31, 31 };
lcd_generatechar(LCD_GC_CHAR7, LCD_c_7);

/*
uint8_t LCD_c_0[8] = // LCD-Character 0
{ 31, 31, 31, 31, 31, 31, 31, 31 };
lcd_generatechar(LCD_GC_CHAR0, LCD_c_0);
*/

return; //
} // Ende void LCD_SZ1(void)
// === Ende
// ================================================== =========================== =


// ================================================== =========================== =
// Generierung von LCD-Sonderzeichen für DEM162xx, Satz 2 für große Ziffern
// ================================================== =========================== =
void LCD_SZ2(void) // LCD-Sonderzeichen, Satz 2 = große Ziffern
{ //
// - - - - - - - - - - - - - - - -

// Es folgen LCD-Daten für Element 0 bis 7 für große Zifferndarstellung
//
// 00011 = 3 11000 = 24 11011 = 27 11111 = 31

uint8_t LCD_c_0[8] = // LCD-Character 0, rechte Linie
{ 3, 3, 3, 3, 3, 3, 3, 3 };
// { 6, 6, 6, 6, 6, 6, 6, 6 };
lcd_generatechar(LCD_GC_CHAR0, LCD_c_0);

uint8_t LCD_c_1[8] = // LCD-Character 1, ne Art 7
{ 31, 31, 3, 3, 3, 3, 3, 3 };
lcd_generatechar(LCD_GC_CHAR1, LCD_c_1);

uint8_t LCD_c_2[8] = // LCD-Character 2, ne Art L
{ 3, 3, 3, 3, 3, 3, 31, 31 };
lcd_generatechar(LCD_GC_CHAR2, LCD_c_2);

uint8_t LCD_c_3[8] = // LCD-Character 3, ne Art C
{ 31, 31, 24, 24, 24, 24, 31, 31 };
lcd_generatechar(LCD_GC_CHAR3, LCD_c_3);

uint8_t LCD_c_4[8] = // LCD-Character 4, Spiegel-C
{ 31, 31, 3, 3, 3, 3, 31, 31 };
lcd_generatechar(LCD_GC_CHAR4, LCD_c_4);

uint8_t LCD_c_5[8] = // LCD-Character 5, U
{ 27, 27, 27, 27, 27, 27, 31, 31 };
lcd_generatechar(LCD_GC_CHAR5, LCD_c_5);

uint8_t LCD_c_6[8] = // LCD-Character 6, "n"
{ 31, 31, 27, 27, 27, 27, 27, 27 };
lcd_generatechar(LCD_GC_CHAR6, LCD_c_6);

uint8_t LCD_c_7[8] = // LCD-Character 7, O
{ 31, 31, 27, 27, 27, 27, 31, 31 };
lcd_generatechar(LCD_GC_CHAR7, LCD_c_7);

return; //
} // Ende void LCD_SZ2void)
// === Ende
// ================================================== =========================== =


// ================================================== =========================== =
// Generierung von LCD-Sonderzeichen für DEM162xx, Satz 3 = Balken horizontal
// ================================================== =========================== =
void LCD_SZ3(void) // Generiere LCD-Sonderzeichen, Satz 1 Balken hori
{ //
// - - - - - - - - - - - - - - - -

// Es folgen LCD-Daten für den Balken 1 bis 5 Pixelreihen breit
uint8_t LCD_c_1[8] = // LCD-Character 1, Balken 1 breit
{ 16, 16, 16, 16, 16, 16, 16, 16 };
lcd_generatechar(LCD_GC_CHAR1, LCD_c_1);

uint8_t LCD_c_2[8] = // LCD-Character 1, Balken 2 breit
{ 24, 24, 24, 24, 24, 24, 24, 24 };
lcd_generatechar(LCD_GC_CHAR2, LCD_c_2);

uint8_t LCD_c_3[8] = // LCD-Character 3, Balken 3 breit
{ 28, 28, 28, 28, 28, 28, 28, 28 };
lcd_generatechar(LCD_GC_CHAR3, LCD_c_3);

uint8_t LCD_c_4[8] = // LCD-Character 4, Balken 4 breit
{ 30, 30, 30, 30, 30, 30, 30, 30 };
lcd_generatechar(LCD_GC_CHAR4, LCD_c_4);

uint8_t LCD_c_5[8] = // LCD-Character 5, Balken 5 breit
{ 31, 31, 31, 31, 31, 31, 31, 31 };
lcd_generatechar(LCD_GC_CHAR5, LCD_c_5);

return; //
} // Ende void LCD_SZ3(void)
// === Ende
// ================================================== =========================== =


// ================================================== =========================== =
// Generierung von LCD-Sonderzeichen für DEM162xx, Satz 4 = RETURN
// ================================================== =========================== =
void LCD_SZ4(void) // LCD-Sonderzeichen, NUR RETURN à la pololu
// - - - - - - - - - - - - - - - -
{ //
// Returnzeichen à la pololu
uint8_t LCD_c_0[8] = { // LCD-Character 0
0b00000000, // -----
0b00000010, // ---X-
0b00000001, // ----X
0b00000101, // --X-X
0b00001001, // -X--X
0b00011110, // XXXX-
0b00001000, // -X---
0b00000100 // --X--
};
lcd_generatechar(LCD_GC_CHAR0, LCD_c_0);

// - - - - - - - - - - - - - - - -
// Pfeil auf
uint8_t LCD_c_1[8] = { // LCD-Character 1
0b00000000, // -----
0b00000000, // -----
0b00000100, // --X--
0b00001110, // -XXX-
0b00010101, // X-X-X
0b00000100, // --X--
0b00000100, // --X--
0b00000000 // -----
};
lcd_generatechar(LCD_GC_CHAR1, LCD_c_1);

// - - - - - - - - - - - - - - - -
// Pfeil ab
uint8_t LCD_c_2[8] = { // LCD-Character 2
0b00000000, // -----
0b00000000, // -----
0b00000100, // --X--
0b00000100, // --X--
0b00010101, // X-X-X
0b00001110, // -XXX-
0b00000100, // --X--
0b00000000 // -----
};
lcd_generatechar(LCD_GC_CHAR2, LCD_c_2);

// - - - - - - - - - - - - - - - -
// Pfeil ab
uint8_t LCD_c_3[8] = { // LCD-Character 3, ©
0b00001110, // -XXX-
0b00010001, // X---X
0b00001101, // -XX-X
0b00010001, // X---X
0b00010001, // X---X
0b00001101, // -XX-X
0b00010001, // X---X
0b00001110 // -XXX-
};
lcd_generatechar(LCD_GC_CHAR3, LCD_c_3);

// - - - - - - - - - - - - - - - -
// Doppelpfeil schräg linksunten<=>rechtsoben
uint8_t LCD_c_4[8] = { // LCD-Character 4 => Pfeil-lu-ro
0b00000000, // -----
0b00000111, // --XXX
0b00000011, // ---XX
0b00010101, // X-X-X
0b00011000, // XX---
0b00011100, // XXX--
0b00000000, // -----
0b00000000 // -----
};
lcd_generatechar(LCD_GC_CHAR4, LCD_c_4);

// - - - - - - - - - - - - - - - -
// linke Hälfte Copyright ©
uint8_t LCD_c_5[8] = { // LCD-Character 5 => © linke Hälfte
0b00000011, // ---XX
0b00000100, // --X--
0b00001001, // -X--X
0b00001010, // -X-X-
0b00001010, // -X-X-
0b00001001, // -X--X
0b00000100, // --X--
0b00000011 // ---XX
};
lcd_generatechar(LCD_GC_CHAR5, LCD_c_5);

// - - - - - - - - - - - - - - - -
// Rechte Hälfte Copyright ©
uint8_t LCD_c_6[8] = { // LCD-Character 6 => © rechte Hälfte
0b00011000, // XX---
0b00000100, // --X--
0b00010010, // X--X-
0b00000010, // ---X-
0b00000010, // ---X-
0b00010010, // X--X-
0b00000100, // --X--
0b00011000 // XX---
};
lcd_generatechar(LCD_GC_CHAR6, LCD_c_6);

// - - - - - - - - - - - - - - - -
// Charakter µ
uint8_t LCD_c_7[8] = { // LCD-Character 7 => µ
0b00000000, // -----
0b00000000, // -----
0b00010001, // X---X
0b00010001, // X---X
0b00010011, // X--XX
0b00011101, // XXX-X
0b00010000, // X----
0b00010000 // X----
};
lcd_generatechar(LCD_GC_CHAR7, LCD_c_7);

return; //
} // Ende void LCD_SZ4(void)
// === Ende
// ================================================== =========================== =


// ================================================== =========================== =
// ===== ENDE Subroutinen ================================================== =
// ================================================== =========================== =

Viel Erfolg, vielleicht hilft der Rat.

Nachtrag: Anwendungsbeispiel:
// ================================================== =========================== =
// == LCDausgabe, Test Sonderzeichen 4
// ================================================== =========================== =
void lcd_tSZ4 (void) // LCDausgabe , insbes. neues RETURN à la pololu
{ //
// - - - - - - - - - - - - - - - -
wms ( 100); // Vor-Wartezeit
LCD_SZ4( ); // Initialisiere neues (05 Mai 2013) RETURN kal
lcd_clear(); // Vor LCD-Ausgabe Display leeren lcd

// - - - - - - - - - - - - - - - -
Line2(); // An den Anfang der 2. Zeile springen
lcd_string("A: "); //
lcd_data(127); // Pfeil links
lcd_string(" B: "); //
lcd_data(0); // Sonderzeichen 0, hier RETURN
lcd_data(1); // Sonderzeichen 1, hier RETURN
lcd_data(2); // Sonderzeichen 2, hier RETURN
lcd_string(" C: "); //
lcd_data(126); // Pfeil rechts
wms ( 1000);
while ( TBaus ) {}
while ( TBan ) {} //
while ( TBaus ) {}
lcd_clear(); // Vor LCD-Ausgabe Display leeren lcd
wms ( 1000); // Wartezeit

// - - - - - - - - - - - - - - - -

} // Ende von void snd_01
// ================================================== =========================== =

Holomino
09.08.2024, 09:58
Wenn Du die durchaus berechtigte Sorge hast, bei einer Textänderung den ganzen Quellcode durchgehen zu müssen, kannst Du auch die Texte in einem Block vordefinieren. Dann sieht man die unterschiedlichen Stringlängen besser:


#define TXT_ON "On "
#define TXT_ONERROR "On mit Fehler"
#define TXT_OFF "Off "




Im Aufruf dann einfach den Konstantennamen (TXT_...) statt des Textes einfügen.

StephanG90
10.08.2024, 14:42
Ich danke für eure Hilfe. Ich werde dann die Tipps im aktuellen Projekt einbauen

Crazy Harry
11.08.2024, 13:20
Clear und Cursor setzen sind bei diesen Displays relativ langsame Befehle mit langen Pausen drin. Schau dir mal das Datenblatt an.

Hier mal 3 x-beliebige Datenblätter