OLED flackert mit GFX und Custom fonts

Hallo zusammen.

Ich streite mich gerade mit der Adafruit GFX library. Das Problem ist das bekannte, die Buchstaben und Zahlen haben einen transparenten Hintergrund. Wenn man sie also updatet schreibt man sie ineinander. Normalerweise hilft es hierbei die Schrift auch mit Hintergrundfarbe zu definieren. Leider leider geht dies aber nicht bei custom fonts, also Schriftarten die man selber hinzugefügt hat. Warum, dass verstehe ich nicht..kann man die Hintergrundpixel einer Schriftart nicht speciell für so einen Fall eine Farbe geben?

Nun ja, also muss iche in schwarzes Rechteck aufziehen bevor ich schreibe. Leider ist die ganze Geschichte dann so lahm, dass man das Flackern deutlich sieht.

Nun gibt es ein paar Berichte über Buffer oder Bulk Pixel Writing - allerdings finde ich keine Dokumentation oder Anleitung wie ich das umsetzen kann.

Ich verwende ein 128x128 OLED mit SSD1351, Arduino Nano (gleiches Problem mit Mega), Adafruit GFX und Adafruit ssd1351.

Ich habe eine Menge Text und Zahlen auf dem Display, deshalb verwende ich eine dünne Schriftart in 14 Pixel, die löst das mit der Lesbarkeit wirklich gut.

Alternativ habe ich auch mal die SSD13xx library getestet, soweit so gut, Jedoch bekomme ich bei dieser meine Schriftart nicht importiert und ich finde auch keine Erklärung/Doku wie man das hin bekommen kann.

Hat von euch jemand eine Idee?

BetaCarotin:
Leider leider geht dies aber nicht bei custom fonts, also Schriftarten die man selber hinzugefügt hat.

Was ist ein "custom font"? Ein selbst erstellter in Adafruit_GFX\Fonts\ ?

BetaCarotin:
Hat von euch jemand eine Idee?

Zun Löschen den alten Wert invertiert schreiben.

agmue:
Was ist ein "custom font"? Ein selbst erstellter in Adafruit_GFX\Fonts\ ?
Zun Löschen den alten Wert invertiert schreiben.

Ja genau

agmue:
Was ist ein "custom font"? Ein selbst erstellter in Adafruit_GFX\Fonts\ ?
Zun Löschen den alten Wert invertiert schreiben.

Das probiere ich gleich aus! Danke

BetaCarotin:
Ich streite mich gerade mit der Adafruit GFX library.

Ich verwende ein 128x128 OLED mit SSD1351, Arduino Nano ...

Ich beschäftige mich gerade mit der Bibliothek von Oli Kraus, die viel mehr Möglichkeiten hat. SSD1351 finde ich dort nicht, wohl aber 128x128. Oli bietet auch speicherschonenede Konfigurationen und eine Menge Fonts. Er ist auch in diesem Forum aktiv.

Nur mal so als Alternative.

Die Bibliothek vom Oli wollte ich auch gerade vorschlagen.

Ich bin damit sehr schnell zu dem von mir gewünschten Ergebnis gekommen. Und dies als Arduino Anfänger mit schlechtem Englisch.

Gruß

MiReu

Hallo Zusammen

SSD1351 finde ich dort nicht

Also, wenn die U8g2 gemeint ist, dann wird der SSD1351 tatsächlich dort nicht unterstützt, da der SSD1351 ein controller für RGB displays ist. Allerdings würde Ucglib den SSD1351 unterstützen...

Grüße,
Oliver

Sorry Oliver, nun sehe ich es auch, sogar in Farbe :slight_smile:

So ich habe die UCGlib nun ausprobiert. Bin ich zu dösig oder kann man dort keine Bitmaps ausgeben?
Ich verzweifel langsam.. :frowning:

Ich habe mehrerer Sensorwerte und ein paar Icons (Schneeflocken etc) die ich ausgeben möchte. Das ganze soll nicht flackern und wenn möglich möchte ich so etwas wie alte / Segment Anzeigen durch entsprechende Schriftarten simulieren. Also eigentlich ein klassisches Arduino Projekt.. aber irgendwie komme ich nicht voran damit.

Hat vielleicht jemand einen Demo Sketch für die UCGLib mit Bitmapausgabe?

BetaCarotin:
So ich habe die UCGlib nun ausprobiert. Bin ich zu dösig oder kann man dort keine Bitmaps ausgeben?

Naja, ich hatte halt keine Bitmap Ausgabe programmiert. Das müsste man halt Pixel für Pixel selbst machen. Das Problem ist auch, das RGB Bitmaps sehr viel Speicher brauchen. Ausserdem gibt es kein geeignetes Format für Bilder. Weiter unten hab ich aber dennoch ein Beispiel verlinkt.

BetaCarotin:
Ich habe mehrerer Sensorwerte und ein paar Icons (Schneeflocken etc) die ich ausgeben möchte. Das ganze soll nicht flackern

Also manchmal glaube ich schon, dass Anspruch und Realität oft recht weit auseinanderliegen. Vielleicht bekommt man es mit einem ESP32 oder einem Due einigermaßen mit speziellen Libraries (falls es welche gibt) flackerfrei hin, aber bei allen anderen Boards kann man das komplett vergessen.

Besser wäre hier ein monochromes Display mit der Adafruit lib oder der U8g2. Das ist zwar nicht bunt, flackert dann aber auch nicht. Bei monochromen Displays muss nur 1/18 der Datenmenge übertragen werden und der Bildschirm passt u.U. auch noch ins RAM. Damit kommt man der Flackerfreiheit schon recht nahe.

BetaCarotin:
Hat vielleicht jemand einen Demo Sketch für die UCGLib mit Bitmapausgabe?

Ich hatte mal ein TGA bild von der SD Karte gelesen und mit Ucglib ausgegeben:

Oliver

Hi

Mit 320x200 Punkten und 4-Farb CGA-Grafik flackerte der heimische PC damals auch schon Mal, wenn rasante Spiel-Action herrschte - allerdings war der geneigte Zocker damals bei Weitem nicht so verwöhnt (als Alternative gab es nur Monocrom, ok, mit doppelter Auflösung) und die Hardware ratterte auch nur mit maximal 10MHz vor sich hin und musste noch ein OS mitschleppen.

Heute ist Es schon schwieriger, man muß gegen den Alltags-Gegenstand Handy-Smart-Phone anstinken, Welche eine Rechenleistung haben, womit Die damals wohl bis zur Sonne und zurück gekommen wären (mit Zwischenlandung).
Heute reicht Das dann noch gerade Mal für Tetris, immerhin in True-Color :wink:

Wenn das Display Es hergibt, den Inhalt schnell genug auszutauschen - dann liegt es an Dir, diese Datenmenge in entsprechend kurzer Zeit zur Verfügung zu stellen.
Irgendwo muß ja momentan der Flaschenhals sitzen.

MfG

Danke für eure Antworten!
Ich glaube ich verstehe es nicht so ganz...und ich hab mich etwas umständlich ausgedrückt..

Wenn ich die Adafruit GFX und die dazu passende SS1351 library nehme und keine Schrift definiere, also auf standard schrift bleibe, dann kann ich einen Schrifthintergrund definieren.

Also in meinem Fall weiße Schrift auf schwarzem Grund. Bekomme ich einen neuen Senorwert, so schreibe ich nur den Sensorwert neu aufs Display. kein Flackern! Klappt ganz wunderbar.

Nun habe ich verschiedene Icons aus Bitmaps erzeugt, die ich Pixel für Pixel anzeige und ihnen eine (!) Farbe zuweise. Auch die kommen und gehen- ohne großes geflacker.
Die sehen zB: so aus:
// 'tempmotor jpg', 24x24px
const unsigned char tempmotor [] PROGMEM = {
0x00, 0x70, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x89, 0xe0, 0x00, 0x89, 0xe0, 0x00, 0x88, 0x00, 0x00,
0x89, 0xe0, 0x00, 0x89, 0xe0, 0x00, 0x88, 0x00, 0x00, 0xa9, 0xe0, 0x00, 0xa9, 0xe0, 0x00, 0xa8,
0x00, 0x00, 0xa8, 0xe0, 0x00, 0xa8, 0xe0, 0x01, 0xac, 0x00, 0x03, 0x76, 0x00, 0x06, 0xfb, 0x00,
0x05, 0xfd, 0x00, 0x05, 0xfd, 0x00, 0x05, 0xfd, 0x00, 0x05, 0xfd, 0x00, 0x06, 0xfb, 0x00, 0x03,
0x76, 0x00, 0x01, 0xdc, 0x00, 0x00, 0xf8, 0x0
};

Möchte ich nun aber andere Schrift haben, kann ich keine Schrifthintergrundfarbe mehr definieren und die Probleme beginnen..

Ein Rechteck in der Größe eines Digits führt zu flackern des Wertes (Wenn dieser überschrieben wird). Also- sehr viel längeres flackern als einfach nur ein digit wechsel, man sieht dass das digit ausgeht und wieder neu geschrieben wird.

Den alten Sensorwert farblich invertieren, schreiben (also ausradieren), farben wieder umdrehen und neuen Sensorwert schreiben klappt, ist aber genau so langsam wie das rechteck. Spätestens bei zwei Werten flackern diese mit Zeitverzögerung.

Was macht denn die Standart Schrift anders, das es mit ihr so einfach ist?
Kann ich nicht einfach meine selbst erstellte Schrift (font generator Angularclient) so umbauen, dass diese automatisch auf schwarzem Hintergrund schreibt?

Was muss ich dazu machen?

Alternativ

..Oder wie erstelle ich eine Schriftart, die genau so funktioniert wie die standardschriftart in der GFX?
Nach was muss ich suchen um eine Beschreibung zu finden wie man Schriften eigentlich definiert? Ich kann zwar alles hin und her kopieren, aber ich verstehe nicht was ich da tue..mit diesen lustigen Werten die ich da ins PROGMEM schreibe...

Alternativ....Wie zeige ich meine kleinen Icons in der UCGLib an?

Alternativ....Wie zeige ich meine kleinen Icons in der UCGLib an?

Wie ich schon geschrieben hatte, das müsste man (wie in meinem verlinkten Beispiel) Pixel für Pixel selbst machen.

Um die Adafruit Lib zu verstehen müsste man sich halt die Mühe machen, den Sourcecode der Lib zu lesen.

Grüße,
Oliver

Ich verstehe das Beispiel nicht- Ich muss also in jedem Fall eins von beidem lernen. Ich finde Deine Lib interessanter und würde gern verstehen wie man aus den vielen Hex werten (cpp?) zu einem Pixel kommt. Egal was ich google- ich lande nie richtig. Vermutlich google ich falsch oder die falschen Begriffe.

Kannst Du - oder jemand anders- mir sagen nach was ich suchen muss? Oder wie es funktioniert? Was mache ich da eigentlich wenn ich ein Bitmap in cpp umwandle- alles ins Progmem schreibe und dann nur noch drawbitmap aufrufe.. sind das hex werte die einzelne Pixelgruppen beschreiben oder ist das ein anderes Format?

Hallo,

postmaster-ino:
Heute ist Es schon schwieriger, man muß gegen den Alltags-Gegenstand Handy-Smart-Phone anstinken, Welche eine Rechenleistung haben, womit Die damals wohl bis zur Sonne und zurück gekommen wären (mit Zwischenlandung).

Spaß ohne, die sind damals mit einem Taschenrechner zum Mond (und zurück) geflogen. :wink: (wenn es um die Rechenleistung geht)

Es gibt in der Adafruit GFX lib folgende Funktion, die das ganze erleichtern soll:
tft.getTextBounds(string, x, y, &x1, &y1, &w, &h);Quelle: Adafruit GFX
Allerdings hat der Author das in der gfx.cpp groß dokumentiert.

Adafruit_GFX.cpp:
// NOTE: THERE IS NO 'BACKGROUND' COLOR OPTION ON CUSTOM FONTS.
// THIS IS ON PURPOSE AND BY DESIGN. The background color feature
// has typically been used with the 'classic' font to overwrite old
// screen contents with new data. This ONLY works because the
// characters are a uniform size; it's not a sensible thing to do with
// proportionally-spaced fonts with glyphs of varying sizes (and that
// may overlap). To replace previously-drawn text when using a custom
// font, use the getTextBounds() function to determine the smallest
// rectangle encompassing a string, erase the area with fillRect(),
// then draw new text. This WILL infortunately 'blink' the text, but
// is unavoidable. Drawing 'background' pixels will NOT fix this,
// only creates a new set of problems. Have an idea to work around
// this (a canvas object type for MCUs that can afford the RAM and
// displays supporting setAddrWindow() and pushColors()), but haven't
// implemented this yet.

Quelle: Adafruit_GFX.cpp

lg dony

Ich fasse nochmal zusammen:
Du besitzt ein SSD1351 Display und möchtest (einfarbige?) Icons und flickerfreien Text mit einem selbst-definierten Font darstellen.

Flicker-freier Text:
In der Adafruit Lib gibt es dazu scheinbar eine Spezial-Lösung mit einem bestimmten Font.
Laut "Note" im Code gibt es dafür keine Lösung mit "custom" Fonts.

Als Author der Ucglib, kann ich das nur bestätigen. Aktiviert man die Hintergrundfarbe und nimmt man in Ucglib einen monospace Font, sollte es einigermaßen flickerfrei gehen.

Flicker-freie Icons:
Dafür gibt es aus meiner Sicht erst recht keine Lösung um das flicker-frei hinzubekommen. Ausserdem kommt noch das Problem dazu, dass wir nicht wissen, in welchem Format dein Bild abgespeichert ist (dazu unten mehr).

Die Frage ist eigentlich: Warum nimmst Du denn ein RGB SSD1351 Display? Warum nicht ein monochromes Display benutzen, für das es (A) wunderbare flickerfreie Lösungen gibt (Adafruit Lib oder U8g2) und (B) das Zeichnen von Bitmaps überhaupt gar kein Problem ist. Hier nur mal ein recht nettes Tutorial zu dem Thema: https://sandhansblog.wordpress.com/2017/04/16/interfacing-displaying-a-custom-graphic-on-an-0-96-i2c-oled/

Monochrome Displays gibt es genug: Beispielsweise so ein SSD1306 128x64 OLED aus Fernost oder irgendein anderes Monochromes LCD (beispielsweise die JLX Displays oder die DOGM Reihe, die es auch bei deutschen Elektronikversendern gibt). Anregungen gibt es auch hier: gallery · olikraus/u8g2 Wiki · GitHub.

Kannst Du - oder jemand anders- mir sagen nach was ich suchen muss? Oder wie es funktioniert? Was mache ich da eigentlich wenn ich ein Bitmap in cpp umwandle- alles ins Progmem schreibe und dann nur noch drawbitmap aufrufe..

Ich denke das ist genau der Punkt. Ich weiss es nämlich auch nicht, was du da umwandelst. Aber ohne das zu wissen, kann man natürlich auch nicht die Pixel zurückgewinnen.

Bei meinem oben verlinkten Beispiel hatte ich in Bild im TGA Format ausgelesen. Das ist natürlich schon kompliziert und erfordert das einlesen in das TGA Datenformat. Aber wenn Du selbst nicht weisst, was das für eine Bitmap ist, ist es schwierig. Für monochrome Bilder empfehle ich XBM (wie im verlinkten Tutorial verwendet). Für eine XBM Bitmap könnte ich dann hier auch den Ucglib code liefern, aber flickerfrei wäre das dann eben nicht.

Oliver

dony:
Hallo,
Spaß ohne, die sind damals mit einem Taschenrechner zum Mond (und zurück) geflogen. :wink: (wenn es um die Rechenleistung geht)

Es gibt in der Adafruit GFX lib folgende Funktion, die das ganze erleichtern soll:
tft.getTextBounds(string, x, y, &x1, &y1, &w, &h);Quelle: Adafruit GFX
Allerdings hat der Author das in der gfx.cpp groß dokumentiert.Quelle: Adafruit_GFX.cpp

lg dony

Ja- und das funktioniert nicht, mit getbounds flackerts trotzdem

Und "the classic font" ist exact nur diese eine Systemschrift, oder mache ich da was falsch?

BetaCarotin:
...oder mache ich da was falsch?

Nein, das glaube ich nicht. Hier liegt das Problem an der Rechenpower. Du bräuchtest wahrscheinlich einen Due oder sowas damit es flackerfrei ist.

Aber ein Gedanke, Links steht welcher Wert, Rechts (oder mittig) steht der jeweilige Wert. Dann zeichnest Du ein Rechteck über alle Werte und beginnst mit den tft.print's. Da wird man wahrscheinlich beim Text Aufbau zuschauen können!?
Aber: Zeilenweise Rechtecke... schon probiert?

Ich kann mich sonst auch nur Oliver anschließen.

lg dony

Ja fast!
Ich habe ein wunderschönes Farb OLED in 128x128 mit einem SSD1351.
Der einzige Text der nicht flackert ist die eckige Systemschrift die es nur in einer Größe gibt, will man sie etwas größer haben, dann geht nur doppelt so groß. Dann pixelts extrem und ist zu groß. Mit anderen Worten: Voillkommen unbrauchbar.
Alle anderen Custom fonts haben das Problem dass sie den Hintergrund nicht schreiben und somit sich selbst überschreiben.
Screen löschen und neu schreiben ist zu langsam.
Rechteck ziehen, über dem digit ist zu langsam
getbounds flackert auch deutlich sichtbar. Je größer die Schriftart, desto schlimmer.

Die Icons sind flackerfrei, ich zeichne sie nur einmal und lasse sie stehen, bzw. lösche sie, wenn ich sie nicht mehr brauche.

Warum kein Monocromes Display? Zum einen gabs das nicht in 128x128 zum anderen ist der Trick dass ich nicht Weiss auf Schwarz schreibe, sondern ein etwas gelbliches Weiß verwende, dass an meine Tachobeleuchtung im Auto angepasst ist (Das ganze soll ins Auto gebaut werden, später). Die Icons haben auch Farben, so ist die Temperaturwarnung rot, die Schneeflocke blau, die Tankwarnung gelb...

Wie habe ich die Icons erzeugt? So wie es für die Adafruit beschrieben wurde, ich habe den konvertierer genutzt, ein bmp reingeladen, ein bytechaos erhalten (mein Temperaturicon habe ich gepostet). wenn ich dann den draw.bitmap befehl verwende, erscheint mein icon auf dem display. Ich hab keine Ahnung was ich da tue- im wesentlichen aber das gleiche was auch der demo/Beispiel Sketch macht.

Zusammenfassend habe ich also das Problem mit Adafruit das es flackert wenn ich einzelne Sensorwerte update
(egal mit welcher Methode: Invertiert überschreiben und neu schreiben, Rechteck ziehen, getbounds)

Mit der UCglib beckome ich die Icons nicht angezeigt, da ich nicht weiß wie ich von einzelnen Pixeln zu meinen kleinen piktogrammen komme

Ich habe hier mehrere ssd1306 liegen, aber- ich mein, dass kann doch nicht die Lösung sein. Ist das 128x128 OLED einfach unbrauchbar mit dem Arduino?

dony:
Nein, das glaube ich nicht. Hier liegt das Problem an der Rechenpower. Du bräuchtest wahrscheinlich einen Due oder sowas damit es flackerfrei ist.

Aber ein Gedanke, Links steht welcher Wert, Rechts (oder mittig) steht der jeweilige Wert. Dann zeichnest Du ein Rechteck über alle Werte und beginnst mit den tft.print's. Da wird man wahrscheinlich den Text Aufbau, zuschauen!?
Zeilenweise Rechtecke... schon probiert?

Ich kann mich sonst auch nur Oliver anschließen.

lg dony

Ja man kann dem Rechteck und dem Textaufbau zuschauen. Selbst bei nur einer Zahl die man schreibt. Das verstehe ich nicht, mit dem ssd1306 schreibt man ein ganzes Display flackerfrei und hier will ich nur ein kleines schwarzes rechteck ziehen und dann ist schon Schluss.. das muss man doch irgendwie schlau lösen können. Ich erwarte ja keine Megagrafiken- lediglich ein paar Pixel. Ich mein...Temperatur auf nem OLED anzeigen, dass sollte doch ein Nano können