Vollgrafikanzeige mit Grafikbibliothek und Touchscreen

Ich habe hier plötzlich einen Arduino Uno mit ATmega328p sowie ein TFT-Display mit der Bezeichnung 2.8 ITDB02 Shield (Itead Studio) herumliegen. Ungefähr das hier. Was macht man damit? Also Webseite besuchen, fürchterliche Datenblätter herunterladen und Beispielprogramm austesten.

Immerhin ist da noch ein Touchscreen und ein SD-Kartenleseschacht dran. Der arme kleine Mikrocontroller! (Verwalte mal 32 Gigabyte mit 32 Kilobyte!) Dafür gibt es jedoch vom Hersteller keinen Verweis auf Demo-Programme. Es gibt auch keine. Bananen-Hardware? (Soll beim Anwender reifen.) Das Display ist leider write-only angeschlossen, damit ist Alpha-Transparenz nicht realisierbar.

Arduino-Kritik

Warum Arduino über drei Viertel der Weltbevölkerung vom Programmieren ausschließt?

Gerade junge Leute, die Zielgruppe, werden vom English-Only eher abgeschreckt. Da will man also ein kompliziertes Ding in einer Fremdsprache mit blumigen Worten erklären. Und behauptet, dass alles ganz einfach ist. Das Bereitstellen von Unmengen von Beispielen und magischen Bibliotheken zweifelhafter Qualität hilft nicht, Kreativität zu fördern.

Computer denken nicht englisch, sondern in Zahlen. Die sind sprachbarrierefrei. Früher wusste jeder Programmierer, was ein Int21 ist. Das musste man gar nicht übersetzen. Heutzutage wird alles, aber auch alles, nur in Englisch erklärt. Mit unverständlichen Abkürzungen, Schreibfehlern, die jedes Übersetzungsprogramm aushebeln, und symbolischen Namen, die überflüssig sind.

Huh, da muss man auch noch eine fette Java-Programminstallation über sich ergehen lassen. Für jedes Betriebssystem extra, na klar. Robuste Software sieht anders aus! Mit Arduino hatte ich bis jetzt nichts zu tun. Wie ich sogleich sah, das war auch gut so:

UTFT - ziemlich unbrauchbar

Die Demo-Programme basieren auf UTFT, einer mickrigen Grafikbibliothek mit riesigem Speicherverbrauch.

Also erst mal alles nicht benötigte herausgeworfen und laufen gelassen: Von dem was übrig bleibt sieht's schon mal ganz gut aus! So wie's aussieht gibt's nichts besseres. Daher habe ich als erstes ein WinAVR-Projekt draus gemacht und den Arduino-Ramsch 'rausgeschmissen. An einem Demo konnte ich die folgenden Features erkennen:

Implementiert aber ungesehen ist (weil Demo gekürzt werden musste): Anmerkung: Die Rund-Rechtecke sind mit festem Eckenradius. Ellipsen gibt's nicht, die Display-Pixel müssen gefälligst 1:1 sein.

UTFT - noch einmal

Beim Blick auf das Disassemblerlisting (die man mit der Arduino-Software auf Tod und Teufel nicht zu Gesicht bekommt) fand ich riesige Passagen identischen Kodes. Was ist da los? Also: Unfähiger Programmierer. (Fleißig aber unfähig.) Sowas erwächst aus dem Arduino-System. War kaum anders zu erwarten. (Das gleiche Dilemma ist von VisualBasic bekannt.)

Ah, da findet sich eine memorysaver.h. Mal alle Displays ausknipsen, die nicht gebraucht werden. Wieso sind die per Default alle (~ 30) an? Hm, komischer Verdacht: Alles steckt in switch/case statt in #ifdef/#endif-Konstrukten! Wer kommt schon auf die Idee, an einen Mikrocontroller zwei Displays dranzuhängen??

Wie man's richtig macht sieht man bei V-USB: Fähiger Programmierer. Der nimmt auch keinen Arduino. Gut so. Schade nur, auch hier kein Deutsch.

Also alle nicht benötigten Controller auch noch restlos rausgeworfem, und die Code-Größe dampft auf erträgliche 20 Kilobyte ein. Unter Verzicht auf Gleitkomma und damit der freien Rotation. Würde sicherlich sowieso unleserlich aussehen, so ein schräger Font. Im Prinzip habe ich's neu geschrieben, aber (klar!) unfertig und mit folgenden Features:

Das Demo enthält auch Kode für den Touchscreen, ganz simpel zum Weiterschalten oder zum Pausieren.

Was fehlt und in eine abgeleitete Klasse gehört:

Das alles ercheint nur sinnvoll für Mikrocontroller mit mindestens 16 Bit Verarbeitungsbreite und mindestens 64 KByte Flash-Speicher. Der RAM-Verbrauch hält sich hingegen in Grenzen.

Hier ist Software (Download). Diese enthält eine make-basierte VisualStudio-2008-Projektdatei, um den Quelltext mit IntelliSense bearbeiten zu können und gleich in der Entwicklungsumgebung (IDE) übersetzen zu können. Abgesehen dass diese IDE noch einiges fetter ist, nicht unter Linux läuft und kein Deutsch kann, ist's auf Dauer trotzdem komfortabler. Für die Filterung des gcc-Outputs wird gccfilter benötigt.

Die Datenblätter nochmal:

  1. DB0
  2. DB1
  3. DB2
  4. DB3
  5. GND
  6. IOVCC
  7. /CS
  8. RS
  9. WR
  10. RD
  11. NC
  12. X+
  13. Y+
  14. X-
  15. Y-
  16. A
  17. K1
  18. K2
  19. K3
  20. K4
  21. NC
  22. DB4
  23. DB8
  24. DB9
  25. DB10
  26. DB11
  27. DB12
  28. DB13
  29. DB14
  30. DB15
  31. RESET
  32. VCC
  33. IOVCC
  34. GND
  35. DB5
  36. DB6
  37. DB7

Rätselhaftes TFT

Für diesen Ebay-Artikel (Suchworte TFT Arduino Uno R3) ist weder Dokumentation noch ein Beispielprogramm aufzutreiben! Alle UTFT-Displaytypen ausprobiert führte auch zu keiner Funktion. Die Pinbeschriftung deutet weder auf den benutzten Controller hin, noch ist klar wo und wie das Touchpanel angeschlossen ist. Nur dass es 240 × 320 Pixel hat ist dokumentiert. Bananen-Hardware also, oder gar ein Briefbeschwerer?

Also das Display gewaltsam von der Platine getrennt. Auf der flexiblen Leiterplatte steht eine Bezeichnung: FRD2803703. Google fördert ein PDF mit der Anschlussbelegung der Flexleiterplatte (siehe rechts) zu Tage, sowie den verwendeten TFT-Controllerchip: ILI9341. Keinen Schaltplan. Nicht mal einen unleserlichen.

Auf der Platine befindet sich ein Null-Ω-Widerstand mit der Beschriftung R8 und R16. Man hätte drauf kommen können, dass es sich dabei um die Auswahl der Busbreite 8 bit oder 16 bit handelt. Bestückt ist er als R8 auf 8 bit. Da aber nirgends in der Doku zu entnehmen ist, wie die IMx-Eingänge des ILI9341 beschaltet sind, kam mir zunächst der Verdacht, dass man den Low-Teil ansteuern muss und das Arduino-Shield, so wie's ist, gar nicht gehen kann.

Einige Experimente später kam schließlich raus, dass alles richtig angeschlossen und verdrahtet ist. Nur die UTFT-Bibliothek ist krankhaft konstruiert. Die IM-Anschlüsse und Datenleitungen müssen wie folgt beschaltet sein:

IM3IM2IM1IM0ModusDB15:8DB7:0
1000 16-bit-Interface IID17:10D8:1
18-bit-Interface II
Anschlussbelegung des Displays — nicht des Arduino-Shields
Immerhin unterstützt es das Rücklesen und damit Alpha-Blending und Scrollen. Der Pullup R1 auf der Unterseite wird nicht benötigt.

Die Touchpanel-Anschlüsse X+,X-,Y+,Y- teilen sich die übrigen Datenleitungen wie folgt:

ElektrodeSignalArduino-PinATmega328-PinATmega328-FunktionRuhezustandX messenY messen
X- (links) LCD_D7A124PC1ADC1 Z L Z + messen
Y- (oben) LCD_RS~610PD6- L Z L
X+ (rechts)LCD_WR 711PD7PCINT23Hi-Z + InterruptH Z
Y+ (unten) LCD_D6A225PC2ADC2 L Z + messenH
Direkte Analogwertabfrage beim „TFT-Shield 2.8″ R3“
So, hier ist eine halbfertige aber funktionierende Firmware (Einsicht). Dreh- und Angelpunkt ist eine "utft-config.h", die ich mit der Arduino-Software leider ums Verderben willen nicht in das Verzeichnis neben die .ino-Datei bekomme. Touchscreen-Unterstützung fehlt auch noch.

2016: Andere TFT-Zuordnung

Siehe Datei Touchscreen.h. Die TFT- und TouchScreen-Zuordnung ist immer noch etwas unglücklich gelöst und erfordert das Herumspielen am Makefile und der utft-config.h. Letzlich gibt es drei oder vier einigermaßen unabhängige Schräubchen zum Drehen:
ElektrodeSignalArduino-PinATmega328-PinATmega328-Funktion RuhezustandX messenY messen
X- (links) LCD_D0 814PB0PCINT0Hi-Z + InterruptL Z
Y- (oben) LCD_RSA326PC3ADC3 L Z + messenL
X+ (rechts)LCD_WRA225PC2ADC2 Z H Z + messen
Y+ (unten) LCD_D6~915PB1PCINT1L Z H
Direkte Analogwertabfrage beim „2.4″TFT LCD SHIELD“
Firmwarestand von 2016 auf ILI9341. Der Proportionalfont sieht fetzig aus
Seit August 2016 gibt es auch einen Monatskalender mit Editierfunktion.

Was man nicht sieht: Vom Hauptbild geht es per Touch in drei Bereiche zu drei Unterprogrammen:
Touchscreen kalibrieren
MonatskalenderUhr stellen
Die Klickbereiche sind hierbei unkalibriert getrennt, damit man überhaupt sinnvoll zum Kalibrier-Dialog kommt. Zielgenauigkeit ist erst bei „Monatskalender“ und „Uhr stellen“ vonnöten.

Abfallkalender

Nach einigen Diskussionen mit den Besitzern solcher Arduinos + TFT-Shields stellte sich doch noch eine sinnvolle Anwendung heraus. Natürlich nicht für Bewohner von Plattenbauten, wie ich, sondern für Häuslebesitzer — ein Abfallkalender oder kurz Müllkalender. Dieser hängt in der Küche oder an der Hauseingangstür und erinnert mit einer auffälligen Hintergrundfarbe daran, die entsprechende Tonne an den Straßenrand zu stellen. Von Vorteil ist der geringe Stromverbrauch von ca. 100 mA, der sicherlich aus 80 % Hintergrundbeleuchtung besteht. Die gleiche Lösung mit einem Raspberry wäre deutlich gefräßiger.

Die derzeitige Firmware zeigt die Aktion für den heutigen, morgigen und übermorgigen Tag an, auch mehrere Aktionen pro Tag können angezeigt werden. Ein Großteil des Kodes kümmert sich um das Stellen der Uhr mit dem Touchscreen. Die UTFT-Bibliothek kommt nunmehr mit UTF-8 zurecht und kann die Zeichenposition 0x80..0x9F im Windows-Zeichensatz CP1252 benutzen. Für mehr als 256 Zeichen ist's aber erst mal nicht vorgesehen. Zur perfekten Ablesbarkeit wurden zwei Proportionalschriften mit 19 und 24 Pixeln Zellenhöhe und je 224 Zeichen eingebaut, was trotzdem nur ca. 13 kByte Speicher verbraucht. Das Konvertierungsprogramm für die UB-PixelFontGenerator-Dateien ist in awk geschrieben.

Die jetzige Implementierung ist mit einigen Unvollständigkeiten verbunden:

Aber so ein Arduino ist ja zum Dranherumspielen gemacht. Der Flash-Speicher ist nun ziemlich voll. Was man so noch einbauen könnte bzw. was vorsehbar ist: Funktionsfähige Firmware (Müllkalender) für die beiden untersuchten Displays mit Da ich die beiden Displays nicht gleichzeitig zum Test da hatte, leider mit getrennter UTFT-Bibliothek.

Rätselhaftes Display

Ein September 2016 geliefertes 2,4″-Touch-Display mit der Aufschrift „S24GF31“ (auf dem Metallgehäuse), der Prägung „LMS241GF31“ sowie „CK241_REV0.1“ und „IS9F01YOP1P“ auf dem Flexboard erweist sich zwar ganz sicher als eines mit 240 × 320 Pixeln (400 Pixel sind Quatsch, ich hab's nachgezählt), aber mit dem Sketch „st7883.zip/examples/Mygraphicstest/Mygraphicstest.ino“ kommt auch nur ein zuckender (= kurzzeitig auf Schwarz umschaltender) weißer Bildschirm mit einigen farbigen Pixeln heraus. Immerhin, alle anderen Sketche zucken gar nicht. Es könnte sich also tatsächlich um einen ST7883 handeln. Aber ein Datenblatt dazu ist nicht zu finden. Ob es ein S6D04H0 ist, muss sich noch erweisen.

Gelöst!

Das Display LMS241GF31 enthält den Chip S6D04H0, welcher weitestgehend identisch zum ILI9341 ist, nur die Initialisierungssequenz ist anders. Siehe Quelltext-Abschnitt der Initialisierungssequenz. Damit funktionieren Programme wie die oben gezeigte Müllkalender-Äpp auch prompt mit diesem neuen Display.

Der Touchscreen verhält sich anscheinend wie bei älteren Displays mit ILI9325 und funktioniert nun auch:

ElektrodeSignalArduino-PinATmega328-PinATmega328-FunktionRuhezustandX messenY messen
X- (links) LCD_D7711PD7PCINT23Hi-Z + InterruptLZ
Y- (oben) LCD_RSA225PC2ADC2LZ + messenL
X+ (rechts)LCD_WRA124PC1ADC1ZHZ + messen
Y+ (unten) LCD_D6~610PD6-LZH
Direkte Analogwertabfrage beim neuesten Arduino-Shield mit „LMS241GF31“

Noch eins mit ILI9481

Solche 3,5-Zoll-Displays sind (September 2016) preiswert zu kaufen, haben mit 320 x 480 die doppelte Pixelzahl und bieten angenehm viel Fläche — leider ohne Touch. Die Initialisierungssequenz aus der originalen UTFT-Bibliothek eingebaut läuft diese Version prompt los, nur bei der Rotation hapert's noch.

Siehe Quelltext.

Unbekanntes 2,4-Zoll-Display (August 2017)

Eine neue Lieferung enthält Displays mit der Aufschrift 2,4" TFT LCD SHIELD www.mcufriend.com. Auf dem Blechmantel steht M202110419 TFT1P5589-E. Kein bisher bekannter Display-Chip. Hm.