Sie sind auf Seite 1von 36

Wilkommen!

Vielen Dank, dass sie sich für unseren AZ-Delivery 128x64 LCD Bildschirm
entschieden haben. In den nachfolgenden Seiten werden wir Ihnen erklären
wie Sie das Gerät einrichten und nutzen können.

Viel Spaß!
Eine Flüssigkristallanzeige, auch LCD genannt, ist ein Gerät, dass
Flüssigkristalle verwendet, um das Licht aus der Hintergrundbeleuchtung
der Anzeige zu blockieren. Flüssigkristalle selber strahlen kein Licht aus,
sondern blockieren das aus dem Gegenlicht kommende Licht und erzeugen
monochrome oder farbige Bilder. Die Flüssigkristalle leiten Strom, und wenn
Strom durch diese Kristalle fließt, verändern sie ihre Struktur, um Licht
durchzulassen. Fließt kein Strom, kehren die Kristalle in ihren
Ausgangszustand zurück. In diesem Zustand wird kein Licht durchgelassen.

Technische Daten

Betriebstemperatur: von -20 °C bis 70 °C


Spannungslevel für logic: 3.3V oder 5V
Spannungslevel für Leistung: 5V
Pixelanzahl: 128 x 64 = 8192 Pixel
Pixelgröße: 0.42 x 0.58 mm
Dimensionen: 70 x 93 x 13 mm
Ansichtsbereich: 39 x 70 mm
LCD-Typ: STN Negativ, Blau, Transmissiv
Hintergrundbeleuchtung: LED, Weiß
Betrachtungswinkel: von 20° bis 40°
Modi: paralleler (8bit, 4bit) und serieller Modus
LCD-Displays mit einer Auflösung von 128x64 bestehen aus 8192 Pixel, die
einzeln genutzt werden können. Die anderen beiden LCD-Displays in
unserem Sortiment, mit einer Auflösung 16x02 und 20x04 sind in der Lage,
Buchstaben, Zahlen und einige Zeichen anzuzeigen. Diese beiden Displays
haben vordefinierte Stellen für Zeichen. Das Modell mit 16x02 hat zwei
Zeilen und in jede dieser Zeilen passen 16 Zeichen. Bei unserem anderen
Modell mit 20x04 gibt es vier Zeilen mit Platz für jeweils 20 Zeichen.

Im Gegensatz zu diesen Displays ist das 128x64-Modell ein Grafikdisplay,


d.h. es können alle Arten von Zeichen, mit unterschiedlichen Schriften und
Größen oder monochromen Grafiken an beliebiger Stelle auf dem Display
angezeigt werden.

Das 128x64-Modell besitzt zwei Treiberchips. Einer davon ist der "KS0108"
(davon wurden zwei verbaut) und der andere ist der "KS0107". Einer der
"KS0108"-Chips betreibt 64x64 Pixel und der andere "KS0108" weitere
64x64 Pixel. Das bedeutet, dass das 128x64 Display tatsächlich aus zwei
64x64 Bildschirmen besteht. Mit den CS1- und CS2-Pins können wir
auswählen, welcher der Chips die Daten im Datenbus empfängt
(DB0 - DB7-Pins). Wenn der Chip die Daten empfängt, aktiviert er das Pixel
für seinen Teil des Displays.

Das 128x64 Display hat 20 Pins. Pinbelegung wie unten abgebildet.


BLA- und BLK-Pins werden verwendet, um die Hintergrundbeleuchtung des
Displays ein- oder auszuschalten. Um das Display einzuschalten, verbinden
Sie den BLA-Pin mit dem +5V und den BLK mit GND.

Der V0-Pin wird für den Kontrast verwendet. Schließen Sie es an eine
analoge Spannung an. Der Wert dieser analogen Spannung wird benötigt,
um den Farbton des Displays anzupassen. In unserem Beispiel verwenden
wir ein Potentiometer, bei dem ein Pin mit +5V, der zweite mit GND und der
mittlere Pin mit V0 verbunden ist. Durch Drehen der Welle des
Potentiometers ändern wir die Analogspannung und damit den Kontrast der
Anzeige.
Das Display kann parallel und seriell arbeiten. Diese Modi werden über den
PSB-Pin ausgewählt. Wenn wir diesen Pin hochziehen, dann ist der
Parallelmodus ausgewählt. Wird der Pin runtergezogen, dann ist der serielle
Modus ausgewählt. Der Parallelmodus arbeitet in zwei anderen Modi, 8bit
und 4bit. Das bedeutet, dass die Daten von allen D0 - D7 Pins im 8bit- und
von allen D4 - D7 Pins im 4bit-Modus gelesen werden. Parallele Modi
werden in diesem E-Book nicht näher behandelt.

In unseren Verbindungsbeispielen werden wir den seriellen Modus


verwenden. Wir verwenden diesen, weil dabei weniger Pins für den Betrieb
benutzt werden, als im Parallelbetrieb. Im seriellen Modus verwenden wir
nur einen Pin für den Datenaustausch und zwei weitere, um diesen seriellen
Modus auszuwählen und einzurichten.

Der serielle Modus ist eigentlich eine partielle SPI-Schnittstelle, da wir


keinen MISO-Pin des SPI verwenden. Wir verwenden SCL-, MOSI- und CS-
Pins von der SPI-Schnittstelle und verbinden diese:
Für Atmega328P Board:
E bis SCL entspricht dem D13
R/W bis MOSI entspricht dem D11
RS bis CE entspricht dem D10

Für Raspberry Pi:


E bis SCL entspricht dem GPIO11 (SPIO_SCLK),
R/W bis MOSI entspricht dem GPIO10 (SPIO_MOSI)
RS bis CE entspricht dem GPIO8 (SPIO_CE0) (generell auf jeder
anderen GPIO)
Verbindung des Displays mit dem Atmega328P Board
Verbinden Sie das Display mit dem Mikrocontroller-Karte, wie unten
abgebildet:

LCD Pin > Pin


GND > GND Schwarzer Draht
VCC > 5V Roter Draht
RS > D10 Grüner Draht
R/W > D11 Purple Draht
E > D13 Brauner Draht
PSB > GND Schwarzer Draht
BLA > 5V Roter Draht
BLK > GND Schwarzer Draht

Das blaue Potentiometer im Verbindungsplan wird verwendet, um den


Kontrast des Displays einzustellen. Ein Pin des Potentiometers ist an +5V
angeschlossen, der zweite an GND und der mittlere Pin ist an den V0-Pin
des Displays (Blauer Draht auf dem Anschlussplan der vorherigen Seite).
Durch Drehen der Welle des Potentiometers ändern wir die
Analogspannung und damit den Kontrast der Anzeige.

Laut unserem Verbindungsplan verwenden wir das Display im seriellen


Modus, indem wir den PSB-Pin zu GND bringen. Das bedeutet, dass wir
nur einen Pin für die Steuerung des Displays verwenden. Die anderen Pins
sind für Leistung, Kontrast und Einstellung des seriellen Modus.
Arduino IDE Library

Wir werden die “u8g2”-Library benutzen. Um diese Library runterzuladen,


öffnen Sie ihr Arduino IDE. Gehen Sie bis Tools > Manage Libraries. In
einem sich neu öffnenden Fenster geben Sie in dem Suchfeld “u8g2” ein
und installieren Sie die “U8g2” library von “oliver”.

Danach gehen Sie zu File > Examples und scrollen bis zu den“U8g2”-
Skizzenbeispielen. Wir werden File > Examples > U8g2 > full_buffer >
GraphicsTest benutzen, aber passen es an unsere Bedürfnisse an.
Code:
#include <U8g2lib.h>
U8G2_ST7920_128X64_F_SW_SPI u8g2(U8G2_R0, 13, 11, 10);
// clock=13, data=11, CS=10
const char COPYRIGHT_SYMBOL[] = {0xa9, '\0'};
void u8g2_prepare() {
u8g2.setFont(u8g2_font_6x10_tf);
u8g2.setFontRefHeightExtendedText();
u8g2.setDrawColor(1);
u8g2.setFontPosTop();
u8g2.setFontDirection(0);
}
void u8g2_box_frame() {
u8g2.drawStr(0, 0, "drawBox");
u8g2.drawBox(5, 10, 20, 10);
u8g2.drawStr(60, 0, "drawFrame");
u8g2.drawFrame(65, 10, 20, 10);
}
void u8g2_r_frame_box() {
u8g2.drawStr(0, 0, "drawRFrame");
u8g2.drawRFrame(5, 10, 40, 15, 3);
u8g2.drawStr(70, 0, "drawRBox");
u8g2.drawRBox(70, 10, 25, 15, 3);
}
void u8g2_disc_circle() {
u8g2.drawStr(0, 0, "drawDisc");
u8g2.drawDisc(10, 18, 9);
u8g2.drawDisc(30, 16, 7);
u8g2.drawStr(60, 0, "drawCircle");
u8g2.drawCircle(70, 18, 9);
u8g2.drawCircle(90, 16, 7);
}

void u8g2_string_orientation() {
u8g2.setFontDirection(0);
u8g2.drawStr(5, 15, "0");
u8g2.setFontDirection(3);
u8g2.drawStr(40, 25, "90");
u8g2.setFontDirection(2);
u8g2.drawStr(75, 15, "180");
u8g2.setFontDirection(1);
u8g2.drawStr(100, 10, "270");
}
void u8g2_line() {
u8g2.drawStr( 0, 0, "drawLine");
u8g2.drawLine(7, 10, 40, 32);
u8g2.drawLine(14, 10, 60, 32);
u8g2.drawLine(28, 10, 80, 32);
u8g2.drawLine(35, 10, 100, 32);
}
void u8g2_triangle() {
u8g2.drawStr( 0, 0, "drawTriangle");
u8g2.drawTriangle(14, 7, 45, 30, 10, 32);
}
void u8g2_unicode() {
u8g2.drawStr(0, 0, "Unicode");
u8g2.setFont(u8g2_font_unifont_t_symbols);
u8g2.setFontPosTop();
u8g2.setFontDirection(0);
u8g2.drawUTF8(10, 15, "☀");
u8g2.drawUTF8(30, 15, "☁");
u8g2.drawUTF8(50, 15, "☂");
u8g2.drawUTF8(70, 15, "☔");
u8g2.drawUTF8(95, 15, COPYRIGHT_SYMBOL); //COPYRIGHT SIMBOL
u8g2.drawUTF8(115, 15, "\xb0"); // DEGREE SYMBOL
}

void setup() {
u8g2.begin();
u8g2_prepare();
}
void loop() {
u8g2.clearBuffer();
u8g2_prepare();
u8g2_box_frame();
u8g2_disc_circle();
u8g2.sendBuffer();
delay(1500);

u8g2.clearBuffer();
u8g2_r_frame_box();
u8g2.sendBuffer();
delay(1500);

u8g2.clearBuffer();
u8g2_line();
u8g2.sendBuffer();
delay(1500);

u8g2.clearBuffer();
u8g2_triangle();
u8g2.sendBuffer();
delay(1500);

u8g2.clearBuffer();
u8g2_unicode();
u8g2_prepare();
u8g2_string_orientation();
u8g2.sendBuffer();
delay(1500);
}

Zunächst gehen wir alle Schritte durch.

In der ersten Funktion "u8g2_prepare()" haben wir sämtliche vordefinierte


"u8g2"-library Funktionen benutzt.
Die "setFont()" Funktion wird benutzt, um die Schriftart von Zeichen
einzurichten. In diesem Fall ist die Funktion si "u8g2_font_5x7_tf" , aber Sie
können sich auch eine andere aussuchen, unter
https://github.com/olikraus/u8g2/wiki/fntlist8x8
Mit der "setFontRefHeightExtendedText()" Funktion werden Zeichen
ausgewählt. Eine Auswahl finden Sie unter
https://github.com/olikraus/u8g2/wiki/u8g2reference#setfontrefheightextendedtext
Unter "setDrawColor()", leuchtet nur ein Zeichen auf, wenn Sie Argument
"1" benutzen. Wenn Sie Argument "0" benutzen, werden die Pixel für jeden
Buchstaben invertiert, das heißt, dass der Hintergrund, aber nicht das
Zeichen beleuchtet wird. Das Argument "2", liefert dasselbe Ergebnis wie
Argument - 0.
"setFontPosTop()" hat verschiedene Funktionen: "setFontPosBaseline()",
"setFontPosCenter()" und "setFontPosBottom()". Diese Funktionen ändern
die Position der Zeichen in der Zeile.
"setFontDirection()" ändert den Winkel der Zeichen in der Zeile. Diese hat
vier verschiedene Argumentwerte, 0 = 0° , 1 = 90° , 2 = 180° and 3 = 270°.
Wir verwenden dies in der "u8g2_string_orientation()" Funktion.
Um Text auf dem Display anzuzeigen, verwenden wir die "drawStr()".
Funktion. Sie hat drei Argumente. Das erste ist die X-Position des Textes,
das zweite ist die Y-Position und das dritte ist die eigentliche Zeichenkette.
Bevor wir diese Funktion nutzen, sollten wir "u8g2_prepare()" verwenden,
um die Schriftart für den anzuzeigenden Text auszuwählen. Die X-Position
beginnt in der linken oberen Ecke des Displays und endet in der rechten
oberen Ecke. Die Y-Position beginnt oben links im Display und endet in der
rechten unteren Ecke. Dies ist für alle Positionsargumente der Fall.

Die Funktion "drawStr()" zeigt nur konstante Zeichenketten an, das heißt
nur Zeichenketten, die sich nicht ändern. Wenn Sie jedoch einige
Variablenwerte in der Zeichenkette anzeigen möchten, gibt es eine weitere
Funktion für die Anzeige der Zeichenkettenwerte, genannt "print()". Diese
Funktion akzeptiert nur ein Argument, nämlich den Zeichenkettenwert, der
angezeigt wird. Dieser Wert kann eine beliebige Variable, Float, Integer,
Zeichen, etc. sein. ABER diese Funktion muss im Zusammenhang mit einer
anderen Funktion verwendet werden, da sie allein nicht weiß, wo sie
angezeigt werden soll. Die zweite Funktion ist "setCursor(x, y)", die zwei
Argumente akzeptiert, die X- und Y-Position des Cursors. An diesen
Punkten wird mit dem Anzeigen des Zeichenkettenwertes begonnen.
Beispiel:

float container = 1.5;


u8g2.setCursor(10, 15);
u8g2.print(container);
Um einen Kasten, einen Rahmen, einen Kreis, eine Disc, eine Linie, oder
ein Dreieck anzuzeigen, verwenden wir korrespondierend "drawBox()",
"drawFrame()", "drawCircle()", "drawDisc()", "drawLine()" und
"drawTriangle()". Für alle diese Funktionen ist das erste Argument die X-
Position und das zweite die Y-Position eines Objekts. Andere Jedoch sind
weitere Unterschiede zu beachten. Bei Kasten und Rahmen, sind das dritte
und vierte Argument die Breite und Höhe, beim Kreis und Scheibe das dritte
Argument der Radius. Für die Linie sind die ersten beiden Argumente die X-
und Y-Position des ersten Punktes der Linie, und die zweiten beiden
Argumente sind die X- und Y-Position des letzten Punktes der Linie. Das
Dreieck hat drei Punkte, also gibt es 6 Argumente. Die ersten beiden sind
für den ersten Punkt, die zweiten für den zweiten Punkt und die dritten
beiden sind für den dritten Punkt des Dreiecks.

Es gibt eine Funktion zum Anzeigen von Boxen oder Rahmen mit einem
Radius an den Ecken. Mithilfe von "drawRFrame()" und "drawRBox()".
Beide Funktionen besitzen ein fünftes Argument für den Radius.

Es gibt eine Funktion zum Anzeigen von Unicodezeichen "drawUTF8()".


Diese Funktion hat drei Argumente, die ersten beiden für die X- und Y-
Positionen des Zeichens, das dritte für das Zeichen. Es gibt drei
Möglichkeiten, diese Zeichen anzuzeigen. Sie können kopiert und in eine
Skizze eingefügt werden (wie die Wolke oder der Regenschirm in unserem
Beispiel). Dann kann man eine Char-Array-Variable erstellen, mit zwei
Werten, der hexadezimalen Unicode-Nummer für Sonderzeichen, und dem
Escape-Zeichen, wie in unserem Beispiel für die "COPYRIGHT_SYMBOL"-
Variable. Als letztes kann man hexadezimale Zahlen in einer Zeichenkette
wie "\xb0" (das Grad-Zeichen) in unserem Beispiel verwenden.
Anzeige des Bildes auf dem Display

Auf diesem LCD-Display können nur ".xbm"-Bilder angezeigt werden. Unter


".xbm" versteht man ein Bitmap-Bild. Dieses wird benutzt, um Cursor- und
Symbolbild-Bitmaps zu speichern. Wie kann man ein ".xbm"-Bild erstellen?
Es gibt viele Tools, aber wir werden es mit der Hilfe eines GIMP-Programms
erklären. https://www.gimp.org/downloads/ .

Zuerst müssen Sie ein Bild erstellen oder auswählen. Dann müssen Sie es
in ein zweifarbiges Bild (vorzugsweise ein Schwarz-Weiß-Bild)
posterisierien. Dann müssen Sie es skalieren, um die Breite und Höhe der
Anzeige anzupassen. Dann müssen Sie es als ".xbm" exportieren. Am Ende
müssen Sie die exportierte ".xbm"-Datei in einem Texteditor öffnen (wir
verwenden Sublime Text https://www.sublimetext.com/ , aber Sie können
auch den Texteditor oder ähnliches benutzen) und diesen Text in unsere
Skizze einfügen. Lassen Sie uns die einzelnen Schritte durchgehen.

Wir benutzen ein Bild unserer Website:


https://cdn.shopify.com/s/files/1/1509/1638/files/DIY-
Dreams_poweRoter_by_AZ-Delivery_Kopie_x250@2x.png?v=1515324305
Öffnen Sie es mit "GIMP". Da es bereits ein zweifarbiges Bild ist, müssen
wir nur noch Rot in Schwarz und den transparenten Hintergrund in weiß
umwandeln.

Danach gehen Sie zu Image > Scale and skalieren das Bild indem Sie die
Breite auf “128” festlegen. Die Höhe wird automatisch skaliert. Sollte die
Höhe "64" übersteigen, ändern sie die Höhe auf "64". Die Breite wird
entsprechend auf einen geringeren Wert als "128" geändert.
Danach müssen Sie das Bild bearbeiten, damit Sie nur noch Pixel mit
schwarzer Farbe für das Bild und weiße für den Hintergrund haben. Sollten
Sie diesen Schritt unterlassen, kann es zu Fehldarstellungen kommen.

Danach exportieren Sie die “.xbm”-Datei, indem Sie File > Export As…
auswählen oder CTRL + SHIFT + E drücken. In dem sich öffnenden
Fenster, wählen sie die “.xbm”-Einstellung und den Namen des Bildes.

Danach öffnen Sie die exportiere “.xbm”-Datei mit einem Texteditor. Sie
werden ein ähnliches Ergebnis, wie unten abgebildet, bekommen.
Wir brauchen den gesamten Text. Kopieren Sie das in Ihren Arduino IDE,
und ändern Sie nur diese Zeile:
static unsigned char image_bits[] = {
zu
static const unsigned char image_bits[] U8X8_PROGMEM = {

Dann sollte die Skizze für die Anzeige des Bildes wie eine der unten
abgebildeten Skizzen aussehen.

#include <U8g2lib.h>
U8G2_ST7920_128X64_F_SW_SPI u8g2(U8G2_R0, 13, 11, 10);
#define image_width 128
#define image_height 21
static const unsigned char image_bits[] U8X8_PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x1f, 0x00, 0x00,
0xfc, 0x1f, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xfe, 0x1f, 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x00, 0x00, 0x0c, 0x60, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x18, 0x00, 0x00,
0x0c, 0xc0, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x18, 0x00, 0x00, 0x0c, 0xc0, 0xf0, 0x1f, 0x06, 0x63, 0x80, 0xf1,
0x1f, 0xfc, 0x33, 0xc0, 0x03, 0x18, 0x00, 0x00, 0x0c, 0xc0, 0xf8, 0x3f,
0x06, 0x63, 0xc0, 0xf9, 0x3f, 0xfe, 0x33, 0xc0, 0x03, 0x18, 0x00, 0x00,
0x0c, 0xc0, 0x18, 0x30, 0x06, 0x63, 0xc0, 0x18, 0x30, 0x06, 0x30, 0xc0,
0xff, 0xff, 0xdf, 0xff, 0x0c, 0xc0, 0x18, 0x30, 0x06, 0x63, 0xe0, 0x18,
0x30, 0x06, 0x30, 0xc0, 0xff, 0xff, 0xdf, 0xff, 0x0c, 0xc0, 0x98, 0x3f,
0x06, 0x63, 0x60, 0x98, 0x3f, 0x06, 0x30, 0xc0, 0x03, 0x18, 0x0c, 0x00,
0x0c, 0xc0, 0x98, 0x1f, 0x06, 0x63, 0x70, 0x98, 0x1f, 0x06, 0x30, 0xc0,
0x03, 0x18, 0x06, 0x00, 0x0c, 0xc0, 0x18, 0x00, 0x06, 0x63, 0x38, 0x18,
0x00, 0x06, 0x30, 0xc0, 0x03, 0x18, 0x03, 0x00, 0x0c, 0xe0, 0x18, 0x00,
0x06, 0x63, 0x1c, 0x18, 0x00, 0x06, 0x30, 0xc0, 0x00, 0x80, 0x01, 0x00,
0xfc, 0x7f, 0xf8, 0x07, 0x1e, 0xe3, 0x0f, 0xf8, 0x07, 0x06, 0xf0, 0xcf,
0x00, 0xc0, 0x00, 0x00, 0xfc, 0x3f, 0xf0, 0x07, 0x1c, 0xe3, 0x07, 0xf0,
0x07, 0x06, 0xe0, 0xcf, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x30, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xe0, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0xfc, 0x1f, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f };

void u8g2_prepare() {
u8g2.setFont(u8g2_font_open_iconic_all_4x_t);
u8g2.setFontRefHeightExtendedText();
u8g2.setDrawColor(1);
u8g2.setFontPosTop();
u8g2.setFontDirection(0);
}
void u8g2_bitmap() {
u8g2.drawXBMP(0, 22, image_width, image_height, image_bits);
}
void setup() {
u8g2.begin();
u8g2_prepare();
u8g2.clearBuffer();
u8g2_bitmap();
u8g2.sendBuffer();
}
void loop() { }

Um ein Bild anzuzeigen haben wir die Funktion “drawXPMP()” benutzt.


Diese Funktion erlaubt 5 Argumente, die ersten beiden sind die X- und Y-
Positionen des Bildes auf dem Display, die dritte ist die Breite und die vierte
die Höhe des Bildes (diese Werte ergeben sich aus den Variablen, die Sie
bekommen, wenn Sie das “.xbm”-Bild im Texteditor öffnen). Das fünfte
Argument sind die Bilder-Bits oder der Bildbereich, den wir aus dem
Texteditor kopiert haben.
Verbindung des Displays mit dem Raspberry Pi

Verbinden Sie das Display mit dem Raspberry Pi, wie unten abgebildet.

LCD Pin > Pin


GND > GND [jeglicher GND Pin des RaspPi] Schwarzer Draht
VCC > 5V [Pin 2] Roter Draht
RS > GPIO8 [Pin24] Grüner Draht
R/W > GPIO10 [Pin 19] Purple Draht
E > GPIO11 [Pin 23] Brauner Draht
PSB > GND [jeglicher GND Pin des RaspPi] Schwarzer Draht
BLA > 5V [Pin 4] Roter Draht
BLK > GND [jeglicher GND Pin des RaspPi] Schwarzer Draht
Das Blaue Potentiometer im Verbindungsplan wird verwendet, um den
Kontrast des LCD-Displays einzustellen. Es wird auf die gleiche Weise wie
auf dem Verbindungsplan des Mikrocontroller-Karte verbunden. Der blaue
Draht auf dem Plan wird zwischen dem mittleren Pin des Potentiometers
und dem V0-Pin des Displays angeschlossen. Durch Drehen der Welle des
Potentiometers ändern wir die Analogspannung und damit den Kontrast der
Anzeige.

Library für Python Skript

Bei einem Raspberry Pi gibt es keine libraries in Python, die mit unserem
128x64-LCD funktionieren. Aber es gibt einen Weg die "u8g2"-library
(welche wir für den Atmega328P Board benutzt haben) mit einem
Raspberry Pi zu nutzen (ohne Python).

Wir müssen "u8g2"-library-“C++”-Code auf Rasbian (Betriebssystem des


Raspberry Pi) kompilieren. Dafür muss Code in der “C++”-
Programmiersprache geschrieben werden. Allerdings müssen dafür zuerst
einige Compiler installiert werden, sowie deren Hilfs-tools.

Starten Sie Ihren Raspberry Pi, und öffnen Sie die Terminal App. Geben Sie
diese Befehle ein:
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install libcurl4-openssl-dev
git clone https://github.com/Kitware/CMake.git
cd CMake

Starten Sie diesen Befehl:


./bootstrap --system-curl
Es kann 10-15 Minuten dauern, bis dieser Befehl ausgeführt worden ist.

Dann haben wir noch zwei weitere Befehle, die ausgeführt werden müssen:
sudo make
Es kann 10-15 Minuten dauern, bis dieser Befehl ausgeführt worden ist.

Der zweite Befehl:


sudo make install
Hier müssen Sie wieder ein paar Minuten warten, bis dieser Befehl
ausgeführt wurde.

Danach gehen Sie zum Home-Ordner. Falls Sie die Terminal App noch nicht
geschlossen haben, führen Sie “cd ..” aus. Das bringt Sie direkt zu ihrem
Home-Ordner.

Dann laden Sie die "u8g2"-library rutner und installieren diese auf Rasbian.
Führen Sie diese Befehle nacheinander aus:
git clone https://github.com/ribasco/u8g2-rpi-demo.git
cd u8g2-rpi-demo

Nach dem Download müssen Sie das Shell-Skript “compile.sh” auführen.


Das müssen Sie jedes Mal tun, wenn Sie die “main.cpp”-Datei ändern. Das
ist jedes Mal der Fall, wenn wir ein neues Programm für das 128x64 Display
erstellen wollen. In der “main.cpp”-Datei schreiben wir den Code.

Wenn Sie das “compile.sh” Shell-Skript ausführen, ohne die “main.cpp“-


Datei geändert zu haben, werden Sie ein Programmbeispiel sehen können,
das von dem "u8g2"-library Erschaffer erstellt worden ist.

Um das “compile.sh”-Skript auszuführen, sollten Sie nicht in dem “u8g2-rpi-


demo”-Verzeichnis sein, müssen Sie die Terminal App in diesem
Verzeichnis öffnen und diesen Befehl ausführen:
./compile.sh

Danach sollte es Ihnen möglich sein ein Programmbeispiel zu sehen, dass


Sie in der “main.cpp”-Datei geschrieben haben. Um das Skript zu beenden
drücken Sie CTRL + C.

Wenn Sie nichts installiert haben, erfahren Sie durch den Befehl
"compile.sh" was Sie vorher installieren müssen. Installieren Sie alles
notwendige und führen “compile.sh” erneut aus.

Die Kompilation kann einige Minuten in Anspruch nehmen.


Das ist die Skript-Anzeige für das Beispiel. Das ist der zweite Durchgang
des Skripts ohne die “main.cpp”-Datei verändert zu haben. Die erste
Anzeige ist sehr lang.

Alle Funktionen, die Sie im Arduino IDE mit der “u8g2”-library benutzt haben
sind nahezu identisch. Anschließend zeigen wir Ihnen, wie Sie diese im
Raspberry Pi nutzen können.
Dieser Code nutzt “wiringPi” GPIO Verbindungsnamen. So werden die drei
Pins benannt:

HW Pin > GPIO Pin > WiringPi Pin > SPI Pin > LCD Pin
Pin 24 > GPIO8 > 10 > CE > RS
Pin 19 > GPIO10 > 12 > MOSI > R/W
Pin 23 > GPIO11 > 14 > SCLK >E

Alle Funktionen, die wir im Mikrocontroller-Karte benutzt haben wurden


überarbeitet, so dass wir sie hier nutzen können. Diesen Code speicher Sie
in der "main.cpp"-Datei ab:

#include <iostream>
#include <wiringPi.h>
#include <cstring>
#include <csignal>
#include <unistd.h>
#include "u8g2_hal_rpi.h"

using namespace std;


u8g2_t u8g2;
static volatile bool complete = false;
static int forced_exit_attempts = 0;

void exitHandler(int s) {
if (forced_exit_attempts >= 2) {
cout << "Forcing shutdown" << endl;
u8g2_ClearDisplay(&u8g2);
exit(1);
}
complete = true;
forced_exit_attempts++;
}

void drawU8G2Logo(u8g2_t *u8g2) {


u8g2_ClearBuffer(u8g2);
u8g2_SetFontMode(u8g2, 1);
u8g2_SetFontDirection(u8g2, 0);
u8g2_SetFont(u8g2, u8g2_font_inb16_mf);
u8g2_DrawStr(u8g2, 0, 22, "U");
u8g2_SetFontDirection(u8g2, 1);
u8g2_SetFont(u8g2, u8g2_font_inb19_mn);
u8g2_DrawStr(u8g2, 14, 8, "8");
u8g2_SetFontDirection(u8g2, 0);
u8g2_SetFont(u8g2, u8g2_font_inb16_mf);
u8g2_DrawStr(u8g2, 36, 22, "g");
u8g2_DrawStr(u8g2, 48, 22, "\xb2");
u8g2_DrawHLine(u8g2, 2, 25, 34);
u8g2_DrawHLine(u8g2, 3, 26, 34);
u8g2_DrawVLine(u8g2, 32, 22, 12);
u8g2_DrawVLine(u8g2, 33, 23, 12);
u8g2_SendBuffer(u8g2);
}
void drawBannerText(u8g2_t *u8g2, uint32_t durationSecs) {
uint8_t x = 255;
uint32_t prevMillis = 0;
u8g2_SetFont(u8g2, u8g2_font_7x13B_mf); // Set Font
uint32_t elapsed = 0;
while (elapsed != durationSecs) {
if (complete) { break; }
uint32_t curMillis = millis();
//Count the number of elapsed seconds
if ((curMillis - prevMillis) >= 1000) {
prevMillis = curMillis;
elapsed++; }
if (x <= 0) { x = 255; }
u8g2_ClearBuffer(u8g2);
string text = "UG82 running on Raspberry Pi!";
u8g2_DrawStr(u8g2, x, 32, text.c_str());
u8g2_SendBuffer(u8g2);
x-=5;
delay(500); } // end while
}

// we define our Funktions here, all way down to main() function


void prepare(u8g2_t *u8g2) {
u8g2_ClearBuffer(u8g2);
u8g2_SetFontMode(u8g2, 1);
u8g2_SetFont(u8g2, u8g2_font_6x10_tf);
u8g2_SetFontDirection(u8g2, 0);
u8g2_SetFontPosTop(u8g2);
u8g2_SendBuffer(u8g2);
}
void box_frame(u8g2_t *u8g2) {
string text1 = "Draw Box"; string text2 = "Draw Frame";
u8g2_ClearBuffer(u8g2);
u8g2_DrawStr(u8g2, 0, 0, text1.c_str());
u8g2_DrawBox(u8g2, 5, 10, 20, 10);
u8g2_DrawStr(u8g2, 60, 0, text2.c_str());
u8g2_DrawFrame(u8g2, 65, 10, 20, 10);
u8g2_SendBuffer(u8g2);
}
void r_frame_box(u8g2_t *u8g2) {
string text1 = "Draw Rbox"; string text2 = "Draw RFrame";
u8g2_ClearBuffer(u8g2);
u8g2_DrawStr(u8g2, 0, 0, text2.c_str());
u8g2_DrawRFrame(u8g2, 5, 10, 40, 15, 3);
u8g2_DrawStr(u8g2, 70, 0, text1.c_str());
u8g2_DrawRBox(u8g2, 70, 10, 25, 15, 3);
u8g2_SendBuffer(u8g2);
}
void disc_circle(u8g2_t *u8g2) {
string text1 = "Draw Disc"; string text2 = "Draw Circle";
u8g2_ClearBuffer(u8g2);
u8g2_DrawStr(u8g2, 0, 0, text1.c_str());
u8g2_DrawDisc(u8g2, 10, 20, 9, 15);
u8g2_DrawDisc(u8g2, 30, 17, 7, 15);
u8g2_DrawStr(u8g2, 60, 0, text2.c_str());
u8g2_DrawCircle(u8g2, 70, 20, 9, 15);
u8g2_DrawCircle(u8g2, 90, 17, 7, 15);
u8g2_SendBuffer(u8g2);
}

void string_orientation(u8g2_t *u8g2) {


string text = "String Orientation";
string textZero = "0";
string textNineZero = "90";
string textOneEightZero = "180";
string textTwoSevenZero = "270";
u8g2_ClearBuffer(u8g2);
u8g2_DrawStr(u8g2, 0, 0, text.c_str());
u8g2_SetFontDirection(u8g2, 0);
u8g2_DrawStr(u8g2, 5, 30, textZero.c_str());
u8g2_SetFontDirection(u8g2, 3);
u8g2_DrawStr(u8g2, 40, 35, textNineZero.c_str());
u8g2_SetFontDirection(u8g2, 2);
u8g2_DrawStr(u8g2, 75, 30, textOneEightZero.c_str());
u8g2_SetFontDirection(u8g2, 1);
u8g2_DrawStr(u8g2, 100, 25, textTwoSevenZero.c_str());
u8g2_SendBuffer(u8g2);
}
void lines(u8g2_t *u8g2) {
string text = "Draw Lines";
u8g2_ClearBuffer(u8g2);
u8g2_DrawStr(u8g2, 0, 0, text.c_str());
u8g2_DrawLine(u8g2, 7, 22, 40, 55);
u8g2_DrawLine(u8g2, 14, 22, 60, 55);
u8g2_DrawLine(u8g2, 28, 22, 80, 55);
u8g2_DrawLine(u8g2, 35, 22, 100, 55);
u8g2_SendBuffer(u8g2);
}
void triangle(u8g2_t *u8g2) {
string text = "Draw Triangle";
u8g2_ClearBuffer(u8g2);
u8g2_DrawStr(u8g2, 0, 0, text.c_str());
u8g2_DrawTriangle(u8g2, 10, 20, 99, 60, 17, 55);
u8g2_SendBuffer(u8g2);
}

const char COPYRIGHT_SYMBOL[] = {0xa9, '\0'};


void unicodes(u8g2_t *u8g2) {
string text = "Unicode Chars";
u8g2_ClearBuffer(u8g2);
u8g2_DrawStr(u8g2, 0, 0, text.c_str());

u8g2_SetFont(u8g2, u8g2_font_unifont_t_symbols);
u8g2_SetFontPosTop(u8g2);
u8g2_SetFontDirection(u8g2, 0);

u8g2_DrawUTF8(u8g2, 10, 25, "☀");


u8g2_DrawUTF8(u8g2, 30, 25, "☁");
u8g2_DrawUTF8(u8g2, 50, 25, "☂");
u8g2_DrawUTF8(u8g2, 70, 25, "☔");
u8g2_DrawUTF8(u8g2, 95, 25, COPYRIGHT_SYMBOL); // COPYRIGHT SIMBOL
u8g2_DrawUTF8(u8g2, 115, 25, "\xb0"); // DEGREE SYMBOL
u8g2_SendBuffer(u8g2);
}
// this two variables are from image text we copied from text editor
int image_width = 128;
int image_height = 21;
static const unsigned char image_bits[] U8X8_PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x1f, 0x00, 0x00,
0xfc, 0x1f, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xfe, 0x1f, 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x00, 0x00, 0x0c, 0x60, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x18, 0x00, 0x00,
0x0c, 0xc0, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x18, 0x00, 0x00, 0x0c, 0xc0, 0xf0, 0x1f, 0x06, 0x63, 0x80, 0xf1,
0x1f, 0xfc, 0x33, 0xc0, 0x03, 0x18, 0x00, 0x00, 0x0c, 0xc0, 0xf8, 0x3f,
0x06, 0x63, 0xc0, 0xf9, 0x3f, 0xfe, 0x33, 0xc0, 0x03, 0x18, 0x00, 0x00,
0x0c, 0xc0, 0x18, 0x30, 0x06, 0x63, 0xc0, 0x18, 0x30, 0x06, 0x30, 0xc0,
0xff, 0xff, 0xdf, 0xff, 0x0c, 0xc0, 0x18, 0x30, 0x06, 0x63, 0xe0, 0x18,
0x30, 0x06, 0x30, 0xc0, 0xff, 0xff, 0xdf, 0xff, 0x0c, 0xc0, 0x98, 0x3f,
0x06, 0x63, 0x60, 0x98, 0x3f, 0x06, 0x30, 0xc0, 0x03, 0x18, 0x0c, 0x00,
0x0c, 0xc0, 0x98, 0x1f, 0x06, 0x63, 0x70, 0x98, 0x1f, 0x06, 0x30, 0xc0,
0x03, 0x18, 0x06, 0x00, 0x0c, 0xc0, 0x18, 0x00, 0x06, 0x63, 0x38, 0x18,
0x00, 0x06, 0x30, 0xc0, 0x03, 0x18, 0x03, 0x00, 0x0c, 0xe0, 0x18, 0x00,
0x06, 0x63, 0x1c, 0x18, 0x00, 0x06, 0x30, 0xc0, 0x00, 0x80, 0x01, 0x00,
0xfc, 0x7f, 0xf8, 0x07, 0x1e, 0xe3, 0x0f, 0xf8, 0x07, 0x06, 0xf0, 0xcf,
0x00, 0xc0, 0x00, 0x00, 0xfc, 0x3f, 0xf0, 0x07, 0x1c, 0xe3, 0x07, 0xf0,
0x07, 0x06, 0xe0, 0xcf, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x30, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xe0, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0xfc, 0x1f, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f };
void bitmaps(u8g2_t *u8g2) {
u8g2_ClearBuffer(u8g2);
u8g2_DrawXBMP(u8g2, 0, 22, image_width, image_height, image_bits);
u8g2_SendBuffer(u8g2);
}
void printText(u8g2_t *u8g2, string yourText) {
string text = yourText;

u8g2_ClearBuffer(u8g2);
u8g2_DrawStr(u8g2, 0, 0, text.c_str());
u8g2_SendBuffer(u8g2);
}
std::string& rtrim(std::string& str, const std::string& chars = "\t\n\v\f\r0. ") {
str.erase(str.find_last_not_of(chars) + 1);
return str;
}
int main() {
struct sigaction sigIntHandler{};
sigIntHandler.sa_handler = exitHandler;
sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;
sigaction(SIGINT, &sigIntHandler, nullptr);
// this variable is just bis show you have bis print variable strings
float b = 0.0;
wiringPiSetup(); // Initialize Wiring Pi
// Configure the SPI Pins
// clock (EN) = 14, mosi (R/W) = 12, cs (RS) = 10
u8g2_rpi_hal_t u8g2_rpi_hal = {14, 12, 10};
u8g2_rpi_hal_init(u8g2_rpi_hal);
u8g2_Setup_st7920_s_128x64_f(&u8g2, U8G2_R2, cb_byte_spi_hw, cb_gpio_delay_rpi);
// Initialize Display
u8g2_InitDisplay(&u8g2);
u8g2_SetPowerSave(&u8g2, 0);
u8g2_ClearDisplay(&u8g2);
cout << "Running display demo...Press Ctrl+C bis exit" << endl;
// one tab
while (!complete) { //Run display loop
/* this part is from demo
//Draw U8G2 Logo
drawU8G2Logo(&u8g2);
delay(5000);

//Run Banner Animation


drawBannerText(&u8g2, 20);*/

// this is part with Funktions we made


prepare(&u8g2); delay(100);
box_frame(&u8g2); delay(1500);
r_frame_box(&u8g2); delay(1500);
disc_circle(&u8g2); delay(1500);
string_orientation(&u8g2); delay(1500);

// we have bis do this prepare() Funktion


// because previous Funktion changes these setups
prepare(&u8g2); delay(100);
lines(&u8g2); delay(1500);
triangle(&u8g2); delay(1500);
unicodes(&u8g2); delay(1500);
bitmaps(&u8g2); delay(1500);

string text = bis_string(b);


printText(&u8g2, rtrim(text)); delay(1500);
b = b + 1.5;
}
cout << "Exiting demo" << endl;
u8g2_ClearDisplay(&u8g2);
}
Um diesen Code auszuführen müssen wir das “compile.sh”-Skript
ausführen oder genauer, um zu kompilieren, erstellen und die "main.cpp"-
Datei auszuführen. Das "compile.sh" Skript tut dies. Dafür müssen Sie als
Erstes das “u8g2-rpi-demo” Verzeichnis öffnen, indem Sie die Terminal App
in diesem Verzeichnis öffnen und dann diesen Befehl ausführen:
./compile.sh

Wenn Sie dieses Skript ausführen, sollte es wie folgt aussehen (nach
Bearbeitung der "main.cpp"-Datei):

Um das Skript zu beenden, drücken Sie CTRL + C.


Alle Funktionen, die wir in Arduino IDE benutzt haben sind mit kleinen
Änderungen, fast identisch. Jede Funktion aus der library oder eigens
Erstellte muss neben den bereits erlaubten Argumenten ein weiteres
Argument erlauben. Nämlich das “u8g2”-Objekt, ein Typ des “u8g2_t”.
Dieses Argument muss an erster Stelle stehen. Beispielsweise:
u8g2_DrawStr(u8g2, 0, 22, "U");

Sollte eine Funktion kein Argument erlauben, muss sie nun das “u8g2"-
Objekt erlauben. Beispielsweise:
u8g2_ClearBuffer(u8g2);
u8g2_SendBuffer(u8g2);

Wir haben diese Funktion benutzt, um konstante Zeichenketten anzuzeigen,


aber jetzt können nur einzelne Zeichen angezeigt werden:
u8g2_DrawStr(u8g2, 0, 22, "U");

Wenn Sie nur konstante oder variable Zeichenketten mit dieser Funktion
anzeigen möchten, gehen Sie wie folgt vor:
string text = "Draw Box";
u8g2_ClearBuffer(u8g2);
u8g2_DrawStr(u8g2, 0, 0, text.c_str());
u8g2_SendBuffer(u8g2);
Nun kann die Variable "text" konstant oder variabel sein. Wenn wir einen
Float-Wert auf diese Weise anzeigen möchten, müssen wir Float in eine
Zeichenkette konvertieren und überschüssige Nullen entfernen. Um dies zu
tun führen wir Folgendes aus:
std::string& rtrim(std::string& str, const std::string& chars="\t\n\v\f\r0. ")
{
str.erase(str.find_last_not_of(chars) + 1);
return str;
}

Um Float in eine Zeichenkette umzuwandeln:


string text = bis_string(b);

So werden beide Funktionen zusammen ausgeführt:


printText(&u8g2, rtrim(text));

Mehr Argumente als in der Arduino IDE-Version, haben nur:


u8g2_DrawDisc(u8g2, 10, 20, 9, 15);
and
u8g2_DrawDisc(u8g2, 10, 20, 9, 15);

Die Zahl "15" bedeutet, dass die Funktion den ganz Kreis anzeigen wird.
Dabei können Sie eine Zahl von 0 bis 15 benutzen:
0 - keine Anzeige
1 - zeigt das erste Viertel des Kreises an
2 - zeigt das vierte Quartal des Kreises
3 - zeigt die obere Hälfte des Kreises
4 - zeigt das dritte Quartal des Kreises
5 - zeigt das erste und dritte Viertel des Kreises
6 - zeigt die linke Hälfte des Kreises
7 - zeigt das erste, dritte und vierte Quartal des Kreises
8 - zeigt das zweite Viertel des Kreises
9 - zeigt die rechte Hälfte des Kreises
10 - zeigt das zweite und vierte Viertel des Kreises
11 - zeigt das erste, zweite und vierte Viertel des Kreises.
12 - zeigt die untere Hälfte des Kreises
13 - zeigt das erste, zweite und dritte Viertel des Kreises.
14 - zeigt das zweite, dritte und vierte Viertel des Kreises.
15 - zeigt den vollen Kreis

Alle anderen Funktionen sind mit denen des Arduino IDE identisch (Nur das
erste Argument muss das "u8g2"-Objekt sein).

Sie haben es geschafft. Sie können jetzt unser Modul


nun für Ihre Projekte nutzen.
Jetzt sind Sie dran! Entwickeln Sie Ihre eigenen Projekte und Smart-Home
Installationen. Wie Sie das bewerkstelligen können, zeigen wir Ihnen
unkompliziert und verständlich auf unserem Blog. Dort bieten wir Ihnen
Beispielskripte und Tutorials mit interessanten kleinen Projekten an, um
schnell in die Welt der Mikroelektronik einzusteigen. Zusätzlich bietet Ihnen
auch das Internet unzählige Möglichkeiten, um sich in Sachen
Mikroelektronik weiterzubilden.

Falls Sie nach noch weiteren hochwertige Mikroelektronik und


Zubehör, sind Sie bei AZ-Delivery Vertriebs GmbH goldrichtig. Wir
bieten Ihnen zahlreiche Anwendungsbeispiele, ausführliche
Installationsanleitungen, E-Books, Bibliotheken und natürlich die
Unterstützung unserer technischen Experten.

https://az-delivery.de
Viel Spaß!
Impressum
https://az-delivery.de/pages/about-us

Das könnte Ihnen auch gefallen