
Ja, kostet auch in der neusten Form aktuell 50,- EUR........(Preise haben seit kurzen stark angezogen)Feather M4 Express — was realistisch ist
Der ADC im Adafruit Feather M4 Express kann zwar theoretisch relativ schnell sampeln, aber:
stabile 12-Bit-Werte bei sehr hohen Sampleraten sind schwierig
FFT + Display + DMA gleichzeitig kostet Leistung
RAM wird schnell knapp
Realistisch:
sehr gut bis 20 kHz
brauchbar bis ~40 kHz
experimentell bis ~80 kHz
100 kHz eher grenzwertig
Bessere Plattform für 100 kHz FFT
Wenn dein Ziel wirklich ist:
„Ich möchte Frequenzen bis 100 kHz sichtbar machen“ dann wäre deutlich besser:
Teensy 4.1
externer ADC
DMA
CMSIS DSP FFT
Der Teensy 4.1 schafft locker:
500 kHz Sampling
große FFTs
TFT-Ausgabe in Echtzeit
Das ist eine ganz andere Liga als der Feather M4.
Sehr schön und hier nun der verwendete Code:ESP32 Mandelbrot Benchmark – Erklärung
Dieser Sketch verwandelt einen einfachen ESP32 Mikrocontroller in einen kleinen Echtzeit-Grafikcomputer.
Auf einem ST7789 IPS-Display wird kontinuierlich ein sogenanntes Mandelbrot-Fraktal berechnet und dargestellt.
Dabei berechnet der ESP32 für jeden einzelnen Bildpunkt mathematisch:
welche Farbe der Pixel bekommt
wie komplex die Struktur ist
und wie schnell das Ganze berechnet werden kann.
Der Sketch dient gleichzeitig als:
Grafikdemo
CPU-Benchmark
Mathematikvisualisierung
Vergleichstest zwischen Mikrocontrollern
Später kann derselbe Sketch auf anderen Prozessoren laufen, z.B. auf einem Teensy 4.1.
Dadurch lässt sich direkt vergleichen:
welcher Prozessor schneller rechnet
höhere FPS erreicht
mehr Pixel pro Sekunde berechnet
Was ist das Mandelbrot-Fraktal?
Das Mandelbrot-Fraktal ist eines der berühmtesten mathematischen Bilder überhaupt.
Es wurde vom Mathematiker:
Benoît Mandelbrot
bekannt gemacht.
Das Besondere:
Das Bild entsteht rein aus Mathematik
Keine Grafikdatei wird geladen
Jeder Pixel wird live berechnet
Warum ist das so faszinierend?
Wenn man immer tiefer hineinzoomt:
erscheinen neue Muster
Spiralen entstehen
kleine Kopien des Gesamtbildes tauchen auf
Details wiederholen sich unendlich
Das nennt man ein:
Fractal
Ein Fraktal besitzt Strukturen, die sich selbst ähnlich bleiben — egal wie tief man hineinzoomt.
Was macht der Sketch genau?
1. Startbildschirm
Beim Einschalten zeigt das Display:
ESP32
Mandelbrot Rennen
Zoom Benchmark
Danach wird der Bildschirm sanft ausgeblendet.
2. Live-Berechnung des Fraktals
Der ESP32 berechnet anschließend:
jeden Pixel
jede Farbe
jede Zoomstufe
in Echtzeit.
Dabei bewegt sich die Kamera immer tiefer in das Fraktal hinein.
3. Benchmark-Anzeige
Oben auf dem Bildschirm erscheinen Live-Daten:
Anzeige Bedeutung
FPS Bilder pro Sekunde
Fxx aktuelle Framenummer
Zoom aktuelle Zoomstufe
kPix/s berechnete Pixel pro Sekunde
Damit sieht man direkt:
wie stark der Prozessor ausgelastet ist
wie schnell die Berechnung erfolgt
wann der Prozessor an seine Grenzen kommt
Warum ist das ein guter Benchmark?
Das Mandelbrot-Fraktal belastet einen Mikrocontroller stark, weil:
sehr viele mathematische Berechnungen nötig sind
jeder Pixel einzeln berechnet wird
Fließkommaoperationen benötigt werden
das Display permanent aktualisiert wird
Dadurch eignet sich der Sketch hervorragend zum Vergleich von:
ESP32
Teensy
STM32
Raspberry Pi Pico
anderen Mikrocontrollern
Technische Besonderheiten des Sketches
Der Sketch verwendet:
Hardware-SPI für schnellen Displaytransfer
Zeilenbuffer für effizientes Zeichnen
PWM-Fading für weiche Übergänge
Live-HUD mit Benchmarkdaten
optimierte Fraktalberechnung
Dadurch läuft die Demo überraschend flüssig — selbst auf einem kleinen ESP32.
Warum sieht das so beeindruckend aus?
Das Display zeigt:
mathematische Kunst
technische Leistung
Echtzeitberechnung
Farbanimation
gleichzeitig.
Die kleinen IPS-Displays mit den runden Ecken verleihen dem Projekt zusätzlich einen fast professionellen Geräte-Look.
Fazit
Dieser Sketch ist:
Mathematik
Grafikdemo
Benchmark
Mikrocontroller-Projekt
Echtzeitvisualisierung
in einem einzigen kleinen System.
Und das alles läuft vollständig auf einem kleinen ESP32-Mikrocontroller
Code: Alles auswählen
/*
========================================================
ESP32 WROOM Mandelbrot Benchmark V1.1
Display: ST7789 280x240 IPS
Library: TFT_eSPI
Ruesseltechnik 13.05.2026
========================================================
VERDRAHTUNG
========================================================
DISPLAY -> ESP32
GND -> GND
VCC -> 3.3V
SCL -> GPIO 18 // SPI Clock
SDA -> GPIO 23 // SPI MOSI
RES -> GPIO 4
DC -> GPIO 2
CS -> GPIO 5
BLK -> GPIO 15 // Backlight PWM
========================================================
TFT_eSPI User_Setup.h
========================================================
#define ST7789_DRIVER
#define TFT_WIDTH 280
#define TFT_HEIGHT 240
#define TFT_MOSI 23
#define TFT_SCLK 18
#define TFT_CS 5
#define TFT_DC 2
#define TFT_RST 4
#define LOAD_GLCD
#define LOAD_FONT2
#define SPI_FREQUENCY 40000000
========================================================
*/
#include <Arduino.h>
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
// ========================================
// Backlight
// ========================================
#define TFT_BL 15
// ========================================
// Displaygroesse
// ========================================
const int WIDTH = 280;
const int HEIGHT = 240;
// ========================================
// HUD
// ========================================
const int HUD_HEIGHT = 60;
// ========================================
// Mandelbrot
// ========================================
const int MAX_ITER = 64;
// Zoom
float zoom = 1.0;
float zoomSpeed = 1.05;
// ========================================
// Hotspots
// ========================================
const int NUM_SPOTS = 4;
float spotX[NUM_SPOTS] =
{
-0.77568377,
-0.74364388703,
-0.1011,
-0.7453
};
float spotY[NUM_SPOTS] =
{
0.13646737,
0.13182590421,
0.9563,
0.1127
};
int currentSpot = 0;
float centerX = spotX[0];
float centerY = spotY[0];
// ========================================
// Statistik
// ========================================
float fps = 0.0;
float pixelsPerSecond = 0.0;
unsigned long frameTime = 0;
unsigned long frameCount = 0;
// ========================================
// Zeilenbuffer
// ========================================
uint16_t lineBuffer[WIDTH];
// ========================================
// SETUP
// ========================================
void setup()
{
Serial.begin(115200);
// PWM Backlight
ledcAttach(TFT_BL, 5000, 8);
// Volle Helligkeit
ledcWrite(TFT_BL, 255);
// Display starten
tft.init();
// Orientierung
tft.setRotation(1);
// Bildschirm schwarz
tft.fillScreen(TFT_BLACK);
// ====================================
// Startscreen
// ====================================
drawCenteredText("ESP32", 45, TFT_GREEN);
drawCenteredText("Mandelbrot", 75, TFT_GREEN);
drawCenteredText("Rennen", 105, TFT_GREEN);
drawCenteredText("Zoom Benchmark", 150, TFT_WHITE);
delay(2000);
// Sanft abdunkeln
fadeOut();
// Bildschirm loeschen
tft.fillScreen(TFT_BLACK);
// Sanft einblenden
fadeIn();
}
// ========================================
// LOOP
// ========================================
void loop()
{
unsigned long startMicros = micros();
renderMandelbrot();
frameTime = micros() - startMicros;
fps = 1000000.0 / frameTime;
pixelsPerSecond =
(float)(WIDTH * HEIGHT) * fps;
drawHUD();
frameCount++;
// Zoom vergroessern
zoom *= zoomSpeed;
// ====================================
// Naechster Hotspot
// ====================================
if (zoom > 5000.0)
{
// Ausblenden
fadeOut();
// Naechsten Spot waehlen
currentSpot++;
if (currentSpot >= NUM_SPOTS)
{
currentSpot = 0;
}
centerX = spotX[currentSpot];
centerY = spotY[currentSpot];
// Zoom reset
zoom = 1.0;
// Bildschirm schwarz
tft.fillScreen(TFT_BLACK);
// Einblenden
fadeIn();
}
}
// ========================================
// Mandelbrot Rendern
// ========================================
void renderMandelbrot()
{
float scale = 3.0 / zoom;
for (int py = HUD_HEIGHT; py < HEIGHT; py++)
{
float renderHeight = HEIGHT - HUD_HEIGHT;
float y0 =
centerY +
((float)(py - HUD_HEIGHT) -
renderHeight / 2.0) *
scale / renderHeight;
for (int px = 0; px < WIDTH; px++)
{
float x0 =
centerX +
((float)px - WIDTH / 2.0) *
scale / WIDTH;
float x = 0.0;
float y = 0.0;
int iter = 0;
while ((x * x + y * y <= 4.0) &&
(iter < MAX_ITER))
{
float xtemp =
x * x - y * y + x0;
y = 2.0 * x * y + y0;
x = xtemp;
iter++;
}
uint16_t color;
if (iter >= MAX_ITER)
{
color = TFT_BLACK;
}
else
{
uint8_t r = (iter * 9) % 255;
uint8_t g = (iter * 7) % 255;
uint8_t b = (iter * 5) % 255;
color = tft.color565(r, g, b);
}
lineBuffer[px] = color;
}
// Ganze Zeile senden
tft.pushImage(
0,
py,
WIDTH,
1,
lineBuffer
);
}
}
// ========================================
// HUD
// ========================================
void drawHUD()
{
// HUD Hintergrund
tft.fillRect(
0,
0,
WIDTH,
HUD_HEIGHT,
TFT_BLACK
);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextSize(2);
char line1[64];
char line2[64];
sprintf(line1,
"ESP32 %.1fFPS F%lu",
fps,
frameCount);
sprintf(line2,
"Z%.1fx %lukPix/s",
zoom,
(unsigned long)(pixelsPerSecond / 1000.0));
int w1 = strlen(line1) * 12;
int w2 = strlen(line2) * 12;
// Zentriert
tft.setCursor((WIDTH - w1) / 2, 10);
tft.print(line1);
tft.setCursor((WIDTH - w2) / 2, 32);
tft.print(line2);
}
// ========================================
// Zentrierter Text
// ========================================
void drawCenteredText(
const char* text,
int y,
uint16_t color)
{
tft.setTextColor(color, TFT_BLACK);
tft.setTextSize(2);
int w = strlen(text) * 12;
tft.setCursor((WIDTH - w) / 2, y);
tft.print(text);
}
// ========================================
// Fade Out
// ========================================
void fadeOut()
{
for (int i = 255; i >= 0; i--)
{
ledcWrite(TFT_BL, i);
delay(15);
}
}
// ========================================
// Fade In
// ========================================
void fadeIn()
{
for (int i = 0; i <= 255; i++)
{
ledcWrite(TFT_BL, i);
delay(9);
}
}
Den Rest des Tages habe ich dann benötigt alle Änderungen in meinen WIN11 System wieder rückgängig zu machen ;-)Wir sehen nicht immer dieselben Datenquellen.
Du arbeitest mit:
echter Live-Verbindung
deinem Netzwerk
deinem Browser
direktem Serverzugriff.
Ich arbeite oft mit:
Suchindexen
gecachten Informationen
aggregierten Daten
bereits bekannten Webinhalten.
Code: Alles auswählen
/*
========================================================
TEENSY 4.1 Mandelbrot Benchmark V1.2
Ruesseltechnik 14.05.2026
Display: ST7789 280x240 IPS
Library: TFT_eSPI
========================================================
TEENSY VERDRAHTUNG
========================================================
DISPLAY -> TEENSY 4.1
GND -> GND
VCC -> 3.3V
SCL -> PIN 13
SDA -> PIN 11
RES -> PIN 8
DC -> PIN 7
CS -> PIN 10
BLK -> 3.3V
TASTER
Eine Seite -> GND
Andere Seite -> PIN 2
========================================================
TFT_eSPI User_Setup.h
========================================================
#define USER_SETUP_INFO "Teensy41 ST7789"
// Display Driver
#define ST7789_DRIVER
// Displaygroesse
#define TFT_WIDTH 240
#define TFT_HEIGHT 280
#define CGRAM_OFFSET
// Teensy 4.1 SPI Pins
#define TFT_MOSI 11
#define TFT_SCLK 13
#define TFT_CS 10
#define TFT_DC 7
#define TFT_RST 8
// Backlight optional
#define TFT_BL 3
#define TFT_BACKLIGHT_ON HIGH
// SPI Geschwindigkeit
#define SPI_FREQUENCY 40000000
// Fonts
#define LOAD_GLCD
#define LOAD_FONT2
#define LOAD_FONT4
#define LOAD_GFXFF
// Smooth Fonts optional
#define SMOOTH_FONT
========================================================
*/
#include <Arduino.h>
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
// ========================================
// Starttaster
// ========================================
#define BUTTON_PIN 2
// ========================================
// Displaygroesse
// ========================================
const int WIDTH = 280;
const int HEIGHT = 240;
// ========================================
// HUD
// ========================================
const int HUD_HEIGHT = 60;
// ========================================
// Mandelbrot
// ========================================
const int MAX_ITER = 64;
// Zoom
float zoom = 1.0;
float zoomSpeed = 1.05;
// ========================================
// Hotspots
// ========================================
const int NUM_SPOTS = 4;
float spotX[NUM_SPOTS] =
{
-0.77568377,
-0.74364388703,
-0.1011,
-0.7453
};
float spotY[NUM_SPOTS] =
{
0.13646737,
0.13182590421,
0.9563,
0.1127
};
int currentSpot = 0;
float centerX = spotX[0];
float centerY = spotY[0];
// ========================================
// Statistik
// ========================================
float fps = 0.0;
float pixelsPerSecond = 0.0;
unsigned long frameTime = 0;
unsigned long frameCount = 0;
// ========================================
// Zeilenbuffer
// ========================================
uint16_t lineBuffer[WIDTH];
// ========================================
// Vorwaertsdeklarationen
// ========================================
void renderMandelbrot();
void drawHUD();
void drawCenteredText(
const char* text,
int y,
uint16_t color);
// ========================================
// SETUP
// ========================================
void setup()
{
Serial.begin(115200);
// Starttaster
pinMode(BUTTON_PIN, INPUT_PULLUP);
// Display starten
tft.init();
// Orientierung
tft.setRotation(1);
// Bildschirm schwarz
tft.fillScreen(TFT_BLACK);
// ====================================
// Startscreen
// ====================================
drawCenteredText("TEENSY 4.1", 45, TFT_GREEN);
drawCenteredText("READY", 95, TFT_WHITE);
drawCenteredText("Press Start", 130, TFT_WHITE);
// ====================================
// Warten auf Taster
// ====================================
while (digitalRead(BUTTON_PIN) == HIGH)
{
delay(10);
}
// Kleine Entprellung
delay(30);
// Sofort starten
tft.fillScreen(TFT_BLACK);
}
// ========================================
// LOOP
// ========================================
void loop()
{
unsigned long startMicros = micros();
renderMandelbrot();
frameTime = micros() - startMicros;
fps = 1000000.0 / frameTime;
pixelsPerSecond =
(float)(WIDTH * HEIGHT) * fps;
drawHUD();
frameCount++;
// Zoom vergroessern
zoom *= zoomSpeed;
// ====================================
// Naechster Hotspot
// ====================================
if (zoom > 5000.0)
{
// Naechsten Spot waehlen
currentSpot++;
if (currentSpot >= NUM_SPOTS)
{
currentSpot = 0;
}
centerX = spotX[currentSpot];
centerY = spotY[currentSpot];
// Zoom reset
zoom = 1.0;
// Bildschirm schwarz
tft.fillScreen(TFT_BLACK);
}
}
// ========================================
// Mandelbrot Rendern
// ========================================
void renderMandelbrot()
{
float scale = 3.0 / zoom;
float renderHeight = HEIGHT - HUD_HEIGHT;
for (int py = HUD_HEIGHT; py < HEIGHT; py++)
{
float y0 =
centerY +
((float)(py - HUD_HEIGHT) -
renderHeight / 2.0) *
scale / renderHeight;
for (int px = 0; px < WIDTH; px++)
{
float x0 =
centerX +
((float)px - WIDTH / 2.0) *
scale / WIDTH;
float x = 0.0;
float y = 0.0;
int iter = 0;
while ((x * x + y * y <= 4.0) &&
(iter < MAX_ITER))
{
float xtemp =
x * x - y * y + x0;
y = 2.0 * x * y + y0;
x = xtemp;
iter++;
}
uint16_t color;
if (iter >= MAX_ITER)
{
color = TFT_BLACK;
}
else
{
uint8_t r = (iter * 9) % 255;
uint8_t g = (iter * 7) % 255;
uint8_t b = (iter * 5) % 255;
color = tft.color565(r, g, b);
}
lineBuffer[px] = color;
}
// Ganze Zeile senden
tft.pushImage(
0,
py,
WIDTH,
1,
lineBuffer
);
}
}
// ========================================
// HUD
// ========================================
void drawHUD()
{
// HUD Hintergrund
tft.fillRect(
0,
0,
WIDTH,
HUD_HEIGHT,
TFT_BLACK
);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextSize(2);
char line1[64];
char line2[64];
sprintf(line1,
"TEENSY %.1fFPS F%lu",
fps,
frameCount);
sprintf(line2,
"Z%.1fx %lukPix/s",
zoom,
(unsigned long)(pixelsPerSecond / 1000.0));
int w1 = strlen(line1) * 12;
int w2 = strlen(line2) * 12;
// Zentriert
tft.setCursor((WIDTH - w1) / 2, 10);
tft.print(line1);
tft.setCursor((WIDTH - w2) / 2, 32);
tft.print(line2);
}
// ========================================
// Zentrierter Text
// ========================================
void drawCenteredText(
const char* text,
int y,
uint16_t color)
{
tft.setTextColor(color, TFT_BLACK);
tft.setTextSize(2);
int w = strlen(text) * 12;
tft.setCursor((WIDTH - w) / 2, y);
tft.print(text);
}
Code: Alles auswählen
/*
========================================================
ESP32 WROOM Mandelbrot Benchmark V1.2
Ruesseltechnik 14.05.2026
Display: ST7789 280x240 IPS
Library: TFT_eSPI
========================================================
VERDRAHTUNG
========================================================
DISPLAY -> ESP32
GND -> GND
VCC -> 3.3V
SCL -> GPIO 18 // SPI Clock
SDA -> GPIO 23 // SPI MOSI
RES -> GPIO 4
DC -> GPIO 2
CS -> GPIO 5
BLK -> GPIO 15 // Backlight PWM
TASTER
Eine Seite -> GND
Andere Seite -> GPIO 27
========================================================
TFT_eSPI User_Setup.h
========================================================
#define ST7789_DRIVER
#define TFT_WIDTH 280
#define TFT_HEIGHT 240
#define TFT_MOSI 23
#define TFT_SCLK 18
#define TFT_CS 5
#define TFT_DC 2
#define TFT_RST 4
#define LOAD_GLCD
#define LOAD_FONT2
#define SPI_FREQUENCY 40000000
========================================================
*/
#include <Arduino.h>
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
// ========================================
// Backlight
// ========================================
#define TFT_BL 15
// ========================================
// Starttaster
// ========================================
#define BUTTON_PIN 27
// ========================================
// Displaygroesse
// ========================================
const int WIDTH = 280;
const int HEIGHT = 240;
// ========================================
// HUD
// ========================================
const int HUD_HEIGHT = 60;
// ========================================
// Mandelbrot
// ========================================
const int MAX_ITER = 64;
// Zoom
float zoom = 1.0;
float zoomSpeed = 1.05;
// ========================================
// Hotspots
// ========================================
const int NUM_SPOTS = 4;
float spotX[NUM_SPOTS] =
{
-0.77568377,
-0.74364388703,
-0.1011,
-0.7453
};
float spotY[NUM_SPOTS] =
{
0.13646737,
0.13182590421,
0.9563,
0.1127
};
int currentSpot = 0;
float centerX = spotX[0];
float centerY = spotY[0];
// ========================================
// Statistik
// ========================================
float fps = 0.0;
float pixelsPerSecond = 0.0;
unsigned long frameTime = 0;
unsigned long frameCount = 0;
// ========================================
// Zeilenbuffer
// ========================================
uint16_t lineBuffer[WIDTH];
// ========================================
// SETUP
// ========================================
void setup()
{
Serial.begin(115200);
// Starttaster
pinMode(BUTTON_PIN, INPUT_PULLUP);
// PWM Backlight
ledcAttach(TFT_BL, 5000, 8);
// Volle Helligkeit
ledcWrite(TFT_BL, 255);
// Display starten
tft.init();
// Orientierung
tft.setRotation(1);
// Bildschirm schwarz
tft.fillScreen(TFT_BLACK);
// ====================================
// Startscreen
// ====================================
drawCenteredText("ESP32", 45, TFT_GREEN);
drawCenteredText("READY", 95, TFT_WHITE);
drawCenteredText("Press Start", 130, TFT_WHITE);
// ====================================
// Warten auf Taster
// ====================================
while (digitalRead(BUTTON_PIN) == HIGH)
{
delay(10);
}
// Kleine Entprellung
delay(30);
// Sofort starten
tft.fillScreen(TFT_BLACK);
}
// ========================================
// LOOP
// ========================================
void loop()
{
unsigned long startMicros = micros();
renderMandelbrot();
frameTime = micros() - startMicros;
fps = 1000000.0 / frameTime;
pixelsPerSecond =
(float)(WIDTH * HEIGHT) * fps;
drawHUD();
frameCount++;
// Zoom vergroessern
zoom *= zoomSpeed;
// ====================================
// Naechster Hotspot
// ====================================
if (zoom > 5000.0)
{
// Ausblenden
fadeOut();
// Naechsten Spot waehlen
currentSpot++;
if (currentSpot >= NUM_SPOTS)
{
currentSpot = 0;
}
centerX = spotX[currentSpot];
centerY = spotY[currentSpot];
// Zoom reset
zoom = 1.0;
// Bildschirm schwarz
tft.fillScreen(TFT_BLACK);
// Einblenden
fadeIn();
}
}
// ========================================
// Mandelbrot Rendern
// ========================================
void renderMandelbrot()
{
float scale = 3.0 / zoom;
float renderHeight = HEIGHT - HUD_HEIGHT;
for (int py = HUD_HEIGHT; py < HEIGHT; py++)
{
float y0 =
centerY +
((float)(py - HUD_HEIGHT) -
renderHeight / 2.0) *
scale / renderHeight;
for (int px = 0; px < WIDTH; px++)
{
float x0 =
centerX +
((float)px - WIDTH / 2.0) *
scale / WIDTH;
float x = 0.0;
float y = 0.0;
int iter = 0;
while ((x * x + y * y <= 4.0) &&
(iter < MAX_ITER))
{
float xtemp =
x * x - y * y + x0;
y = 2.0 * x * y + y0;
x = xtemp;
iter++;
}
uint16_t color;
if (iter >= MAX_ITER)
{
color = TFT_BLACK;
}
else
{
uint8_t r = (iter * 9) % 255;
uint8_t g = (iter * 7) % 255;
uint8_t b = (iter * 5) % 255;
color = tft.color565(r, g, b);
}
lineBuffer[px] = color;
}
// Ganze Zeile senden
tft.pushImage(
0,
py,
WIDTH,
1,
lineBuffer
);
}
}
// ========================================
// HUD
// ========================================
void drawHUD()
{
// HUD Hintergrund
tft.fillRect(
0,
0,
WIDTH,
HUD_HEIGHT,
TFT_BLACK
);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextSize(2);
char line1[64];
char line2[64];
sprintf(line1,
"ESP32 %.1fFPS F%lu",
fps,
frameCount);
sprintf(line2,
"Z%.1fx %lukPix/s",
zoom,
(unsigned long)(pixelsPerSecond / 1000.0));
int w1 = strlen(line1) * 12;
int w2 = strlen(line2) * 12;
// Zentriert
tft.setCursor((WIDTH - w1) / 2, 10);
tft.print(line1);
tft.setCursor((WIDTH - w2) / 2, 32);
tft.print(line2);
}
// ========================================
// Zentrierter Text
// ========================================
void drawCenteredText(
const char* text,
int y,
uint16_t color)
{
tft.setTextColor(color, TFT_BLACK);
tft.setTextSize(2);
int w = strlen(text) * 12;
tft.setCursor((WIDTH - w) / 2, y);
tft.print(text);
}
// ========================================
// Fade Out
// ========================================
void fadeOut()
{
for (int i = 255; i >= 0; i--)
{
ledcWrite(TFT_BL, i);
delay(15);
}
}
// ========================================
// Fade In
// ========================================
void fadeIn()
{
for (int i = 0; i <= 255; i++)
{
ledcWrite(TFT_BL, i);
delay(9);
}
}

