mbed mit TFT-Touchscreen

Schon im Sommer hatte ich einen Testbericht über die kleinen mbed-Eval-Boards mit Cortex-M3 von NXP verfasst und mir einen Schwung diverser Elektronik inklusive dem 2,8″-TFT-Touch-Shield (die Variante mit dem ST7781R-Controller) von SeeedStudio bestellt. Dabei handelt es sich um das derzeit inklusive Versandkosten günstigste mir bekannte QVGA-Display mit Touch, für welches auch umfangreiche Dokumentationen verfügbar sind.
Das Display und seine Ansteuerung werden im SeeedStudio-Wiki detailliert beschrieben (2.8′’ TFT Touch Shield externerLink) und es werden auch Treiberbibliotheken angeboten - nur gibt es in Verbindung mit dem mbed ein Problem. Das Display hat nicht nur ein Arduino-Layout für seine Kontakte, auch die Bibliotheken sind auf den Arduino-Spielkram ausgelegt. Also muss für die Verwendung mit einem LPC1768-Mikrocontroller ein gewisser Teil des Rades neu erfunden werden.

Schon kurz nachdem ich das Display hatte, begann ich mit der Treiberanpassung und ohne irgendwelche Optimierungen bekam ich auch schnell eine lauffähige Version. Allerdings ist das Ergebnis dann unglaublich langsam, immerhin sind Arduino-Bibliotheken nicht gerade für hohe Performance und ressourcenschonende Codeoptimierungen bekannt. Für einen mit 96 MHz getakteten ARM-Prozessor war mir das Ergebnis dann auch um Welten zu schlecht, also mussten Optimierungen her. Diese Optimierungen waren extrem frickelig und verschlangen reichlich Zeit. Es stellte sich dabei schnell heraus, dass dieses extrem günstige Display nicht dafür geeignet ist, mit Prozessoren der ARM-M-Klasse ohne künstliche Verzögerungen angesprochen zu werden. Im Datenblatt finden sich zu mehreren Operationen auch enorm langsame Reaktionszeiten von teils um die 150µs. Etwas verwirrend war auch, dass teilweise Befehle in Reihenfolgen verwendet werden müssen, die so nicht aus dem Signalablaufplan des Datenblatts hervorgehen. Als bestes Beispiel einer enormen Performancesteigerung durch die Codeoptimierungen lässt sich der ClearScreen nennen. Dabei kam ich immerhin von ca. 27s auf unter 2.5s - das dürfte beim ursprünglichen Zielgebiet Arduino selbst mit perfekter Optimierung weit jenseits des Machbaren liegen. An anderen Stellen wie dem normalen SetPixel hingegen gelangen mir trotz intensiver Versuche keine Optimierungen; hier konnte ich nicht auf die durch umständliche Funktionsaufrufe bedingten Verzögerungen verzichten. Den größten Teil der Zeichenfunktionen habe ich unverändert aus dem Arduino-Original übernommen und ein paar kleine Funktionen ergänzt. Da ich im Code alte Fragmente von Optimierungsversuchen drin gelassen habe, kann man an dieser Stelle neu ansetzen und weiterprobieren.

Vorschau: mbed mit TFT-Touch-DisplayAnfang Oktober war im ersten Kommentar meines Artikels zu einem Lithium-Polymer-Lader bereits ein Foto mit dem am mbed laufenden Display zu sehen, da waren auch schon die meisten Optimierungen fertig. Ursprünglich wollte ich bis Ende Oktober dann auch die Bibliotheken veröffentlichen - nun, jetzt ist es so weit. Perfekt sind diese zwar noch lange nicht, aber das Display funktioniert und eine Touchauswertung ist sogar mit nur zwei Leitungen (”normal” sind 4 GPIO-/AD-Pins) ansatzweise möglich. Standardmäßig werden 4-wire-Touchs auch mit allen 4 Leitungen ausgewertet. Hierzu müssen permanent die Pins umdefiniert werden, was natürlich beim Schreiben der Routinen nervt und später im Betrieb Zeit und Ressourcen kostet. Mehr zu dieser normalen Vorgehensweise findet sich im oben verlinkten Wiki und z.B. in Datenblättern von Atmel (AVR341) oder NXP (AN10675). Andererseits ist es möglich, zwei der Touch-Pins fest mit GND/VCC zu verbinden und nur die anderen beiden per ADC auszuwerten, was nicht nur das Umschalten spart, vor allem verbleiben 2 der raren ADC-Pins zur sonstigen Verfügung. Allerdings hat auch diese Variante einen Nachteil. Hierfür ist nämlich eine Umrechnung notwendig, da je nach Position des Touchs die Brückenschaltung der integrierten X-/Y-Widerstände dazu führt, dass eine Änderung in X-Richtung auch Y beeinflusst und die Y-Richtung andersherum auch X. Irgendwo hatte ich die nötigen Formeln mal gesehen, nur wo? Vielleicht kann mir einer der Leser weiterhelfen, sonst muss ich mich irgendwann doch selbst darum kümmern und zur Not die Beeinflussung der anderen Achse selbst herausrechnen. Falls jemand Lust verspürt, eine 4-Pin-Variante für den mbed auf Basis meiner Bibliotheken zu schreiben und mir zukommen zu lassen, würde ich mich auch darüber freuen. Das ist beim ARM-Controller bedingt durch seine größere Flexibilität etwas frickeliger als bei Atmel AVRs und ich würde dazu vielleicht erst zum Jahresende kommen.

Bis Ende des Jahres wollte ich eigentlich auch ein Entwicklungsboard in Kleinserie fertig haben, welches direkt für Anwendungen zu diesem Artikel hier optimiert ist. Es soll also ein Board werden, dass auf die Verwendung des mbed mit diesem Touch-Display (oder anderen Arduino-Shields) ergänzt um einige nette zusätzliche Elemente, optimiert ist. Erste Versionen hatte ich schon im Sommer entworfen, aber so richtig rund ist es noch immer nicht. Es fehlte bisher schlicht die nötige Zeit für solche doch recht umfangreichen “Nebenbeiprojekte” … Vielleicht schaffe ich es trotzdem noch, bis zum Ende des Jahres zumindest manuell gelötete Prototypen anbieten zu können. Wer nicht so lange warten möchte, findet inzwischen auch alternative Boards anderer Anbieter, wenngleich mir die allesamt nicht gefallen - manch einer wird damit sicherlich trotzdem glücklich werden.

Doch zurück zum eigentlichen Thema, meiner kleinen Bibliothekssammlung. Diese findet sich im Download-Bereich und eine detaillierte Beschreibung der Dateien und Funktionen kommt in den nächsten Tagen in einem separaten Artikel. Die zip-Datei beinhaltet das Standardverzeichnis sample von Tollos, welches man einfach durch meine Sammlung ersetzt.
Die Verdratung ist simpel. Hierzu benötigt man drei Dinge:
- das Arduino-Pinout des Displays (im oben verlinkten Wiki)
- das mbed-Pinout (liegt z.B. im mbed-Set als Visitenkarte und als ID1-Card bei)
- aus meiner Sammlung die Datei lcd/TFT-ST7781R.h (im Kopfbereich steht die Pinzuordnung)
Entsprechend den Pinouts und der Zuordnung steckt man alles mittels einfacher female-female-Jumper zusammen, kompiliert das Programmpaket (evtl. in der churn.bat den Pfad zum mbed-USB-Laufwerk anpassen) und nach einem mbed-Reset sollte alles laufen. Im Beispielcode wird noch ein LDR ausgewertet, wer diesen nicht hat, kann das auch auskommentieren oder ignorieren. Nach einem Druck auf das Display wird die (noch nicht korrekt umgerechnete) Position angezeigt. Der Bildschirm wird im Beispielcode 1x pro Sekunde gelöscht und das Testbild neu gezeichnet, erkennbar am kurzen Flackern.

PS: ja ich weiß, dass der Code schmuddelig ist und die Bibliotheken nur aus Headern inkl. Code bestehen. Das ist während der Entwicklung wesentlich praktischer und übersichtlicher, in endgültigen Versionen korrigiere ich derartiges dann manchmal auch durch Aufsplitten in C- und H-Files ;)

Einen Kommentar schreiben