/* Uhrzeit mit millis() erzeugen
 * Die Abfrage von millis() und previousMillis gibt eine Ausführung in der if-Abfrage
 * im Sekundentakt. Mit einem Module-60-Zähler werden Sekunden und Minuten erzeugt
 */
#include <Wire.h>
#include <LiquidCrystal_I2C.h>    // Die Bibliothek muss noch installiert werden!

LiquidCrystal_I2C lcd(0x27, 16, 2); // Display mit 2 Zeilen, 16 Zeichen, I2C-Adresse 0x27 (PCF8574!)

//***** Taster und LEDs wie auf bleuer Platine **********************
const int LED_rot=32, LED_gruen=33, Taster2=2, Taster4=4;

//***** Globale Variablen *******************************************
byte Stunde, Minute, Sekunde;
char buf[20];         // Zeichenpuffer für sprintf
unsigned long previousMillis = 0;  // wie im Beispiel 02. Digital/BlinkWithoutDelay
const int MillisProSekunde = 1000;


//***** Setup, wird 1x ausgeführt ***********************************
void setup() {
  Serial.begin(115200);
  pinMode(LED_rot, OUTPUT);
  pinMode(LED_gruen, OUTPUT);
  pinMode(Taster2, INPUT_PULLUP);
  pinMode(Taster4, INPUT_PULLUP);

  Stunde = 10;      // Anfangs-Uhrzeit
  Minute = 15;
  Sekunde = 55;

  Serial.println("Hello 2BKI2!");
  lcd.init();
  lcd.backlight();       // Hintergrundbeleuchtung einschalten
  lcd.setCursor(1, 0);   // Cursor auf 2. Zeichen in der 1. Zeile setzen
  lcd.print("Hello 2BKI2!");
  lcd.setCursor(1, 1);   // Cursor auf 2. Zeichen in der 2. Zeile setzen
  sprintf(buf, "Zeit: %2d:%02d:%02d", Stunde, Minute, Sekunde);
  lcd.print(buf);
  
}

//***** Loop wird immer wieder ausgeführt ****************************
void loop() {
  // Sekundentakt erzeugen
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis >= MillisProSekunde) {
    previousMillis = currentMillis;     // letzte Zeit merken
    Sekunde ++;
    if(Sekunde == 60) {   // Modulo-60-Zähler
      Sekunde = 0;
      Minute ++;
      if(Minute == 60) {
        Minute = 0;
        Stunde ++;
        if(Stunde == 24) { // Modulo-24-Zähler
          Stunde = 0;
          // Tag ++;
        }
      }
    }
    // Uhrzeit ist jetzt akutalisiert, also ausgeben
    lcd.setCursor(1, 1);
    sprintf(buf, "Zeit: %2d:%02d:%02d", Stunde, Minute, Sekunde);
    lcd.print(buf);
  }

  // Irgend was auf der seriellen Schnittstelle angekommen?
  if(Serial.available()>0) {
    char Zeichen = Serial.read();   // die Variable Zeichen ist nur in der if-Abfrage gültig!
    // hier jetzt die Uhrzeit einstellbar machen (die Abfrage '1' und '0' kann drin bleiben)
    switch(Zeichen) {
      case '1': digitalWrite(LED_rot, HIGH);
      break;
      case '0': digitalWrite(LED_rot, LOW);
      break;
      
    }
  }
  
}
Taster2
Taster4
LED32
LED33
ESP32 Schulboard mit LEDs und Tastern, I2C-Bus mit Standard-Belegung
Auf dem Display sitzt ein PCF8574