Skip to content

Technik Blog

Programmieren | Arduino | ESP32 | MicroPython | Python | Raspberry Pi | Raspberry Pi Pico

Menu
  • Smarthome
  • Gartenautomation
  • Mikrocontroller
    • Arduino
    • ESP32 & Co.
    • Calliope Mini
    • Raspberry Pi & Pico
  • Solo Mining
  • Deutsch
  • English
Menu

LDR auf dem Cheap Yellow Display auslesen – Schritt für Schritt erklärt

Veröffentlicht am 21. Februar 202620. Februar 2026 von Stefan Draeger

Das Cheap Yellow Display (ESP32-2432S028) besitzt auf der Vorderseite ein kleines, oft übersehenes Bauteil: einen Fotowiderstand – kurz LDR (Light Dependent Resistor).

Ein LDR verändert seinen Widerstand abhängig von der Umgebungshelligkeit. Je heller es ist, desto geringer wird sein Widerstand – in dunkler Umgebung steigt er entsprechend an. Über einen analogen Eingang des ESP32 lässt sich diese Änderung als Messwert erfassen.

LDR auf dem Cheap Yellow Display auslesen – Schritt für Schritt erklärt
Dieses Video auf YouTube ansehen.

In der Praxis kann man dieses Feature sinnvoll nutzen, um das Display automatisch an die Umgebungshelligkeit anzupassen. So bleibt der Bildschirminhalt bei direkter Sonneneinstrahlung gut ablesbar, während das Display in dunkler Umgebung gedimmt werden kann – ideal für Dashboard- oder Smart-Home-Projekte.

In diesem Beitrag zeige ich dir Schritt für Schritt, wie du den LDR auf dem Cheap Yellow Display ausliest und in deinem Projekt verwendest.

Cheap Yellow Display - ESP32-2432S028 - Vorderseite
Cheap Yellow Display – ESP32-2432S028 – Vorderseite
LDR am Cheap Yellow Display - ESP32-2432S028
LDR am Cheap Yellow Display – ESP32-2432S028

Hinweis:
Der LDR ist fest mit GPIO34 verbunden. GPIO34 und GPIO35 gehören beim ESP32 zu den reinen ADC-Eingängen und unterstützen keine OUTPUT-Funktionalität.

Inhaltsverzeichnis

  • Was ist ein LDR überhaupt?
  • LDR am Cheap Yellow Display auslesen
  • Anzeigen des Wertes vom LDR auf dem Display des ESP32-2432S028 (CYD)
    • Hinweis zur Programmierung mit LVGL
  • Dashboard-Helligkeit automatisch mit dem LDR regulieren
  • Fazit

Was ist ein LDR überhaupt?

Ein LDR (Light Dependent Resistor) ist ein lichtabhängiger Widerstand.
Er verändert seinen elektrischen Widerstand abhängig von der Helligkeit der Umgebung.

Das Prinzip ist einfach:

  • Viel Licht → niedriger Widerstand
  • Wenig Licht → hoher Widerstand

Der LDR selbst erzeugt kein Signal. Er ist lediglich ein variabler Widerstand.
Damit der ESP32 diesen Helligkeitswert erfassen kann, wird der LDR auf dem Board in einer Spannungsteiler-Schaltung betrieben.

Beim Cheap Yellow Display ist der LDR bereits fest mit GPIO34 (ADC1) verbunden. Eine zusätzliche Verdrahtung ist also nicht notwendig.

LDR am Cheap Yellow Display - ESP32-2432S028
LDR am Cheap Yellow Display – ESP32-2432S028

LDR am Cheap Yellow Display auslesen

Der LDR auf dem Cheap Yellow Display (ESP32-2432S028) ist fest mit GPIO34 (ADC1) verbunden.
Wir lesen den Helligkeitswert über den integrierten Analog-Digital-Wandler des ESP32 aus.

Der folgende Sketch gibt den Messwert nur dann aus, wenn sich dieser merklich ändert. Dadurch vermeiden wir unnötige serielle Ausgaben.

#define ldrPin 34 // LDR am GPIO34

// letzter gelesener Wert vom LDR
int lastLDRValue = 0;

// Zeitpunkt (in ms) des letzten Lesevorgangs
unsigned long lastRead = 0;

// Pause zwischen zwei Lesezyklen (in Millisekunden)
const int PAUSE = 50;

void setup() {
  // Start der seriellen Kommunikation mit 9600 Baud
  Serial.begin(9600);

  // ADC-Dämpfung setzen
  // siehe: https://docs.espressif.com/projects/arduino-esp32/en/latest/api/adc.html#analogsetattenuation
  analogSetAttenuation(ADC_0db);
}

void loop() {

  // aktuelle Millisekunden seit Start/Reset des Mikrocontrollers ermitteln
  unsigned long currentMillis = millis();

  // prüfen, ob die definierte Pause abgelaufen ist
  if (currentMillis > (lastRead + PAUSE)) {

    // Zeitpunkt des letzten Lesevorgangs aktualisieren
    lastRead = currentMillis;

    // analogen Wert vom LDR (GPIO34) einlesen
    int currentLDRValue = analogRead(ldrPin);

    // nur reagieren, wenn sich der Wert deutlich verändert hat (>= 5)
    if (abs(currentLDRValue - lastLDRValue) >= 5) {

      // Ausgabe des Messwertes über die serielle Schnittstelle
      // kann z.B. im seriellen Plotter als Liniendiagramm dargestellt werden
      Serial.println(currentLDRValue);

      // neuen Wert als Referenz speichern
      lastLDRValue = currentLDRValue;
    }
  }
}

Die gelesenen Werte können wir nun im seriellen Monitor der Arduino IDE auslesen oder auch im seriellen Plotter in einem Liniendiagram visualisieren lassen.

Ausgabe der Daten vom LDR im seriellen Monitor der Arduino IDE
Ausgabe der Daten vom LDR im seriellen Monitor der Arduino IDE
visualisieren der Daten vom LDR im seriellen Plotter der Arduino IDE
visualisieren der Daten vom LDR im seriellen Plotter der Arduino IDE

Anzeigen des Wertes vom LDR auf dem Display des ESP32-2432S028 (CYD)

Nachdem wir den LDR über analogRead() auslesen können, soll der Messwert nun direkt auf dem Display des Cheap Yellow Display angezeigt werden.

CYD - Anzeige des Wertes vom LDR auf dem Display
CYD – Anzeige des Wertes vom LDR auf dem Display
CYD - Anzeige des Wertes vom LDR auf dem Display - Sensor abgedunkelt
CYD – Anzeige des Wertes vom LDR auf dem Display – Sensor abgedunkelt

Hierfür verwende ich LVGL in Kombination mit der TFT_eSPI-Bibliothek.
Der aktuelle Helligkeitswert wird dabei:

  • als numerischer Wert angezeigt
  • zusätzlich visuell über einen Kreis dargestellt, dessen Helligkeit sich abhängig vom LDR-Wert verändert
#include <lvgl.h>
#include <TFT_eSPI.h>

#define TFT_HOR_RES 240
#define TFT_VER_RES 320

#define TFT_ROTATION LV_DISPLAY_ROTATION_270

#define DRAW_BUF_SIZE (TFT_HOR_RES * TFT_VER_RES / 10 * (LV_COLOR_DEPTH / 8))

uint32_t draw_buf[DRAW_BUF_SIZE / 4];

#define COLOR_BG lv_color_hex(0x000000)      // Hintergrund: Schwarz
#define COLOR_WHITE lv_color_hex(0xFFFFFF)   // Weiß
#define COLOR_YELLOW lv_color_hex(0xFDD835)  // Gelb

#define ldrPin 34

lv_obj_t *ldrValueLabel;
int lastLDRValue = 0;
unsigned long lastRead = 0;
const int PAUSE = 250;

lv_obj_t *ldrCircle;

void setup() {
  Serial.begin(9600);

  analogSetAttenuation(ADC_0db);

  lv_init();

  lv_display_t *disp = lv_tft_espi_create(
    TFT_HOR_RES,
    TFT_VER_RES,
    draw_buf,
    sizeof(draw_buf));
  lv_display_set_rotation(disp, TFT_ROTATION);
  lv_obj_t *scr = lv_screen_active();
  lv_obj_set_style_bg_color(scr, COLOR_BG, 0);
  lv_obj_set_style_bg_opa(scr, LV_OPA_COVER, 0);
  lv_obj_set_style_pad_all(scr, 12, 0);
  lv_obj_set_scrollbar_mode(scr, LV_SCROLLBAR_MODE_OFF);

  lv_obj_t *ldrDescLabel = lv_label_create(scr);
  lv_label_set_text(ldrDescLabel, "LDR");
  lv_obj_set_style_text_color(ldrDescLabel, COLOR_YELLOW, 0);
  lv_obj_set_style_text_font(ldrDescLabel, &lv_font_montserrat_28, 0);
  lv_obj_align(ldrDescLabel, LV_ALIGN_TOP_MID, 0, 0);

  ldrValueLabel = lv_label_create(scr);
  lv_label_set_text(ldrValueLabel, "0");
  lv_obj_set_style_text_color(ldrValueLabel, COLOR_WHITE, 0);
  lv_obj_set_style_text_font(ldrValueLabel, &lv_font_montserrat_28, 0);
  lv_obj_align(ldrValueLabel, LV_ALIGN_TOP_MID, 0, 50);

  ldrCircle = lv_obj_create(scr);
  lv_obj_set_size(ldrCircle, 80, 80);                     
  lv_obj_set_style_radius(ldrCircle, LV_RADIUS_CIRCLE, 0);  
  lv_obj_set_style_bg_color(ldrCircle, COLOR_YELLOW, 0);    
  lv_obj_set_style_border_width(ldrCircle, 0, 0);           
  lv_obj_set_style_bg_opa(ldrCircle, LV_OPA_0, 0);         
  lv_obj_align(ldrCircle, LV_ALIGN_CENTER, 0, 40);         
  setOpacity(0);
}

void setOpacity(int currentLDRValue) {
  int opa = map(currentLDRValue, 0, 1023, 255, 0);
  opa = constrain(opa, 0, 255);
  lv_obj_set_style_bg_opa(ldrCircle, (lv_opa_t)opa, 0);
}

void loop() {
  lv_tick_inc(5);
  lv_timer_handler();

  unsigned long currentMillis = millis();
  if (currentMillis > (lastRead + PAUSE)) {
    lastRead = currentMillis;
    int currentLDRValue = analogRead(ldrPin);
    if (abs(currentLDRValue - lastLDRValue) >= 5) {
      lastLDRValue = currentLDRValue;
      Serial.println(currentLDRValue);
      String s = String(currentLDRValue, DEC);
      lv_label_set_text(ldrValueLabel, s.c_str());
      setOpacity(currentLDRValue);
    }
  }

  delay(5);
}

Hinweis zur Programmierung mit LVGL

Die grundlegende Einrichtung des Cheap Yellow Display (ESP32-2432S028) in Kombination mit der LVGL-Bibliothek habe ich bereits ausführlich anhand eines kleinen Dashboards erklärt.

Dort zeige ich unter anderem:

  • Einrichtung von LVGL
  • Einbindung der TFT_eSPI-Bibliothek
  • Display-Rotation und Buffer-Konfiguration
  • Erstellen von Labels und grafischen Elementen
  • Grundlegende Struktur mit lv_timer_handler() und lv_tick_inc()

Falls du neu mit LVGL auf dem CYD arbeitest, empfehle ich dir zunächst einen Blick in meine YouTube-Playlist zu diesem Thema: ESP32 CYD Display mit LVGL programmieren – Komplettkurs

In diesem Beitrag konzentrieren wir uns ausschließlich auf das Auslesen und Visualisieren des LDR-Wertes.

Dashboard-Helligkeit automatisch mit dem LDR regulieren

Nachdem wir den LDR-Wert auslesen und visualisieren können, lässt sich dieser nun verwenden, um die Helligkeit eines Dashboards automatisch anzupassen.

Dashboard am CYD mit normaler Helligkeit
Dashboard am CYD mit normaler Helligkeit
Dashboard am CYD mit abgedunkelten LDR
Dashboard am CYD mit abgedunkelten LDR

In diesem Beispiel simulieren wir ein kleines Dashboard mit:

  • Temperaturwert
  • Statusanzeige
  • Hintergrundfläche

Je nach Umgebungshelligkeit wird dabei die gesamte Display-Helligkeit bzw. die Hintergrund-Deckkraft angepasst.

#include <lvgl.h>
#include <TFT_eSPI.h>

#define TFT_HOR_RES 240
#define TFT_VER_RES 320
#define TFT_ROTATION LV_DISPLAY_ROTATION_270
#define DRAW_BUF_SIZE (TFT_HOR_RES * TFT_VER_RES / 10 * (LV_COLOR_DEPTH / 8))

uint32_t draw_buf[DRAW_BUF_SIZE / 4];

#define COLOR_BG lv_color_hex(0x000000)
#define COLOR_WHITE lv_color_hex(0xFFFFFF)
#define COLOR_GREEN lv_color_hex(0x4CAF50)
#define COLOR_RED lv_color_hex(0xE53935)

// 3 Helligkeitsstufen
enum BrightnessLevel {
  BRIGHT,
  MEDIUM,
  DARK
};

// Farben-Array: [Helligkeit][Farbtyp]
lv_color_t colorSet[3][3] = {
  // BRIGHT
  {
    lv_color_hex(0xFFFFFF),  // Weiß
    lv_color_hex(0xFF0000),  // Rot
    lv_color_hex(0x00FF00)   // Grün
  },
  // MEDIUM
  {
    lv_color_hex(0xAAAAAA),  // Grau
    lv_color_hex(0xCC4444),  // Mittel-Rot
    lv_color_hex(0x44CC44)   // Mittel-Grün
  },
  // DARK
  {
    lv_color_hex(0x555555),  // Dunkelgrau
    lv_color_hex(0x662222),  // Dunkelrot
    lv_color_hex(0x226622)   // Dunkelgrün
  }
};

#define ldrPin 34

lv_obj_t *titleLabel;
lv_obj_t *tempLabel;
lv_obj_t *statusLabel;

unsigned long lastUpdate = 0;
const int UPDATE_INTERVAL = 1000;

BrightnessLevel getBrightnessLevel(int ldrValue) {

  if (ldrValue < 10) {
    return BRIGHT;
  } else if (ldrValue < 50) {
    return MEDIUM;
  } else {
    return DARK;
  }
}

void applyColorTheme(int ldrValue, bool statusWarning) {

  BrightnessLevel level = getBrightnessLevel(ldrValue);

  // Textfarbe Temperatur (Weiß/Grau)
  lv_obj_set_style_text_color(titleLabel, colorSet[level][0], 0);
  lv_obj_set_style_text_color(tempLabel, colorSet[level][0], 0);

  // Statusfarbe (Rot oder Grün)
  if (statusWarning) {
    lv_obj_set_style_text_color(statusLabel, colorSet[level][1], 0);
  } else {
    lv_obj_set_style_text_color(statusLabel, colorSet[level][2], 0);
  }
}

// ----------- Setup -----------
void setup() {

  Serial.begin(115200);
  analogSetAttenuation(ADC_0db);

  lv_init();

  lv_display_t *disp = lv_tft_espi_create(
    TFT_HOR_RES,
    TFT_VER_RES,
    draw_buf,
    sizeof(draw_buf));

  lv_display_set_rotation(disp, TFT_ROTATION);

  lv_obj_t *scr = lv_screen_active();
  lv_obj_set_style_bg_color(scr, COLOR_BG, 0);
  lv_obj_set_style_bg_opa(scr, LV_OPA_COVER, 0);

  // Titel
  titleLabel = lv_label_create(scr);
  lv_label_set_text(titleLabel, "DASHBOARD");
  lv_obj_set_style_text_color(titleLabel, COLOR_WHITE, 0);
  lv_obj_set_style_text_font(titleLabel, &lv_font_montserrat_28, 0);
  lv_obj_align(titleLabel, LV_ALIGN_TOP_MID, 0, 10);

  // Temperatur
  tempLabel = lv_label_create(scr);
  lv_label_set_text(tempLabel, "-- °C");
  lv_obj_set_style_text_color(tempLabel, COLOR_WHITE, 0);
  lv_obj_set_style_text_font(tempLabel, &lv_font_montserrat_28, 0);
  lv_obj_align(tempLabel, LV_ALIGN_CENTER, 0, -20);

  // Status
  statusLabel = lv_label_create(scr);
  lv_label_set_text(statusLabel, "--");
  lv_obj_set_style_text_font(statusLabel, &lv_font_montserrat_28, 0);
  lv_obj_align(statusLabel, LV_ALIGN_CENTER, 0, 30);
}

// ----------- Loop -----------
void loop() {

  lv_tick_inc(5);
  lv_timer_handler();

  // Dashboard-Werte aktualisieren
  if (millis() - lastUpdate > UPDATE_INTERVAL) {
    lastUpdate = millis();

    int ldrValue = analogRead(ldrPin);

    int temperature = random(20, 35);
    bool warn = temperature > 30;

    String tempText = String(temperature) + " °C";
    lv_label_set_text(tempLabel, tempText.c_str());

    lv_label_set_text(statusLabel, warn ? "WARN" : "OK");

    applyColorTheme(ldrValue, warn);
  }


  delay(5);
}

Fazit

Das Auslesen eines LDR – oder generell anderer analoger Sensoren, die über einen Spannungsteiler betrieben werden (z. B. ein NTC-Widerstand) – ist mit dem ESP32 denkbar einfach. Im Grunde benötigt es nur wenige Zeilen Code, um einen stabilen Messwert über den ADC einzulesen und weiterzuverarbeiten.

Der integrierte LDR auf dem Cheap Yellow Display ist daher ein kleines, aber praktisches Feature, das sich ohne zusätzliche Hardware direkt nutzen lässt. Besonders für Projekte mit automatischer Helligkeitsanpassung oder einfachen Umgebungslicht-Erkennungen bietet sich dieser Sensor an.

Deutlich umfangreicher wird der Code erst dann, wenn der Messwert grafisch auf dem Display visualisiert wird. Durch den Einsatz von LVGL wächst das Projekt spürbar an – was jedoch der Flexibilität und den Gestaltungsmöglichkeiten geschuldet ist. Mit einem einfachen OLED-Display über I2C ließe sich die reine Anzeige des Messwertes deutlich schlanker umsetzen.

Das Cheap Yellow Display bietet hier jedoch den Vorteil, dass sich Sensorwerte nicht nur anzeigen, sondern auch ansprechend visualisieren lassen – etwa durch grafische Elemente wie Balken, Kreise oder dynamische Oberflächen.

Letzte Aktualisierung am: 20. Februar 2026

Foto von Stefan Draeger
Über den Autor

Stefan Draeger — Entwickler & Tech-Blogger

Ich zeige praxisnah, wie du Projekte mit Arduino, ESP32 und Smarthome-Komponenten umsetzt – Schritt für Schritt, mit Code und Schaltplänen.

Mehr Artikel von Stefan →

Schreibe einen Kommentar Antwort abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Fragen oder Feedback?

Du hast eine Idee, brauchst Hilfe oder möchtest Feedback loswerden?
Support-Ticket erstellen

Newsletter abonnieren

Bleib auf dem Laufenden: Erhalte regelmäßig Updates zu neuen Projekten, Tutorials und Tipps rund um Arduino, ESP32 und mehr – direkt in dein Postfach.

Jetzt Newsletter abonnieren

Unterstütze meinen Blog

Wenn dir meine Inhalte gefallen, freue ich mich über deine Unterstützung auf Tipeee.
So hilfst du mit, den Blog am Leben zu halten und neue Beiträge zu ermöglichen.

draeger-it.blog auf Tipeee unterstützen

Vielen Dank für deinen Support!
– Stefan Draeger

Kategorien

Tools

  • QR-Code Generator
  • Unix-Zeitstempel-Rechner
  • ASCII Tabelle
  • Spannung, Strom, Widerstand und Leistung berechnen
  • Widerstandsrechner
  • 8×8 LED Matrix Tool
  • 8×16 LED Matrix Modul von Keyestudio
  • 16×16 LED Matrix – Generator

Links

Blogverzeichnis Bloggerei.de TopBlogs.de das Original - Blogverzeichnis | Blog Top Liste Blogverzeichnis trusted-blogs.com

Stefan Draeger
Königsberger Str. 13
38364 Schöningen
Tel.: 015565432686
E-Mail: info@draeger-it.blog

Folge mir auf

link zu Fabook
link zu LinkedIn
link zu YouTube
link zu TikTok
link zu Pinterest
link zu Instagram
  • Impressum
  • Datenschutzerklärung
  • Disclaimer
  • Cookie-Richtlinie (EU)
©2026 Technik Blog | Built using WordPress and Responsive Blogily theme by Superb
Cookie-Zustimmung verwalten
Wir verwenden Technologien wie Cookies, um Geräteinformationen zu speichern und/oder darauf zuzugreifen. Wir tun dies, um das Surferlebnis zu verbessern und um personalisierte Werbung anzuzeigen. Wenn Sie diesen Technologien zustimmen, können wir Daten wie das Surfverhalten oder eindeutige IDs auf dieser Website verarbeiten. Wenn Sie Ihre Zustimmung nicht erteilen oder zurückziehen, können bestimmte Funktionen beeinträchtigt werden.
Funktional Immer aktiv
Die technische Speicherung oder der Zugang ist unbedingt erforderlich für den rechtmäßigen Zweck, die Nutzung eines bestimmten Dienstes zu ermöglichen, der vom Teilnehmer oder Nutzer ausdrücklich gewünscht wird, oder für den alleinigen Zweck, die Übertragung einer Nachricht über ein elektronisches Kommunikationsnetz durchzuführen.
Vorlieben
Die technische Speicherung oder der Zugriff ist für den rechtmäßigen Zweck der Speicherung von Präferenzen erforderlich, die nicht vom Abonnenten oder Benutzer angefordert wurden.
Statistiken
Die technische Speicherung oder der Zugriff, der ausschließlich zu statistischen Zwecken erfolgt. Die technische Speicherung oder der Zugriff, der ausschließlich zu anonymen statistischen Zwecken verwendet wird. Ohne eine Vorladung, die freiwillige Zustimmung deines Internetdienstanbieters oder zusätzliche Aufzeichnungen von Dritten können die zu diesem Zweck gespeicherten oder abgerufenen Informationen allein in der Regel nicht dazu verwendet werden, dich zu identifizieren.
Marketing
Die technische Speicherung oder der Zugriff ist erforderlich, um Nutzerprofile zu erstellen, um Werbung zu versenden oder um den Nutzer auf einer Website oder über mehrere Websites hinweg zu ähnlichen Marketingzwecken zu verfolgen.
  • Optionen verwalten
  • Dienste verwalten
  • Verwalten von {vendor_count}-Lieferanten
  • Lese mehr über diese Zwecke
Einstellungen anzeigen
  • {title}
  • {title}
  • {title}