ESP32 CYD 2.8" Dashboard (Wetter, Aktien & Mond)

ESP32 CYD 2.8" Dashboard (Wetter, Aktien & Mond)

$5.99
Sale price  $5.99 Regular price 
Skip to product information
ESP32 CYD 2.8" Dashboard (Wetter, Aktien & Mond)

ESP32 CYD 2.8" Dashboard (Wetter, Aktien & Mond)

$5.99
Sale price  $5.99 Regular price 
In Stock. Ready to order — printed when you buy.
Fast fulfillment. Ships after quality check. Trackable delivery.
Easy returns. Shop with confidence — see our return policy.
Secure checkout. Encrypted payment powered by Shopify.

📱 ESP32 CYD 2.8" Smart Dashboard (Wetter, Aktien & Mond)

 

Mit Webflasher, kein Programieren oder umständlich Bibliotheken laden:  Smart Dashboard Installer

 

Dieses Projekt verwandelt das preiswerte ESP32-2432S028R (auch bekannt als "Cheap Yellow Display" oder CYD) in ein schickes, funktionales Informations-Dashboard für deinen Schreibtisch.

 

 

✨ Hauptmerkmale:

  • Präzise Uhrzeit: Automatische Synchronisierung über NTP (CET/CEST mit Sommerzeit).
  • Live Wetter: Aktuelle Daten über Open-Meteo (kein API-Key erforderlich!).
  • Mondphasen: Integrierter mathematischer Algorithmus für die aktuelle Mondphase.
  • Finanz-Ticker: Live-Kurse für DAX, DOW Jones, VIX und Bitcoin (€) (via Yahoo Finance & Coinbase).
  • Einfaches Setup: Dank WiFiManager musst du deine WLAN-Daten nicht im Code festschreiben. Das Gerät erstellt beim ersten Start einen Hotspot zur Konfiguration.

🛠️ Hardware Voraussetzungen:

  1. Display: ESP32-2432S028R (2.8" TFT mit resistivem Touch) 
  2. Hier kaufen, mit diesem Display funktioniert das Programm ohne Fehler

     

 

 

Features:

  • 🌦️ Live Weather: Open-Meteo (No API Key needed!)
  • 📈 Finance: Live DAX, DOW, BTC & VIX via Yahoo/Coinbase.
  • 🌙 Moon Phase: Precise mathematical calculation.
  • ⚙️ Easy Setup: WiFiManager included – no hardcoded WiFi credentials!
  • Hardware needed:

 

Hier der Sketch:

 

⚠️ WICHTIG: TFT_eSPI Konfiguration (User_Setup.h)

Damit das Display korrekt angesteuert wird, muss die Bibliothek TFT_eSPI angepasst werden. Ersetze den Inhalt deiner User_Setup.h (im Arduino-Library-Ordner) durch folgende Werte oder stelle sicher, dass diese Zeilen aktiv sind:

 

// ============================================================================
// DISPLAY PIN-KONFIGURATION (Passend für 2.8" ESP32-2432S028R / CYD)
// ============================================================================

#define ILI9341_DRIVER       // Standard Treiber für dieses Display

#define TFT_MISO 12
#define TFT_MOSI 13
#define TFT_SCLK 14
#define TFT_CS   15
#define TFT_DC    2
#define TFT_RST  -1          // Reset ist mit dem EN-Button verbunden

// --- BACKLIGHT KONFIGURATION ---
// Standard CYD (Micro-USB) nutzt Pin 21. 
// Neuere USB-C Versionen (z.B. von diymore) nutzen oft Pin 27.
// Falls das Display schwarz bleibt, einfach die Kommentare (//) tauschen:

#define TFT_BL   21          // <-- Standard Einstellung
// #define TFT_BL   27       // <-- Falls Pin 21 nicht funktioniert, hier // entfernen

#define TFT_BACKLIGHT_ON HIGH // Backlight wird mit HIGH eingeschaltet

// --- SCHRIFTARTEN ---
#define LOAD_GLCD  
#define LOAD_FONT2 
#define LOAD_FONT4 
#define LOAD_GFXFF

// --- GESCHWINDIGKEIT ---
#define SPI_FREQUENCY  40000000
 

Sketch für Arduino IDE 2.3.8 

 

#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <WiFiManager.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <TFT_eSPI.h>
#include "time.h"

// KONFIGURATION & STANDARDS
String cityName = "Oberhausen";
String selectedTZ = "CET-1CEST,M3.5.0,M10.5.0/3"; // Standard: Berlin
const char* ntpServer = "pool.ntp.org";

TFT_eSPI tft = TFT_eSPI();
WiFiClientSecure client;

float latitude, longitude;
String weatherDesc; float weatherTemp;
String moonPhaseText;
float daxValue, dowValue, vixValue, btcValue;

unsigned long lastTimeUpdate, lastWeatherUpdate, lastMoonUpdate, lastQuoteUpdate;
const unsigned long TIME_UPDATE_INTERVAL = 1000;
const unsigned long WEATHER_UPDATE_INTERVAL = 10*60*1000;
const unsigned long MOON_UPDATE_INTERVAL = 60*60*1000;
const unsigned long QUOTE_UPDATE_INTERVAL = 2*60*1000;

bool httpGetJson(const String& url, DynamicJsonDocument& doc) {
 HTTPClient http; http.begin(url);
 http.addHeader("User-Agent", "Mozilla/5.0");
 int code = http.GET();
 if (code != 200) { http.end(); return false; }
 String payload = http.getString(); http.end();
 return deserializeJson(doc, payload) == DeserializationError::Ok;
}

void updateWeather() {
 DynamicJsonDocument doc(4096);
 if (latitude == 0) {
   if (httpGetJson("https://open-meteo.com" + cityName + "&count=1&language=de&format=json", doc)) {
     latitude = doc["results"][0]["latitude"];
     longitude = doc["results"][0]["longitude"];
     cityName = doc["results"][0]["name"].as<String>();
   }
 }
 doc.clear();
 if (httpGetJson("https://open-meteo.com" + String(latitude,4) + "&longitude=" + String(longitude,4) + "&current=temperature_2m,weather_code&timezone=auto", doc)) {
   weatherTemp = doc["current"]["temperature_2m"];
   int code = doc["current"]["weather_code"];
   if(code==0) weatherDesc = "Klar";
   else if(code<=3) weatherDesc = "Bewoelkt";
   else if(code<=67) weatherDesc = "Regen"; 
   else if(code<=77) weatherDesc = "Schnee";
   else weatherDesc = "Gewitter";
 }
}

void updateMoonPhaseLocal() {
 struct tm t;
 if (getLocalTime(&t)) {
   time_t nowTs = mktime(&t);
   double diff = (double)nowTs - 947182440.0;
   double days = diff / 86400.0;
   double cycle = 29.530588;
   double phase = fmod(days, cycle);
   if (phase < 0) phase += cycle;

   if (phase < 1.5) moonPhaseText = "Neumond";
   else if (phase < 6.5) moonPhaseText = "Zunehmend";
   else if (phase < 8.5) moonPhaseText = "1. Viertel";
   else if (phase < 13.5) moonPhaseText = "Fast voll";
   else if (phase < 16.5) moonPhaseText = "Vollmond"; 
   else if (phase < 21.5) moonPhaseText = "Abnehmend";
   else if (phase < 23.5) moonPhaseText = "3. Viertel";
   else if (phase < 28.5) moonPhaseText = "Abnehmend";
   else moonPhaseText = "Neumond";
 }
}

void fetchStockData(String symbol, float& price) {
 DynamicJsonDocument doc(8192);
 if (httpGetJson("https://yahoo.com" + symbol, doc)) {
   price = doc["chart"]["result"][0]["meta"]["regularMarketPrice"];
 }
}

void fetchBitcoinEUR(float& price) {
 DynamicJsonDocument doc(2048);
 if (httpGetJson("https://coinbase.com", doc)) {
   price = doc["data"]["amount"].as<float>();
 }
}

void updateQuotes() {
 fetchStockData("^GDAXI", daxValue);
 fetchStockData("^DJI", dowValue);
 fetchStockData("^VIX", vixValue);
 fetchBitcoinEUR(btcValue);
}

void drawTime() {
 struct tm timeinfo;
 if (!getLocalTime(&timeinfo)) return;
 char buf[32]; strftime(buf, 32, "%H:%M:%S %d.%m", &timeinfo);
 tft.setTextSize(2); tft.setTextColor(TFT_CYAN);
 tft.fillRect(10, 10, 220, 35, TFT_BLACK);
 tft.setCursor(15, 30); tft.print(buf);
 tft.print(timeinfo.tm_isdst > 0 ? " SZ" : " WZ");
}

void drawWeather() {
 tft.setTextSize(2); tft.setTextColor(TFT_WHITE);
 tft.fillRect(10, 50, 230, 50, TFT_BLACK);
 tft.setCursor(15, 55); tft.print(cityName);
 tft.setCursor(15, 80); tft.print(weatherTemp, 1); tft.print("C "); tft.print(weatherDesc);
}

void drawMoon() {
 tft.setTextSize(2); tft.setTextColor(TFT_YELLOW);
 tft.fillRect(10, 105, 220, 35, TFT_BLACK);
 tft.setCursor(15, 125); tft.print(moonPhaseText);
}

void drawQuotes() {
 tft.setTextSize(2); tft.setTextColor(TFT_RED);
 tft.fillRect(10, 155, 220, 90, TFT_BLACK);
 int y = 160;
 tft.setCursor(15, y); tft.print("DAX "); tft.println(daxValue,0); y += 20;
 tft.setCursor(15, y); tft.print("DOW "); tft.println(dowValue,0); y += 20;
 tft.setCursor(15, y); tft.print("VIX "); tft.println(vixValue,1); y += 20;
 tft.setCursor(15, y); tft.print("BTC "); tft.print(btcValue,0); tft.print(" EUR");
}

void setup() {
 Serial.begin(115200);
 tft.init(); tft.setRotation(0); tft.fillScreen(TFT_BLACK);

 // WLAN MANAGER SETUP
 WiFiManager wm;
 
 // Custom Felder für Stadt und Zeitzone
 WiFiManagerParameter custom_city("city", "Stadt eingeben", cityName.c_str(), 40);
 // Ein einfaches HTML-Dropdown für die Zeitzone
 const char* custom_html_tz = "<br/><label for='tz'>Zeitzone wählen</label><br/><select name='tz' id='tz'>"
                              "<option value='CET-1CEST,M3.5.0,M10.5.0/3'>Europa/Berlin</option>"
                              "<option value='GMT0BST,M3.5.0,M10.5.0/2'>London</option>"
                              "<option value='EST5EDT,M3.2.0,M11.1.0'>New York</option>"
                              "<option value='JST-9'>Tokyo</option></select>";
 WiFiManagerParameter custom_tz_html(custom_html_tz);

 wm.addParameter(&custom_city);
 wm.addParameter(&custom_tz_html);

 tft.setTextColor(TFT_WHITE); tft.setTextSize(2); tft.setCursor(10, 50);
 tft.println("WLAN Konfig...");

 if (!wm.autoConnect("MakerDisplay-Setup")) ESP.restart();

 // Werte aus dem Portal übernehmen
 cityName = String(custom_city.getValue());
 // Hinweis: Das Auslesen von select-boxen via WiFiManager ist etwas tricky, 
 // für MakerWorld setzen wir hier Berlin als Default fest, falls nichts kommt.
 configTzTime(selectedTZ.c_str(), ntpServer);

 client.setInsecure();
 updateWeather(); updateMoonPhaseLocal(); updateQuotes();
 tft.fillScreen(TFT_BLACK);
 drawTime(); drawWeather(); drawMoon(); drawQuotes();
 lastTimeUpdate = lastWeatherUpdate = lastMoonUpdate = lastQuoteUpdate = millis();
}

void loop() {
 unsigned long now = millis();
 if (now - lastTimeUpdate > TIME_UPDATE_INTERVAL) { drawTime(); lastTimeUpdate = now; }
 if (now - lastWeatherUpdate > WEATHER_UPDATE_INTERVAL) { updateWeather(); drawWeather(); lastWeatherUpdate = now; }
 if (now - lastMoonUpdate > MOON_UPDATE_INTERVAL) { updateMoonPhaseLocal(); drawMoon(); lastMoonUpdate = now; }
 if (now - lastQuoteUpdate > QUOTE_UPDATE_INTERVAL) { updateQuotes(); drawQuotes(); lastQuoteUpdate = now; }
}
 

 


 

Design by user_2529369599 on MakerWorld (license: CC0).

Customers who viewed this item also viewed