D1-mit-TFT-1.jpgFür Kasse und Bar in den Räumen eines Vereins, in dem ich Mitglied bin, wird eine selbst geschriebene Software verwendet. An der Bar gab es früher ein zweizeiliges LCD-Matrixdisplay aus einer alten Nixdorf-Kasse, auf dem bei Getränkebuchung der Preis für den Gast angezeigt wurde. Wenn gerade kein Gast bedient wurde, zeigte dieses Display in Laufschrift Informationen zu den kommenden Vereinsveranstaltungen an.

Dieses Display habe ich jetzt im Rahmen von ohnehin anstehenden Arbeiten durch ein 3,5-Zoll TFT ersetzt, um die Veranstaltungshinweise zukünftig optisch ansprechender präsentieren zu können. Die Idee ist, auf dem neuen TFT wie bisher die Barrechnung des Gastes anzuzeigen und die Veranstaltungen mit Text und Bild zu bewerben.

Wie alle Erweiterungen, die ich an der mehr als 10 Jahre alten bestehenden Hard- und Softwarelandschaft des Vereins durchführe, sollte auch das neue Display möglichst "lose" an die Bestandsarchitektur gekoppelt werden, um möglichst wenige Änderungen am alten Programmcode des Systems durchführen zu müssen. Ich setze hierbei deshalb auf eine Art "Microservice"-artigen Ansatz, ähnlich wie man es bei der komponentenbasierten Softwareentwicklung tut: Die neue Komponente - diesmal das neue Display - wird isoliert entwickelt und aufgebaut und über Webservices an das bestehende System gekoppelt. Dafür eignen sich ESP8266- und ESP32-basierte Microcontroller ideal dank des eingebauten WLANs und des günstigen Preises.

Ein universelles, per Webservice ansteuerbares Grafikdisplay

Hardware:

  • Wemos D1 Mini-Klon mit ESP8266
  • 3,5'' TFT-Display mit SPI-Schnittstelle und ILI9488-Chipsatz (siehe hier), oder kompatibel

Software:

  • Arduino- oder PlatformIO-IDE mit installierter ESP8266-Unterstützung
  • TFT_eSPI-Bibliothek von Bodmer (Github)
  • TJpeg-Decoder-Bibliothek von Bodmer (Github)
  • "ESP-Bardisplay"-Sketch mit dem Webservice (Github)

Tatsächlich habe ich nur ein Exemplar des großen 3,5'' Displays und das ist in die "echte" Bar eingebaut. Zum Entwickeln und Testen zu Hause verwende ich dieses pin-kompatible 2,4'' Display, welches hier auch auf den Fotos zu sehen ist.

Im weiteren Text werde ich die Umsetzung mit der Arduino IDE beschreiben, auf PlatformIO gehe ich in einem gesonderten Blogbeitrag ein.

Die beiden benötigten Bibliotheken können einfach über die Arduino-Bibliothekenverwaltung (Menü "Werkzeuge/Bibliotheken verwalten...") installiert werden (suche nach "TFT_eSPI" und "TJpeg"). Für absolute Einsteiger, die noch nicht mit der Arduino-IDE gearbeitet haben, gibt es hier eine Anleitung zur Einrichtung der Umgebung für den ESP8266-Microcontroller. 

Aufbau

Displaymodul und D1 Mini Controller werden wie folgt verdrahtet:

bardisplay-schematics-1.png

TFT Pin ESP8266 Pin
VCC 5V
GND GND
CS D2
RESET RST
DC/RS D4
MOSI D7
SCK D5
LED D1
Programmkonfiguration

Wenn die Arduino-IDE mit der Boardbibliothek für den Microcontroller und den beiden benötigten Bibliotheken TFT_eSPI und TJpeg-Decoder startklar ist, kann das "Bardisplay"-Sketch aus dem Github-Repository heruntergeladen oder gecloned werden.

Im Programmcode von ESP-Bardisplay.ino in den Zeilen 25 und 26 müssen SSID (Name) und Kennwort des WLAN-Zugangspunktes eingetragen werden.

Außerdem muss in der TFT-Bibliothek noch konfiguriert werden, welches Display benutzt wird und an welchen Pins des Microcontrollers es angeschlossen ist. Dazu muss die Datei User_Setup.h in der Bibliothek angepasst werden. Diese Datei befindet sich im Unterverzeichnis der TFT-Bibliothek im Arduino-Ordner (also z.B. unter ..\Arduino\Libraries\TFT_eSPI). Achtung: Wenn später mal die TFT-Bibliothek über die Bibliothekenverwaltung mit einem Update aktualisiert wird, dann werden eigene Änderungen in der Datei überschrieben. In der Anleitung zu TFT_eSPI ist beschrieben, wie man dieses Problem umschiffen kann. Eine andere Möglichkeit ist, anstelle der Arduino-IDE mit PlatformIO zu arbeiten. Letzteres zeige ich in einem separaten Blogbeitrag.

Hier die Änderungen für User_Setup.h:

Im Abschnitt für die Definition des Displaychips, ca. ab Zeile 38, alle Zeilen auskommentiert lassen außer für das verwendete Display, hier eines mit ILI9488-Chip:

// Only define one driver, the other ones must be commented out
//#define ILI9341_DRIVER
//#define ST7735_DRIVER  
//#define ILI9163_DRIVER  
//#define S6D02A1_DRIVER
//#define RPI_ILI9486_DRIVER 
//#define HX8357D_DRIVER
//#define ILI9481_DRIVER
//#define ILI9486_DRIVER
#define ILI9488_DRIVER     
//#define ST7789_DRIVER
//#define R61581_DRIVER
//#define RM68140_DRIVER
//#define ST7796_DRIVER
//#define SSD1963_480_DRIVER
//#define SSD1963_800_DRIVER
//#define SSD1963_800ALT_DRIVER
//#define ILI9225_DRIVER

Im Abschnitt für die Definition der Anschlusspins, ca. ab Zeile 156, die Pin-Nummern an den konkreten Aufbau anpassen:

// For NodeMCU - use pin numbers in the form PIN_Dx where Dx is the NodeMCU pin designation
#define TFT_CS   PIN_D2  
#define TFT_DC   PIN_D4  
#define TFT_RST  -1   
#define TFT_BL   PIN_D1   // LED back-light control pin 

Direkt untendrunter noch die folgenden Zeilen hinzufügen:

#define TFT_BACKLIGHT_ON HIGH          // Level to turn ON back-light (HIGH or LOW)
#define TFT_BACKLIGHT_OFF LOW          // Level to turn OFF back-light (HIGH or LOW)

Nun kann das Programm compiliert und auf den Controller hochgeladen werden.

D1-mit-TFT-2.jpgDie Endpunkte des Webservice

Beim Start zeigt das Display die IP-Adresse an, die dem Controller vom WLAN-Router zugeteilt wurde. Der von dem Programm bereitgestellte Webservice ist dann unter dieser Adresse erreichbar. Da alle Service-Endpunkte HTTP GET-Methoden sind, können Sie einfach über den Internetbrowser angesprochen werden, indem die Adresse (URI) des Endpunktes in die Adresszeile des Browsers eingegeben wird. Beispiele gibt es unten. Folgende Funktionen stehen zur Verfügung:

Einen Text auf dem Display anzeigen

URI: /showText
Parameter:
text: Auszugebender Textstring, ist URL-encodiert zu übergeben,
size: Textgröße, numerisch (1 = Originalgröße des Fonts, 2 = doppelte Größe usw.), optional,
x: X-Koordinate, ab der der Text ausgegeben werden soll, optional,
y: Y-Koordinate, ab der der Text ausgegeben werden soll, optional,
color: Nummer der Farbe, in welcher der Text ausgegeben werden soll, siehe unten, optional,
centered: "true", wenn der Text zentriert ausgegeben werden soll, optional,
clear: "true", wenn das Display vor der Ausgabe gelöscht werden soll, optional.

Bei zentriert auszugebendem Text bezeichnet die X-Koordinate die gewünschte Mitte des Strings, bei nicht-zentrierter Ausgabe die linke Kante. Der Text wird automatisch am Zeilenende umgebrochen, mit "\r\n" im Text kann manuell mehrzeilig umgebrochen werden.

Farbcode-Beispiele:

TFT_BLACK 0 TFT_WHITE 65535
TFT_MAROON 30720 TFT_PURPLE 30735
TFT_BLUE 31 TFT_GREEN 2016
TFT_CYAN 2047 TFT_RED 63488
TFT_MAGENTA 63519 TFT_YELLOW 65504
TFT_ORANGE 64928 TFT_NAVY 15

Weitere Farbcodes finden sich in der Datei TFT_eSPI.h im Verzeichnis der TFT-Bibliothek etwa ab Zeile 228.

Es gibt einige Einschränkungen, dazu mehr weiter unten.

Beispiele: (die IP-Adresse bitte durch die jeweilige konkrete IP ersetzen)

  • http://192.168.1.2/showText?text=Bardisplay
  • http://192.168.1.2/showText?text=Ein%20Teststring&size=2&x=120&y=10&color=15&centered=true&clear=true

Eine JPEG-Grafik auf dem Display anzeigen

URI: /showImage
Parameter:
url: Adresse des zu ladenden Bildes (lokal oder im Internet), nur http wird unterstützt,
x: X-Koordinate der linken oberen Bildecke auf dem Display (optional),
y: Y-Koordinate der linken oberen Bildecke auf dem Display (optional).

https-Adressen für die Bild-URL werden von der vorliegenden Programmversion nicht unterstützt, da das Handhaben der dafür notwendigen SSL-Zertifikate auf dem ESP8266 nicht ganz unproblematisch ist.

Die maximale Dateigröße für die Bilder liegt - bedingt durch die RAM-Ausstattung des ESP8266 - bei 35kB, was aber in der Praxis für Bilder in Displaygröße (480x320) durch feinfühliges Justieren der JPEG-Kompression im Bildbearbeitungsprogramm machbar ist.

Beispiel: (die IP-Adresse bitte durch die jeweilige konkrete IP ersetzen)

  • http://192.168.1.2/showImage?url=http://demo.net-things.de/ttig.jpg

D1-mit-TFT-3.jpgSketchversion ausgeben
URI: /version

Displayanzeige "löschen" (alle Pixel auf schwarz setzen)
URI: /clearScreen

Display ausschalten
URI: /off

Display einschalten
URI: /on

Einschränkungen / Mögliche Erweiterungen

Das vorliegende Programm hat einige Einschränkungen, die aber bei Bedarf durch Erweiterungen behoben werden können.

  • es sind nur Grafiken im Format JPEG mit Standardkompression darstellbar. Durch Einsatz eines anderen Decoders als TJpeg könnte man auch andere Formate nutzen.
  • die maximale Dateigröße für eine Bilddatei beträgt 35kB, weil die Daten im RAM des Microcontrollers abgelegt werden. Durch Verwendung eines Moduls mit zusätzlichem Speicher, z.B. eines ESP32 mit PSRAM, könnten auch größere Dateien verarbeitet werden.
  • das Programm verwendet zur Darstellung der Texte den eingebauten Standard-Font, der weder vernüftig skalierbar ist, noch deutsche Umlaute enthält. In meinem Originalprogramm an der "echten" Bar verwende ich stattdessen die von der Bibliothek ebenfalls unterstützten "FreeFont"-Zeichensätze in drei verschiedenen Größen. Das habe ich hier aus Gründen der Übersichtlichkeit des Codes weggelassen.
  • die Textfarbe muss mit dem in der TFT-Bibliothek definierten Zahlenwert angegeben werden. Mit einer kleinen Funktion zum "Übersetzen" der Werte könnte das nutzungsfreundlicher gestaltet werden.