Hallo zusammen
Ich verwende die lcdgfx Bibliothek (https://github.com/lexus2k/lcdgfx)
für einen OLED display, der an meinem Arduino über I2C angeschlossen
ist.
Für die Darstellung von Text kommt die Schrift "ssd1306xled_font6x8" zum
Einsatz. Diese wird per PROGMEM eingebunden. Nun möchte ich den
Footprint der Schriftart reduzieren, da ich nicht alle verfügbaren
Zeichen und Buchstaben benötige. Nach längerer Suche im Internet konnte
ich aber keine entsprechenden Informationen finden.
Gibt es eine Möglichkeit, die Schriftart so zu reduzieren, dass nur noch
die benötigten Zeichen mit kompiliert werden?
Vielen Dank!
Max schrieb:> Gibt es eine Möglichkeit, die Schriftart so zu reduzieren, dass nur noch> die benötigten Zeichen mit kompiliert werden?
Antwort: klar, das nennt sich programmieren und man benötigt halt eine
andere Zuordnung wie die ASCII-Zeichen Repräsentation, also die Nummer
und den Speicherort im Font.
Nutze ein assoziatives Liste, um den Speicherort im Front zu finden.
Das wird mit dem aktuellen Konzept kaum möglich sein.
Erstens sind die Fonts pixelbasiert und optisch bereits auf das
Allernötigste reduziert.
Zweitens sind diese Zeichen, am ACII-Code orientiert, in Arrays mit
fester Größe "gelagert". Es bringt erstmal nichts, dort einzelne
"Stellplätze" leer zu lassen. Nullbits brauchen genausoviel
Speicherplatz wie Einserbits.
Um den benötigten Speicherplatz zu reduzieren, würde der Font eine
zusätzliche Tabelle mit den belegten Zeichen benötigen. Das wiederum
benötigt eine Überarbeitung der Ausgabe- und Rendering-Routinen in den
verwendeten Libs. Geht alles, macht aber Arbeit.
Ich habe eine Library für SSD1306 OLEDs geschrieben, die Zeichensätze
von 8..64 Pixeln Höhe ausgeben kann. Dabei habe ich das gleiche Problem
gehabt wie du, nämlich dass vor allem die größeren Zeichensätze sehr
viel Platz im Flash verbrauchen.
Deshalb nutze ich Sprungtabellen, in denen die nicht benötigten Zeichen
durch Platzhalter ersetzt werden, so dass nur die tatsächlich benötigten
Zeichen im Flash vorgehalten werden müssen.
Leider hilft diese Vorgehensweise bei einem 8er Font nicht viel, weil
der gesparte Platz für die Zeichendaten durch den Speicherverbrauch der
Tabelle weitgehend aufgefressen wird. Bei größeren Fonts ist die
Speicherersparnis aber erheblich.
Das entspricht auch meinen Versuchen. An dem kleinen Font kann man
nichts mehr weg optimieren, das zahlst du woanders wider drauf.
Für größere Texte kann man allerdings auf größere Fonts verzichten und
einfach alle Pixel doppelt so breit und doppelt so hoch darstellen (also
um Faktor 2 skalieren).
Stefan ⛄ F. schrieb:> An dem kleinen Font kann man nichts mehr weg optimieren, das zahlst du> woanders wider drauf.
Na ja, man muss ja nicht ASCII codierte Zeichen übergeben sondern kann
sich z.B. auf die 40 tatsächlich benutzten beschränken von 0..39. Dann
schiebt man den Zeichensatz zusammen und gut is.
Und wenn man unbedingt im Programm ASCII verwenden will, kommt eine
charmap Funktion davor, die per 256 byte Tabelle ummappt. Die 256 sind
dann hoffentlich weniger als zuvor gewonnen.
MaWin schrieb:> kann sich z.B. auf die 40 tatsächlich benutzten beschränken
Lieber nicht.
Das Alphabet hat 26 Buchstaben, die gibt es alle in klein und groß. Das
sind schon 52. Dazu kommen Zahlen, Umlaute und Sonderzeichen.
> Die 256 sind dann hoffentlich weniger als zuvor gewonnen.
Es sind ja jetzt schon weniger als 100.
MaWin schrieb:> Dann schiebt man den Zeichensatz zusammen und gut is.
Eben genau das gibt es nicht umsonst.
Stefan ⛄ F. schrieb:> Das Alphabet hat 26 Buchstaben, die gibt es alle in klein und groß. Das> sind schon 52. Dazu kommen Zahlen, Umlaute und Sonderzeichen.
Wer weiss, vielleicht werden nur ein paar Zahlen benötigt. ;-)
Stefan ⛄ F. schrieb:> Für größere Texte kann man allerdings auf größere Fonts verzichten und> einfach alle Pixel doppelt so breit und doppelt so hoch darstellen (also> um Faktor 2 skalieren).
Diese Methode habe ich verschiedentlich in Libraries gesehen, aber
ehrlich gesagt finde ich das nicht so ideal. Wenn schon ein
Grafikdisplay da ist, soll der Anwender auch schöne Schriften sehen.
Sonst kann man ja gleich ein Charakter Display nehmen.
Um welchen Arduino geht es denn, daß Du so knapp an Flash bist.
Die 256kB des ATmega2560 sollte doch weit reichen.
Du kannst ja die Zeichentabellen in nen externen Flash auslagern.
Z.B. der IS25LQ040B-JNLE hat 512kB (SO-8, 3.3V, Farnell: 0,393€).
Oder der S25FL064LABMFI013 (8MB, 1,08€).
Wow, vielen Dank für all eure Antworten! Das hatte ich mir fast schon
gedacht, dass die Standard ASCII Tabelle ohne leeren Zeichen "simuliert"
werden müsste.
leo schrieb:> Wozu? Ich habe hier e.g. eine 5x7 Font, die braucht:echo '(128-32)*5' |> bc> 480> ... Bytes fuer die sichtbaren Zeichen.
Vielen Dank auch für deinen konstruktiven Beitrag! Mein Programm beläuft
sich jetzt auf mehr als 2000 Zeilen Code exkl. Bibliotheken. Und
momentan kämpfe ich um jede 10 Bytes, die ich mit Optimierung
hinbekomme.
Max schrieb:> Mein Programm beläuft> sich jetzt auf mehr als 2000 Zeilen Code
2000? Das ist eigentlich garnix.
> exkl. Bibliotheken.
Laß' die Bibliotheken weg und ersetze sie durch eigenen, für das
konkrete Problem optimierten Code. Danach kannst du mit einiger
Wahrscheinlichkeit den nächst kleineren Controller nehmen und hast
immer noch genug freien Platz...
Christoph db1uq K. schrieb:> hier ab Zeile 39 ist die Hex-Tabelle zum Font ssd1306xled_font6x8. Sehr> viel gibt es da nicht zu reduzieren.
eigentlich ist es ein 5x7 Font
Jedem Zeichen eine führende 0 mitzugeben als Spaltentrenner ist schon
etwas platzverschwenderich (OK "nur" flash, aber wenn der eng wird?
manchmal fehlen ja 100 Byte)
siehe LCD Font im 5110
0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
0x00, 0x00, 0x42, 0x7F, 0x40, 0x00, // 1
0x00, 0x42, 0x61, 0x51, 0x49, 0x46, // 2
0x00, 0x21, 0x41, 0x45, 0x4B, 0x31, // 3
0x00, 0x18, 0x14, 0x12, 0x7F, 0x10, // 4
0x00, 0x27, 0x45, 0x45, 0x45, 0x39, // 5
führende 0 ist nur Spaltentrenner!
Adafruit bekommt das in der GFX LIB zwar besser hin
0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
0x00, 0x42, 0x7F, 0x40, 0x00, // 1
0x42, 0x61, 0x51, 0x49, 0x46, // 2
0x21, 0x41, 0x45, 0x4B, 0x31, // 3
0x18, 0x14, 0x12, 0x7F, 0x10, // 4
0x27, 0x45, 0x45, 0x45, 0x39, // 5
aber braucht trotzdem mehr RAM im Code
das die gleich aussehen, mir gefiel der 5110 Font besser also kompatibel
in die GFX "kopiert"
ich denke kleiner als 5x7 wird ein Font schwer lesbar, ich brauche auf
dem OLED ja fast auch schon eine Lupe, auf dem Nokia 5110 gehts mit
Lesebrille und auf dem 1,44" TFT 128x128 würde ich sogar alle Pixel
vervierfachen also doppelt in X und Y somit wären ja immer 20 Zeichen x
8 Zeilen möglich, immerhin mehr als auf dem Nokia5110 mit 14 Zeichen x 6
Zeilen.
0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C, // g
Joachim B. schrieb:> Jedem Zeichen eine führende 0 mitzugeben als Spaltentrenner ist schon> etwas platzverschwenderich
Und stimmt auch garnicht:
0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C, // g
Georg