How-to: Zeichen auf Nokia 5110/3310/PCD8544

Hallo!
Da ich gerade etwas mit oben aufgeführtem Display herumprobiert habe und dabei relativ hilflos war, hab ich gedacht ich könnte mal kurz schreiben, wie man mit dem Ding Zeichen "basteln" kann. Wer Fehler findet, ist natürlich herzlich eingeladen, diese aufzuzeigen, dann ändere ich diesen Eintrag hier.

Abgesehen vom Code im Playground ist das eigentlich ganz einfach, wenn man das System erstmal verstanden hat.

Die 84 x 48 Felder des Displays sind auf 5 Spalten breiten und 8 Zeilen hohen "Kästen" aufgebaut.

Für ein Zeichen müssen wir also 5 Byte speichern. Dabei gelten folgende Wertigkeiten (für jede Zeile):

[ ][ ][ ][ ][ ]   1
[ ][ ][ ][ ][ ]   2
[ ][ ][ ][ ][ ]   4
[ ][ ][ ][ ][ ]   8
[ ][ ][ ][ ][ ]  16
[ ][ ][ ][ ][ ]  32
[ ][ ][ ][ ][ ]  64
[ ][ ][ ][ ][ ] 128

Wollen wir ein "F" mit einem Punkt definieren, dann ergibt sich folgendes:

[X][X][X][X][X]   1
[X][ ][ ][ ][ ]   2
[X][ ][ ][ ][ ]   4
[X][X][X][ ][ ]   8
[X][ ][ ][ ][ ]  16
[X][ ][ ][ ][ ]  32
[X][ ][ ][ ][ ]  64
[X][ ][ ][ ][X] 128

Für die Definition im Code bedeutet dies, dass wir in der

  1. Spalte 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128 = 255
  2. Spalte 1 + 8 = 9
  3. Spalte 1 + 8 = 9
  4. Spalte 1
  5. Spalte 1 + 128 = 129
    als Werte erhalten und dies in hexadezimale Werte umrechnen müssen.

Das kann man entweder im Kopf, oder man nimmt eines der unzähligen kostenlosen Tools im Netz dafür.
Es folgen daraus für unsere fünf Bytepaare folgende Werte:

0xff, 0x09, 0x09, 0x01, 0x81

Auf gleiche Art und Weise lässt sich jedes einzelne Feld "beschreiben" und man kann so (von Hand) Grafiken erstellen...

Ja, diese Erkenntnis wollte ich noch kurz teilen, bevor ich schlafen gehe. Vielleicht kann der ein oder andere es ja gebrauchen...

Anmerkung: Fünf Byte Breite ist in keiner Weise festgelegt und frei änderbar. Schmälere oder breitere Fonts sind kein Problem. :slight_smile:
Auch sind variable Buchstabenbreiten interessant und problemlos machbar: Es macht ja z.B. keinen wirklichen Sinn, ein "i" genauso breit zu machen wie ein "m" oder "w". Ich speichere mir daher zu jedem Buchstaben in einem separaten Array die jeweilige Breite (beim "i" z.B. reicht ein einzelnens Pixel plus ein Pixel Abstand zum nächsten Buchstaben) und kann so das maximum an Text pro Zeile auf dem Display herausholen. :smiley:

Die 8 Pixel Höhe (also eigentlich ist es ja eine 7-Punkt-Schrift plus einen Punkt, also eine Zeile, Abstand zwischen den Buchstaben) des Fonts ist ein bisschen schwerer abzuändern, aber zusammen mit Bitshift-Operationen durchaus machbar, man könnte z.B den Font auf insg. 6 Pixel Höhe (5 Pixel Font plus einem Pixel Abstand) planen, dann könnte man statt 6 nun 8 Zeilen Text unterbringen. :slight_smile:

Ich würde die Buchstaben trotzdem in einem Byte speichern (also 2 Bit verschenken), dann würde die erste Zeile funktionieren wie gehabt. Für die zweite Zeile würde ich die Bytes der Buchstaben dann je zweimal anfassen: Einmal um sechs Bit nach "unten" verschoben (siehe Bitshift) in die erste Zeile ODERn einfügen und dann nochmal um zwei Bit nach "oben" verschoben in die zweite Zeile einfügen. Das setzt allerdings voraus dass man mit einer Kopie des Grafikspeichers im RAM arbeitet, was 504 Bytes kostet.

Das ist natürlich alles absolut korrekt, gerade das mit der Breite.

Ich habe darauf geschlossen, weil im Code-Beispiel das Array mit den Zeichen mit fünf Pixeln Breite definiert ist.
Aber klar, ein gesperrter Font wäre natürlich auch möglich.

Insgesamt ist das Display ja eine coole Basis, finde ich.

Gibt es vom Display her eigentlich eine Möglichkeit in die nächste Zeile zu springen und wieder vorne anzufangen? Das ist in einigen Quellcodes integriert, aber ich dachte, das gäbe es vielleicht auch serienmäßig.
Ich bräuchte sowas nämlich, um ein Menü darstellen zu können...