Forum: Mikrocontroller und Digitale Elektronik Arduino fonts "verkleinern"


von Max (Gast)


Lesenswert?

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!

von Karl M. (Gast)


Lesenswert?

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.

von Christoph db1uq K. (christoph_kessler)


Lesenswert?

https://github.com/lexus2k/ssd1306/blob/master/src/ssd1306_fonts.c
hier ab Zeile 39 ist die Hex-Tabelle zum Font ssd1306xled_font6x8. Sehr 
viel gibt es da nicht zu reduzieren.

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

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.

von Erwin E. (kuehlschrankheizer)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

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).

von MaWin (Gast)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

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.

von Wolfgang (Gast)


Lesenswert?

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. ;-)

von Erwin E. (kuehlschrankheizer)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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€).

von leo (Gast)


Lesenswert?

Max schrieb:

>  Nun möchte ich den Footprint der Schriftart reduzieren

Wozu? Ich habe hier e.g. eine 5x7 Font, die braucht:
1
echo '(128-32)*5' | bc
2
480
... Bytes fuer die sichtbaren Zeichen.

Was hast du fuer einen Arduino, wo du kein halbes KByte frei hast?

leo

von Max (Gast)


Lesenswert?

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.

von c-hater (Gast)


Lesenswert?

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...

von Joachim B. (jar)


Lesenswert?

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.

von georg (Gast)


Lesenswert?

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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.