Lesezeit: 5 Minuten

Ziele des Projekts
- Einführung in das Konzept GFXcanvas der Bibliothek Adafruit GFX Library
- Anzeige der analogen Daten eines Potentiometers als Text und als veränderbarer Balken
Verwendete Hardware
- TFT-Display mit 320×240 Pixeln
- TFT-Display mit 160×128 Pixeln
- ESP32-Wroom oder Wemos D1 Mini/NodeMCU
- Potentiometer
Das Programm im Film
Anschluss des Potentiometers
Benötigte Bibliothek

Soll ein schnell wechselnder Text oder ein sich veränderndes grafisches Element an der gleichen Position dargestellt werden, gibt es zwei Probleme:
- der geänderte Text ist länger oder kürzer als der vorherige, dadurch überlappen sich die Buchstaben
das neue grafische Element unterscheidet sich in der Größe vom bisherigen - weil der Bildschirm immer gelöscht und wieder neu aufgebaut wird, verursacht das neue Element ein Flackern des TFTs
Das erste Problem lässt sich lösen indem der bisherige Text oder das grafische Element durch ein ausgefülltes Rechteck "gelöscht" wird. Das verhindert allerdings nicht das Flackern des TFTs.
Die durch die Installation der Bibliothek Adafruit ILI9341 zusätzlich installierte Bibliothek Adafruit GFX Library enthält die Funktion GFXcanvas. Sie legt ein Bild der darzustellenden Daten im Speicher an, auf Anforderung wird dieses Bild auf dem TFT dargestellt.
Im Film wird der blau dargestellte Bereich mit GFXcanvas erzeugt, im roten Bereich wird der Text zunächst durch ein rotes Rechteck "gelöscht" und anschließend neu geschrieben. Als Text wird die mit ⇒millis() gemessene Zeit, die seit dem Start des Programms vergangen ist, dargestellt.
Man kann den Unterschied gut erkennen.
Jedes Objekt vom Typ GFXcanvas1 benötigt pro ein Bit pro Pixel. Wie im Beispiel eines Bereichs mit 240×150 Pixeln sind das 36.000 Bits, das entspricht 4.500 Bytes oder 4,5 kiloBytes. Der Speicherplatz eines Arduino UNO R3 reicht hierfür nicht aus.
Du musst die // vor den Pins des verwendeten Mikrocontrollers entfernen.
// Display mit 240x320 Pixeln
#include "Adafruit_ILI9341.h"
// Wemos D1 Mini
// #define TFT_CS D8
// #define TFT_RST D1
// #define TFT_DC D2
// ESP32-WROOM
// #define TFT_CS 5
// #define TFT_RST 4
// #define TFT_DC 2
// Objekt der Bibliothek erstellen
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
// 1-Bit Canvas definieren
GFXcanvas1 Bereich(240, 150);
void setup()
{
// TFT starten
tft.begin();
// wenn die Farben invertiert sind
// weiß = schwarz, schwarz = weiss ...
// // entfernen
// tft.invertDisplay(1);
// schwarzer Hintergrund
tft.fillScreen(0x0000);
// Text darf nicht über den Rand fließen
Bereich.setTextWrap(false);
tft.setTextWrap(false);
}
void loop()
{
// Canvas erstellen
Bereich.fillScreen(0x0000);
Bereich.setCursor(1, 40);
Bereich.setTextSize(3);
Bereich.print("Millisekunden:");
Bereich.setCursor(1, 80);
Bereich.print(millis());
// Canvas als Bild anzeigen
/*
Farben
0x0000 = schwarz
0xFFFF = weiß
0x000F = blau
0xF800 = rot
*/
tft.drawBitmap(0, 0, Bereich.getBuffer(), Bereich.width(), Bereich.height(), 0xFFFF, 0x000F);
// Bereich für den Text "löschen"
tft.fillRect(1, 180, tft.width(), 100, 0xF800);
tft.setCursor(1, 200);
tft.setTextSize(3);
tft.print("Millisekunden:");
tft.setCursor(1, 240);
tft.println(millis());
}
Konfiguration der Mikrocontroller
Analoger Pin
Schließe das Potentiometer an einem analogen Pin an:
Das Programm TFT 240×320 Pixel
Du musst beim verwendeten Mikrocontroller die // entfernen und den Wert für ADCmax anpassen:
ESP32-Wroom: 4096, ESP8266: 1024
#include "Adafruit_ILI9341.h"
// Schriftarten einbinden
#include "Fonts/FreeSans24pt7b.h"
#include "Fonts/FreeSans12pt7b.h"
// Wemos D1 Mini
// #define TFT_CS D8
// #define TFT_RST D1
// #define TFT_DC D2
// ESP32-WROOM
// #define TFT_CS 5
// #define TFT_RST 4
// #define TFT_DC 2
// Farben
#define SCHWARZ 0x0000
#define WEISS 0xFFFF
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
// GFXcanvas-Objekt erstellen: Höhe 170 Pixel, Breite 320 Pixel
GFXcanvas1 Bereich(170, 320);
// analogen Pin anpassen
int Poti = A0;
// maximalen Wert des ADC anpassen
// ESP32: 4096, ESP8266: 1024
int ADCMax = 1024;
/*
Abstand der Markierung von der Mitte des TFTs
der ADC liefert keine linear verlaufenden Werte
der Abstand kann angepasst werden
*/
int AbstandMarkierung = 40;
void setup()
{
// TFT starten
tft.begin();
// Rotation anpassen
tft.setRotation(2);
// schwarzer Hintergrund
tft.fillScreen(SCHWARZ);
Serial.begin(9600);
}
void loop()
{
Bereich.fillScreen(SCHWARZ);
// analogen Wert lesen
int WertPoti = analogRead(Poti);
Serial.println(WertPoti);
// analogen Wert anzeigen
Bereich.setFont(&FreeSans24pt7b);
Bereich.setCursor(10, 50);
Bereich.print(WertPoti);
// analogen Wert auf die Höhe des TFTs übertragen
int BalkenPoti = map(WertPoti, 0, ADCMax, 0, 320);
/*
bei gedrehtem Bildschirm wird der Balken von oben nach unten angezeigt
zuerest maximalen Wert weiß füllen
anschließend vom maximalen Wert den gemessenen Wert abziehen
und schwarz füllen
*/
Bereich.fillRect(120, 1, 50, 320, WEISS);
Bereich.fillRect(120, 1, 50, 320 - BalkenPoti, SCHWARZ);
Bereich.setCursor(70, tft.width() / 2 - AbstandMarkierung);
Bereich.setFont(&FreeSans12pt7b);
// je nach Wert ADCMax Zahlen anzeigen
if (ADCMax == 4096) Bereich.print("3000");
else Bereich.print("750");
Bereich.drawLine(tft.height() / 2, tft.width() / 2 - AbstandMarkierung, 50, tft.width() / 2 - AbstandMarkierung, WEISS);
Bereich.setCursor(70, tft.width() / 2 + 40);
if (ADCMax == 4096) Bereich.print("2000");
else Bereich.print("500");
Bereich.drawLine(tft.height() / 2, tft.width() / 2 + AbstandMarkierung, 50, tft.width() / 2 + AbstandMarkierung, WEISS);
Bereich.setCursor(70, tft.width() / 2 + AbstandMarkierung * 3);
if (ADCMax == 4096) Bereich.print("1000");
else Bereich.print("250");
Bereich.drawLine(tft.height() / 2, tft.width() / 2 + AbstandMarkierung * 3, 50, tft.width() / 2 + AbstandMarkierung * 3, WEISS);
// GFXcanvas anzeigen
tft.drawBitmap(0, 0, Bereich.getBuffer(), Bereich.width(), Bereich.height(), WEISS, SCHWARZ);
}
Programm für TFT 160×128 Pixel
Du musst beim verwendeten Mikrocontroller die // entfernen und den Wert für ADCmax anpassen:
ESP32-Wroom: 4096, ESP8266: 1024
#include "Adafruit_ST7735.h"
// Schriftarten einbinden
#include "Fonts/FreeSans9pt7b.h"
#include "Fonts/FreeSans12pt7b.h"
// Wemos D1 Mini
// #define TFT_CS D8
// #define TFT_RST D1
// #define TFT_DC D2
// ESP32-WROOM
// #define TFT_CS 5
// #define TFT_RST 4
// #define TFT_DC 2
// Farben
#define SCHWARZ 0x0000
#define WEISS 0xFFFF
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
// GFXcanvas-Objekt erstellen: Höhe 128 Pixel, Breite 160 Pixel
GFXcanvas1 Bereich(128, 160);
// analogen Pin anpassen
int Poti = A0;
// maximalen Wert des ADC anpassen
// ESP32: 4096, ESP8266: 1024
int ADCMax = 4096;
/*
Abstand der Markierung von der Mitte des TFTs
der ADC liefert keine lienear verlaufenden Werte
der Abstand kann angepasst werden
*/
int AbstandMarkierung = 20;
void setup()
{
// TFT starten
tft.initR(INITR_BLACKTAB);
// Rotation anpassen
tft.setRotation(0);
// schwarzer Hintergrund
tft.fillScreen(SCHWARZ);
}
void loop()
{
Bereich.fillScreen(SCHWARZ);
// analogen Wert lesen
int WertPoti = analogRead(Poti);
// analogen Wert anzeigen
Bereich.setFont(&FreeSans12pt7b);
Bereich.setCursor(10, 20);
Bereich.print(WertPoti);
// analogen Wert auf die Höhe des TFTs übertragen
int BalkenPoti = map(WertPoti, 0, ADCMax, 0, 160);
/*
bei gedrehtem Bildschirm wird der Balken von oben nach unten angezeigt
zuerest maximalen Wert weiß füllen
anschließend vom maximalen Wert den gemessenen Wert abziehen
und schwarz füllen
*/
Bereich.fillRect(80, 1, 30, 160, WEISS);
Bereich.fillRect(80, 1, 30, 160 - BalkenPoti, SCHWARZ);
Bereich.setCursor(30, tft.width() / 2 - AbstandMarkierung);
Bereich.setFont(&FreeSans9pt7b);
// je nach Wert ADCMax Zahlen anzeigen
if (ADCMax == 4096) Bereich.print("3000");
else Bereich.print("750");
Bereich.drawLine(tft.height() / 2, tft.width() / 2 - AbstandMarkierung, 50, tft.width() / 2 - AbstandMarkierung, WEISS);
Bereich.setCursor(30, tft.width() / 2 + AbstandMarkierung);
if (ADCMax == 4096) Bereich.print("2000");
else Bereich.print("500");
Bereich.drawLine(tft.height() / 2, tft.width() / 2 + AbstandMarkierung, 50, tft.width() / 2 + AbstandMarkierung, WEISS);
Bereich.setCursor(30, tft.width() / 2 + AbstandMarkierung * 3);
if (ADCMax == 4096) Bereich.print("1000");
else Bereich.print("250");
Bereich.drawLine(tft.height() / 2, tft.width() / 2 + AbstandMarkierung * 3, 50, tft.width() / 2 + AbstandMarkierung * 3, WEISS);
// GFXcanvas anzeigen
tft.drawBitmap(0, 0, Bereich.getBuffer(), Bereich.width(), Bereich.height(), WEISS, SCHWARZ);
}
Letzte Aktualisierung: