2.8'' TFT Shield mit I2C-Ansteuerung

2.8'' TFT Shield mit I2C-Ansteuerung DL6GL Mo., 25.03.2019 - 11:53
TRX TFT screen

Mittlerweile sind hochauflösende TFT mit 320x240 Pixel oder mehr erschwinglich geworden. Anlass, über einen Nachfolger des hier [1] beschriebenen Grafikdisplays mit mickrigen 128x64 Pixel Auflösung nachzudenken.
Update 03/2020: V2.00, Touchscreen mit Rückmeldung an den Master.

Das noch eingetütet vor sich hindämmernde 2,8'' TFT Shield für einen Arduino UNO war also zum Leben zu erwecken. Beschafft wurden beide Teile vor längerer Zeit bei gearbest.com (China) als Bundle. Das TFT Shield ist dank 3,3V-Regler und Levelshifter on Board kompatibel zu 5V-Umgebungen. Dürftig sind die damals angegebenen technischen Daten:

2.8 inch LCD TFT display 
Bright, 4 white-LED backlight 
Colorful, 18 - bit 262,000 different shades 
wire resistive touchscreen 240 x 320 pixels with individual pixel control 
No wiring, no soldering. 
Simply plug it in and load library 
On-board 3.3V 300mA LDO regulator 
8.5V compatible, use with 3.3V or 5V logic 
Support 2GB micro SD TF card.

Das Display wird über 8 Datenleitungen und 5 Kontrollleitungen angesteuert, dazu noch 4 Leitungen zum SD-Kartenleser.

TFT Shield

Abb. 0.1: 2,8'' TFT Shield, Rückseite.

Das mit dem "zum Leben erwecken" entwickelte sich jedoch zur Geduldsprobe besonderer Güte. Mit dem Vorsatz, endlich auch mal die Arduino IDE einzusetzen, zuckte das TFT nicht einmal. Nur weißer Schirm. Probiert wurde mit der mcufriend_kbv zusammen mit der adafruit.gfx. Kurz vor dem Aufgeben deckte schließlich die Inspektion des TFT-Boards zwei kümmerliche Lötstellen an den Stiftleisten auf. Also wurden alle (!) Lötstellen, auch die zum TFT-Flexboard, nachgelötet. Und siehe da, das Programm graphictest_kbv identifizierte auf dem seriellen Monitor den TFT-Controller als ILI9341. Auch weitere Beispielprogramme zauberten richtig nette Grafiken auf den Schirm.

Qualitätskontrolle ist bei einigen Billiganbietern in China offenbar ein Fremdwort. Gearbest bietet das o.g. Arduino UNO + 2,8'' Shield Bundle inzwischen nicht mehr an - wohl deshalb?

Was allerdings bei des Tests herauskam, ist der immense Speicherverbrauch der untersuchten Testprogramme. Platz für ein Anwenderprogramm ist im Arduino UNO kaum noch. Weiterhin sind als freie Ports nur noch A5 (PC5), 0 (PD0/RX) und 1 (PD1/TX) verfügbar, wobei RX und TX auch die USB-Schnittstelle bedienen.

Fazit: Ein Arduino UNO mit einem TFT-Shield und 8Bit Parallelansteuerung ist eigentlich ein Witz. Es braucht einen größeren oder einen zweiten Controller, um die eigentliche Anwendung, die visualisiert werden soll, unterzubringen. Wenn der UNO schon mal da ist, setzen wir ihm also noch einen Master-Controller vor die Nase.

 

Referenzen

[1]  https://dl6gl.de/grafikdisplay-mit-i2c-ansteuerung
[2]  https://bascomforum.de/index.php?thread/225-tft-display-ili9341-2-2-und…
[3]  https://dl6gl.de/avr-kopplung-ueber-i2c

1 Konzept

1 Konzept DL6GL Mo., 25.03.2019 - 11:55

Als gewohnheitsmäßiger BASCOM-Nutzer fremdelte ich dann doch mit der Arduino IDE. Rasche Ergebnisse mussten her. "Mister Display" HKipnik hat in [2] eine Library "Uni-TFT-ILI9341-Uno.zip" für das ILI9341 in einer BASCOM-Umgebung auf Arduino UNO veröffentlicht. Das Testprogramm "ILI9341-8bit-UNO.bas" lief auf Anhieb.

Mit den drei noch verfügbaren Ports ist allerdings kein Staat zu machen, es sei denn, notwendige Steuerungsfunktionen von außen erfolgen seriell über TX/RX, Anschlüsse 0 und 1, bzw. via USB. I2C wäre mir lieber. Das TFT belegt aber den Anschluss A4 (PC4/SDA) für den Software-Reset des Displays. Um den Port PC4/SDA frei zu bekommen, wurde der Reset-Pin "RES" des Arduino mit dem für den TFT-Reset vorgesehenen LCD-Pin LCD-RST verbunden (Abb. 1.1). Das TFT erhält damit den Reset vom Arduino. Dazu wurden die Pins auf der TFT-Steckerleiste zum Arduino A4 (PC4) und A5 (PC5) ausgelötet. Nun sind die Ports SDA und SCL für die I2C-Kommunikation verwendbar.

Da auf die Darstellung von Bitmap-Bildchen über den SD-Kartenslot gut verzichtet werden kann, würden noch PB2 bis PB5 am Arduino zur Verfügung stehen.

TFT Shield modifications

Abb. 1.1: Modifikation des TFT-Boards für eine I2C-Kommunikation.

Die damit verbundene Absicht ist folgende:

  1. Der Arduino ist nur für die Displaysteuerung zuständig. Dafür ist der Flash-Speicher ausreichend.
  2. Ein Master-Controller legt fest, welche Daten in welcher Form auf dem Display dargestellt werden sollen.
  3. Kopplung über I2C.

Master slave configuration

Abb. 1.2: Master-Slave-Konfiguration.

Als Master wurde für Testzwecke ein ATmega16 mit einem 16x2-Display eingesetzt.

Auf beiden Seiten, Master und erst Recht Slave, wird Hardware-I2C eingesetzt. Die Ports müssen also entsprechend zugeordnet werden:

Funktion Controller SCL SDA
Master ATmega16 PC0 PC1
Slave ATmega328P PC5 PC4

Es ist noch eine dritte Verbindung zwischen Master (PC2) und Slave (PB2) vorgesehen: zur Synchronisation. Das LCD im Slave benötigt eine gewisse Zeit zum Malen, je mehr Pixel, je mehr Zeit. Kommt während dieser Ausführungszeit ein neuer I2C-Befehl, gerät alles durcheinander. Der Master muss also mitbekommen, ob der Slave noch mit Malen beschäftigt ist oder nicht. Das könnte mit entsprechendem Aufwand auch mit einem I2C-Protokoll vom Slave zurück zum Master erledigt werden, mit der der Slave eine entsprechende Quittierung an den Master zurückschickt "Ich habe fertig mit Malen, lass mal wieder was kommen".

War mir zu kompliziert. "KISS" (keep it simple and stupid) ist für den Anfang immer noch die bessere Lösung. Stattdessen legt der Slave vor Beginn eines jeden Befehls an das LCD den Port PB2 auf high, mit Abschluss dann wieder auf low. Der Master prüft vor dem Absenden eines neuen Befehls, ob das Signal an seinem Port PC2 low ist, und wartet ggf. darauf.

 

2 Software

2 Software DL6GL Mo., 25.03.2019 - 11:56

Die Grundstruktur der Software ist vergleichbar mit der in [1] beschriebenen:

  • Master: Parametrierung der gewünschten Darstellungen und Übertragung an den Slave,
  • Slave: Darstellung mit Hilfe der aus [2] verfügbaren Displayfunktionen.

Folgende Funktionen sind implementiert:

Lcd_line Linie von/bis mit wählbarer Strichstärke und Farbe
Lcd_box Rechteck mit wählbarer Breite/Höhe, Füllfarbe und Rahmenfarbe
Lcd_circle Kreis mit wählbarem Mittelpunkt/Radius und Linienfarbe
Lcd_fill_circle Kreis mit wählbarem Mittelpunkt/Radius und Füllungs-/Linienfarbe
Lcd_text Text mit wählbarer Schriftgröße/Farbe und Hintergrundfarbe
Lcd_clear Bildschirm löschen und neue Hintergrundfarbe setzen

Explizite Löschfunktionen sind nicht vorgesehen. Sollen z.B. ein Text oder eine Grafik selektiv gelöscht werden, muss der vorherige Befehl zur Darstellung des Textes oder der Grafik mit der aktuellen Schirm-Hintergrundfarbe wiederholt werden. Bei Text etwa Textfarbe = Hintergrundfarbe = Schirm-Hintergrundfarbe. "Löschen" ist also Überschreiben mit der Schirm-Hintergrundfarbe.

Bei einer Balkenanzeige (Bargraph) mit ständig veränderlichen Balkenlängen ginge das dann so:

  1. Erster Balkenwert = Anfangswert, z.B. =0
  2. Bei allen Folgewerten für den Balken die Differenz neuer Wert - aktueller Wert berechnen.
  3. Ist die Differenz = 0 (kein Unterschied), gibt es nicht zu tun.
  4. Ist die Differenz > 0 (neuer Wert größer), den Differenzwert zum aktuellen Balken zufügen.
    Der Balken wird länger
  5. Ist die Differenz < 0 (neuer Wert kleiner), den Differenzwert vom aktuellen Wert abziehen und von dort bis zum aktuellen Wert den Balken mit Schirm-Hintergrundfarbe übermalen.
    Der Balken wird kürzer.

Es ist also einiges an Rechnerei und Pixelmalerei nötig. Das braucht Zeit. Ein heftig zappelndes VU-Meter wie in professionellen Mischpulten bekommt man damit nicht hin.

Die Beschreibung der Master-Funktionsparameter ist im Download zu finden.

Die ILI9341-Library "ILI9341_functions8.inc" von HKipnik [2] wurde entsprechend der genannten Änderungen angepasst:

  • Funktionen für die SD-Card entfernt,
  • Steuerung für den Software-Reset des LCD über A4/PC4 in "Lcd_INIT" entfernt.

Sie heißt nun "ILI9341_functions8_DL6GL.inc".

Im Slave-Programm ist als Standarddarstellung "Landscape", also 320 Pixel horizontal und 240 Pixel vertikal, vorbesetzt.

Funktionen für das TFT-Touchpanel wären noch nett gewesen. Dazu müssten die Touch-Ereignisse dann vom Slave an den Master zurückgegeben werden. Kann die I2C-Software derzeit nicht. Vielleicht später einmal...

Das I2C-Protokoll wird je nach Länge der Parameterliste in den Masterfunktionen variabel aufgesetzt:

Byte Name Bedeutung
0 bytGD_Addr Slave-Address
1 bytGD_Len Number of data bytes from byte 1 to n
2 bytGD_Cmd LCD command
3 bytGD_Dat(1) First command parameter data byte
n bytGD_Dat(n-2) Last command parameter data byte

Mit der Nutzung von Hardware-TWI erfolgt der Empfang im Slave über die Auswertung der TWI-Register wie in [3] beschrieben.

Der Gesamtablauf sieht dann so aus:

Master-Slave data flow

Abb. 2.1: Programmablauf in Master und Slave.

Ein Master Demo- und das Slave-Programm sind im Download zu finden.

Die Pixel-Rechnerei bei der Ausrichtung von Texten auf dem Display erleichtert ein kleines Excel-Sheet im Download.

3 Erweiterte I2C-Kopplung mit Touchscreen

3 Erweiterte I2C-Kopplung mit Touchscreen DL6GL Mo., 09.03.2020 - 11:02

Update V2.00, 03/2020

Nun wollte ich es wissen: Mit der hier in Abschnitt 3 beschriebenen I2C-Kopplung, die auch eine Reaktion des Slaves zulässt, sollte es nun möglich sein, auch einen Touchscreen auszulesen. Ziel war also, ein Touch-Ereignis, etwa Button 2 auf dem Slave-Display wurde gedrückt, zurück an den Master zu geben, um dort eine entsprechende Reaktion des Steuerprogramms auszulösen.

Abb. 3.1: Touch Panel des Slave-Displays.

Im Slave werten die AVR-ADC Touch-Ereignisse aus. Dazu werden jeweils zwei gegenüber liegende Elektroden einer Kontaktfläche (Layer) des Touch Panel an +Vcc bzw. GND gelegt und der durch den Fingerdruck erzeugte Spannungsabfall des Widerstandsnetzwerkes am anderen Layer (Abb. 3.2) gemessen.

Abb. 3.2: Resistives Touch Panel schematisch (Quelle Wikipedia).

Da die gemessenen ADC-Werte infolge kapazitiver Kopplung auf das Panel auch ohne Berührung recht stark schwanken, wird zunächst festgestellt, ob ein bestimmter Schwellenwert durch einen Fingerdruck überschritten wurde. Erst dann erfolgt die ADC-Messung an beiden Layern, um festzustellen, wo die Betätigung erfolgt war.

Die so ermittelten X/Y-Koordinaten sind zunächst ADC-Werte von 0 bis 1023. Eine Umrechnung in die Displaykoordinaten X/Y = 240/320 oder umgekehrt je nach Orientierung ermöglicht eine Kalibrierung. Hierzu wurde die Routine von HKipnik unverändert übernommen. Sie arbeitet im Portrait Mode (aufrecht). Die Umrechnung in andere Orientierungen erfolgt automatisch, zumindest wie erprobt im anschließenden Landscape Mode (quer).

Die Kalibrierungsdaten werden im EEPROM des Slave gespeichert. Das Fuse Bit EESAVE ist dazu zu setzen. Wenn mit dem erstmaligen Betrieb ein unbeschriebenes EEPROM vorgefunden wird, startet die Kalibrierungsroutine im Slave-Testprogramm. Drei mit einem Fadenkreuz gekennzeichnete Punkte sind nacheinander mit einem Stift möglichst genau anzutippen. Eigentlich selbsterklärend.

Zu den vier Anschlüssen des (resistiven) Touch Panels ist noch anzumerken:

  1. Die Anschlüsse X+, X-, Y+, Y- oder auch XP, XM, YP, YM sind mit anderen TFT-Anschlüssen doppelt belegt. Sie sind also nur alternativ zu benutzen, entweder Touch oder TFT. Beides, Touch-Auswertung und TFT-Anzeige, quasi gleichzeitig zu betreiben ließe sich über Zeitscheiben oder Interrupts lösen.
  2. Es ist offenbar so, dass diese Doppelbelegungen je nach Hersteller verschieden sind. Im Zweifelsfall hilft hier nur Ausmessen (welcher Anschluss am Flexboard des Touch Panels geht an welchen beschrifteten Pin des Display-Boards?).
  3. Chinesische Händler liefern zumeist keinerlei Dokumentation, nicht mal Links darauf.

Am oben beschriebenen TFT wurden folgende Pin-Zuordnungen gefunden und in ILI9341-Slave_200.bas programmiert:

Touch TFT-Pin Arduino UNO
X- LCD_RS A2 (PC.2/ADC2)
X+ LCD_D6 PD.6
Y- LCD_D7 PD.7
Y+ LCD_WR A1 (PC.1/ADC1)

Fallweise müssen die Alias-Zuweisungen im Erklärungsteil von ILI9341-Slave_200.bas umdefiniert werden.

Die Include-Dateien "ILI9341_functions8_DL6GL.inc" zu V1.00 und V2.00 sind nicht zueinander kompatibel. Es sind die Versionen aus den jeweiligen .zip-Files zu verwenden.
In V2.00 ist die "ILI9341_Colordefinitions.inc" hinzugekommen.

Das in Abschnitt 2 vorgestellte Testprogramm wurde neben der neuen I2C/TWI-Software um den in Abb. 3.1 gezeigten Touchscreen erweitert. Mit Fingerdruck auf "Touch1" bis "Touch3" wird der entsprechende Button an den Master zurückgegeben. Nach Betätigen von "End" spult sich die schon vorher vorhandene Demo ab.

Die Synchronisation über die in Abb. 1.2 gezeigte Steuerleitung ist verblieben. Sie ist einfacher und vor allem schneller als eine nunmehr denkbare Rückmeldung vom Slave an den Master via I2C.

 

4 Download

4 Download DL6GL Mo., 25.03.2019 - 12:43

Hier noch die Software (Master-Demo, Slave, TFT-Library und Fonts) und eine Beschreibung der Masterbefehle. Als Demo handelt es sich hier um einen Werkzeugkasten, aus dem sich der geneigte Leser die passende Anwendung dann selber stricken kann.

  • V100: Zu Abschnitt 2.
  • V200: Zu Abschnitt 3.