Lichtwecker mit Arduino: Sanft aufwachen mit Sonnenaufgangssimulation

Heute zeige ich dir, wie du einen Lichtwecker mit Arduino mit Sonnenaufgangssimulation baust, der dich auf natürliche Weise weckt. Dieses Projekt kombiniert eine Echtzeituhr, ein 7-Segment-Display, einen MP3-Player und einen dimmbaren LED-Strip. Der Wecker startet 30 Minuten vor deiner Weckzeit mit einem simulierten Sonnenaufgang und spielt dann deine Lieblingsmusik ab. Du steuerst alles über einen Rotary-Encoder, und deine Einstellungen werden dauerhaft im EEPROM gespeichert – selbst nach einem Stromausfall bleiben sie erhalten.

Materialliste – Diese Bauteile brauchst du

Für den Bau deines Lichtweckers benötigst du folgende Komponenten. Ich habe dir alle wichtigen Teile zusammengestellt:

Technische Grundlagen für deinen Lichtwecker mit Arduino

Das Herzstück: Die Echtzeituhr DS1307

Das DS1307-Modul ist ein I²C-basierter Zeitmesser mit Backup-Batterie. Ich verwende es hier, weil es auch bei ausgeschaltetem Arduino weiterläuft und dir präzise Zeitinformationen liefert. Die Kommunikation läuft über die I²C-Pins SDA (Pin A4) und SCL (Pin A5) deines Arduino.


Sieh dir jetzt meinen neuen Arduino-Videokurs an: Jetzt ansehen!


TM1637 Segmentanzeige

Dieses 4-stellige 7-Segment-Display zeigt dir die Uhrzeit und deine Weckzeiten an. Es nutzt ein proprietäres 2-Draht-Protokoll über CLK und DIO und unterstützt verschiedene Helligkeitsstufen. Du kannst damit klar erkennen, ob du gerade die Weckzeit oder die aktuelle Uhrzeit siehst.

DF-Player-Mini: Dein MP3-Player

Der DF-Player-Mini ist ein kompaktes Modul, das MP3-Dateien von einer SD-Karte abspielen kann. Ich steuere ihn über serielle Kommunikation (RX/TX). Wichtig: Du musst deine MP3-Dateien in einem Ordner „01“ auf der SD-Karte ablegen (z.B. „01/001.mp3“), damit der Player sie findet.

MOSFET-Schaltung für LED-Dimming

Der N-Channel-MOSFET fungiert als elektronischer Schalter, den ich durch PWM-Signale vom Arduino steuere. Das ermöglicht dir das sanfte Dimmen des LED-Strips für die Sonnenaufgangssimulation. Der 10kΩ Widerstand am Gate verhindert ungewolltes Schalten, der Kondensator glättet die Spannungsversorgung und verhindert Flackern.

Rotary-Encoder

Der Drehimpulsgeber erzeugt bei Drehung Impulse, die der Arduino auswertet. Der integrierte Taster ermöglicht dir das Umschalten zwischen Menüs. Ich nutze die RotaryEncoder-Bibliothek mit TWO03-Latch-Modus für zuverlässige Erkennung ohne Fehlimpulse.

EEPROM-Speicher

Der Arduino verfügt über nichtflüchtigen EEPROM-Speicher. Dort speichere ich deine Weckzeit und den Wecker-Status dauerhaft, sodass die Einstellungen auch nach einem Stromausfall erhalten bleiben. Das bedeutet: Einmal eingestellt, behält dein Lichtwecker die Daten.

Verkabelung und Schaltplan für deinen Lichtwecker Arduino

Schaltplan Lichtwecker mit Arduino -  Verkabelung aller Komponenten

Pin-Belegung im Detail

Hier zeige ich dir die exakte Verkabelung. Achte besonders auf die gemeinsame Masse zwischen Arduino und externer LED-Stromversorgung – das ist entscheidend!

TM1637 Display:

  • CLK → Arduino Pin 10
  • DIO → Arduino Pin 11
  • VCC → 5V
  • GND → GND

Rotary-Encoder:

  • PIN_IN1 (CLK) → Arduino Pin 8
  • PIN_IN2 (DT) → Arduino Pin 9
  • Button → Arduino Pin 7
  • VCC → 5V
  • GND → GND

DF-Player-Mini:

  • RX → Arduino Pin 2
  • TX → Arduino Pin 3
  • VCC → 5V (empfohlen: mindestens 500mA)
  • GND → GND
  • SPK+ und SPK- → Lautsprecher (oder du nutzt den Klinkenanschluss)

DS1307 RTC:

  • SDA → Arduino Pin A4 (SDA)
  • SCL → Arduino Pin A5 (SCL)
  • VCC → 5V
  • GND → GND

Taster und LEDs:

  • Snooze-Taster → Arduino Pin 12 (mit internem Pull-up)
  • Status-LED → Arduino Pin 5 (über Vorwiderstand 220Ω)

MOSFET-LED-Schaltung:

  • Arduino Pin 6 (PWM) → MOSFET Gate (über 10kΩ Widerstand)
  • MOSFET Source → GND
  • MOSFET Drain → LED-Strip Minus
  • LED-Strip Plus → Externe Stromversorgung Plus
  • 1000µF Kondensator parallel zur LED-Versorgung (Plus zu Minus)
  • 10kΩ Pull-Down-Widerstand von Gate zu GND

Wichtig: Achte darauf, dass Arduino-GND und das GND der externen LED-Stromversorgung verbunden sind!

Lichtwecker mit Arduino Verkabelung Close-Up

Der Code für deinen Lichtwecker Arduino

Erforderliche Bibliotheken

Bevor du den Code hochlädst, installiere diese Bibliotheken über den Arduino Library Manager (Sketch → Bibliothek einbinden → Bibliotheken verwalten):

  • DFRobotDFPlayerMini (by DFRobot)
  • Time (by Michael Margolis)
  • DS1307RTC (by Michael Margolis)
  • TM1637 (by Avishay Orpaz)
  • RotaryEncoder (by Matthias Hertel)

Der vollständige Sketch

Hier ist der komplette Code für deinen Lichtwecker. Ich habe ihn ausführlich kommentiert, damit du jeden Schritt nachvollziehen kannst:

#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h" // DFRobotDFPlayerMini by DFRobot
#include <TimeLib.h> // Time by Michael Margolis
#include <DS1307RTC.h> // DS1307RTC by Micheal Margolis
#include <TM1637Display.h> // TM1637 by Avishay Orpaz
#include <RotaryEncoder.h> // RotaryEncoder by Matthias Hertel
#include <EEPROM.h>

TM1637Display display(10, 11);

#define PIN_IN1 8
#define PIN_IN2 9
#define PIN_R_BTN 7
#define PIN_SNOOZE 12

// EEPROM Adressen
const int EEPROM_ADDR_HOUR = 0;
const int EEPROM_ADDR_MIN = 1;
const int EEPROM_ADDR_ALERT = 2;

RotaryEncoder encoder(PIN_IN1, PIN_IN2, RotaryEncoder::LatchMode::TWO03);

const int alertLedPin = 5;
const int lightPin = 6;

// Zeitvariablen
int theTime[3] = {0, 0, 0};          
int theAlarmTime[2] = {6, 30};       

// Alarm-State-Variablen
bool alertSet = false;               
bool isAlarmRinging = false;         
int snoozeTargetMins = -1;           
int snoozeTime = 5;                  
int daylightMinutes = 30;            
int lastTriggeredMin = -1;           

// State Machine
// 0=Uhr, 1=Wecker Std, 2=Wecker Min, 3=RTC Std, 4=RTC Min
int clockState = 0;                  
bool blinkState = false;

// Button Entprellung & Long-Press
int lastBtnState = HIGH;
int lastSnoozeBtnState = HIGH;
unsigned long lastSnoozePress = 0;

unsigned long btnPressTime = 0;
bool btnHeld = false;
const unsigned long longPressDuration = 2000;

// Timer
unsigned long setTimer = 0;
const unsigned long setTimeout = 6000; 
unsigned long lastDisplayUpdate = 0;
unsigned long lastBlinkUpdate = 0;
const int blinkInterval = 250; 

// DFPlayer
SoftwareSerial mySoftwareSerial(3, 2);
DFRobotDFPlayerMini myDFPlayer;
int lautstaerke = 15;                

void setup() {
  Serial.begin(115200);
  while (!Serial);
  
  Serial.println(F("--- Systemstart Lichtwecker ---"));
  
  mySoftwareSerial.begin(9600);
  
  setSyncProvider(RTC.get);
  if (timeStatus() != timeSet) {
    Serial.println(F("WARNUNG: RTC Modul nicht gefunden oder Zeit nicht gesetzt."));
  } else {
    Serial.println(F("OK: RTC Zeit erfolgreich synchronisiert."));
  }

  display.setBrightness(0x0c);
  delay(100);
  getTimeFromRTC();

  pinMode(alertLedPin, OUTPUT);
  pinMode(PIN_R_BTN, INPUT_PULLUP);
  pinMode(PIN_SNOOZE, INPUT_PULLUP);
  pinMode(lightPin, OUTPUT);

  // --- EEPROM Daten laden ---
  theAlarmTime[0] = EEPROM.read(EEPROM_ADDR_HOUR);
  if (theAlarmTime[0] > 23) theAlarmTime[0] = 6; 
  
  theAlarmTime[1] = EEPROM.read(EEPROM_ADDR_MIN);
  if (theAlarmTime[1] > 59) theAlarmTime[1] = 30; 
  
  alertSet = (EEPROM.read(EEPROM_ADDR_ALERT) == 1);

  Serial.print(F("Geladene Weckzeit aus EEPROM: "));
  Serial.print(theAlarmTime[0]);
  Serial.print(F(":"));
  Serial.println(theAlarmTime[1]);
  Serial.print(F("Wecker Status: "));
  Serial.println(alertSet ? "AKTIV" : "INAKTIV");

  Serial.println(F("Initialisiere DFPlayer ..."));
  if (!myDFPlayer.begin(mySoftwareSerial)) {
    Serial.println(F("FEHLER: DFPlayer prüfen (Verkabelung/SD-Karte)."));
  } else {
    Serial.println(F("OK: DFPlayer Mini online."));
    myDFPlayer.volume(lautstaerke);
  }
}

void loop() {
  encoder.tick();
  
  if (millis() - lastDisplayUpdate >= 1000) {
    lastDisplayUpdate = millis();
    getTimeFromRTC();
    checkAlarm();
    updateDaylight();
  }

  if (millis() - lastBlinkUpdate >= blinkInterval) {
    lastBlinkUpdate = millis();
    blinkState = !blinkState;
  }

  if (clockState == 0) {
    showOnDisplay(theTime[2], theTime[1], 0); 
  } else if (clockState == 1) {
    showOnDisplay(theAlarmTime[0], theAlarmTime[1], blinkState ? 1 : 0); 
  } else if (clockState == 2) {
    showOnDisplay(theAlarmTime[0], theAlarmTime[1], blinkState ? 2 : 0); 
  } else if (clockState == 3) {
    showOnDisplay(theTime[2], theTime[1], blinkState ? 1 : 0);
  } else if (clockState == 4) {
    showOnDisplay(theTime[2], theTime[1], blinkState ? 2 : 0);
  }

  digitalWrite(alertLedPin, alertSet ? HIGH : LOW);

  // --- Encoder Button ---
  int btnState = digitalRead(PIN_R_BTN);
  
  if (btnState == LOW && lastBtnState == HIGH) {
    btnPressTime = millis();
    btnHeld = false;
  }
  
  if (btnState == LOW && lastBtnState == LOW && !btnHeld) {
    if (millis() - btnPressTime >= longPressDuration) {
      btnHeld = true; 
      if (clockState == 0) {
        Serial.println(F("EVENT: Long-Press erkannt. Wechsle in RTC-Setup."));
        clockState = 3; 
        setTimer = millis();
        forceDisplayOn();
        Serial.println(F("MODUS: RTC - Stunden einstellen"));
      }
    }
  }

  if (btnState == HIGH && lastBtnState == LOW) {
    if (!btnHeld && (millis() - btnPressTime > 50)) { 
      Serial.println(F("EVENT: Short-Press erkannt."));
      
      if (clockState == 0) {
        if (isAlarmRinging) {
          isAlarmRinging = false;
          snoozeTargetMins = -1;
          analogWrite(lightPin, 0); 
          myDFPlayer.pause(); 
          Serial.println(F("AKTION: Alarm für heute gestoppt."));
        } else {
          alertSet = !alertSet;
          EEPROM.update(EEPROM_ADDR_ALERT, alertSet ? 1 : 0); 
          if (alertSet) {
            clockState = 1; 
            setTimer = millis();
            forceDisplayOn();
            Serial.println(F("AKTION: Wecker EINGESCHALTET."));
            Serial.println(F("MODUS: Wecker - Stunden einstellen"));
          } else {
            snoozeTargetMins = -1;
            analogWrite(lightPin, 0);
            myDFPlayer.pause(); 
            Serial.println(F("AKTION: Wecker AUSGESCHALTET."));
          }
        }
      } else if (clockState == 1) {
        clockState = 2; 
        setTimer = millis();
        forceDisplayOn();
        Serial.println(F("MODUS: Wecker - Minuten einstellen"));
      } else if (clockState == 2) {
        clockState = 0; 
        saveAlarmTimeToEEPROM();
        Serial.println(F("MODUS: Normal (Uhrzeit)"));
      } else if (clockState == 3) {
        clockState = 4; 
        setTimer = millis();
        forceDisplayOn();
        Serial.println(F("MODUS: RTC - Minuten einstellen"));
      } else if (clockState == 4) {
        clockState = 0; 
        Serial.println(F("AKTION: Neue Uhrzeit gespeichert."));
        Serial.println(F("MODUS: Normal (Uhrzeit)"));
      }
    }
  }
  lastBtnState = btnState;

  // --- Snooze Button ---
  int snoozeBtnState = digitalRead(PIN_SNOOZE);
  if (snoozeBtnState == LOW && lastSnoozeBtnState == HIGH && millis() - lastSnoozePress > 50) {
    lastSnoozePress = millis();
    if (isAlarmRinging) {
      isAlarmRinging = false;
      int currentMins = theTime[2] * 60 + theTime[1];
      snoozeTargetMins = (currentMins + snoozeTime) % 1440;
      analogWrite(lightPin, 0); 
      myDFPlayer.pause(); 
      Serial.print(F("AKTION: Snooze aktiviert. Nächster Alarm um: "));
      Serial.print(snoozeTargetMins / 60);
      Serial.print(F(":"));
      Serial.println(snoozeTargetMins % 60);
    } else {
      Serial.println(F("EVENT: Snooze gedrückt, aber kein Alarm aktiv."));
    }
  }
  lastSnoozeBtnState = snoozeBtnState;

  // --- Encoder Drehung verarbeiten ---
  if (clockState > 0) {
    int dir = getEncoderDirection();
    if (dir != 0) {
      setTimer = millis(); 
      forceDisplayOn(); 
      
      if (clockState == 1) {
        setAlarmHour(dir);
        Serial.print(F("Eingabe: Wecker Stunde -> ")); Serial.println(theAlarmTime[0]);
      } else if (clockState == 2) {
        setAlarmMinute(dir);
        Serial.print(F("Eingabe: Wecker Minute -> ")); Serial.println(theAlarmTime[1]);
      } else if (clockState == 3) {
        setRTCHour(dir);
        Serial.print(F("Eingabe: RTC Stunde -> ")); Serial.println(theTime[2]);
      } else if (clockState == 4) {
        setRTCMinute(dir);
        Serial.print(F("Eingabe: RTC Minute -> ")); Serial.println(theTime[1]);
      }
    }
    
    // Timeout-Schutz
    if (millis() - setTimer > setTimeout) {
      Serial.println(F("EVENT: Timeout. Verlasse Einstellmodus."));
      if (clockState == 1 || clockState == 2) saveAlarmTimeToEEPROM();
      clockState = 0; 
      Serial.println(F("MODUS: Normal (Uhrzeit)"));
    }
  }
}

// --- Hilfsfunktionen ---

void forceDisplayOn() {
  blinkState = false;          
  lastBlinkUpdate = millis();  
}

void setAlarmHour(int step) {
  theAlarmTime[0] += step;
  if (theAlarmTime[0] > 23) theAlarmTime[0] = 0;
  if (theAlarmTime[0] < 0) theAlarmTime[0] = 23;
}

void setAlarmMinute(int step) {
  theAlarmTime[1] += step;
  if (theAlarmTime[1] > 59) theAlarmTime[1] = 0;  
  if (theAlarmTime[1] < 0) theAlarmTime[1] = 59;
}

void setRTCHour(int step) {
  int h = theTime[2] + step;
  if (h > 23) h = 0;
  if (h < 0) h = 23;
  setTime(h, theTime[1], 0, day(), month(), year());
  RTC.set(now()); 
  getTimeFromRTC();
}

void setRTCMinute(int step) {
  int m = theTime[1] + step;
  if (m > 59) m = 0;
  if (m < 0) m = 59;
  setTime(theTime[2], m, 0, day(), month(), year());
  RTC.set(now()); 
  getTimeFromRTC();
}

void saveAlarmTimeToEEPROM() {
  EEPROM.update(EEPROM_ADDR_HOUR, theAlarmTime[0]);
  EEPROM.update(EEPROM_ADDR_MIN, theAlarmTime[1]);
  Serial.println(F("SYSTEM: Weckzeit erfolgreich in EEPROM geschrieben."));
}

void getTimeFromRTC() {
  if (timeStatus() == timeSet) {
    theTime[2] = hour();
    theTime[1] = minute();
    theTime[0] = second();
  }
}

void showOnDisplay(int hours, int minutes, int hideMode) {
  uint8_t data[4];
  
  data[0] = display.encodeDigit(hours / 10);
  data[1] = display.encodeDigit(hours % 10);
  data[2] = display.encodeDigit(minutes / 10);
  data[3] = display.encodeDigit(minutes % 10);

  data[1] |= 0b01000000; 

  if (hideMode == 1) {
    data[0] = 0x00;
    data[1] = 0x00; 
  } else if (hideMode == 2) {
    data[2] = 0x00;
    data[3] = 0x00;
  }

  display.setSegments(data);
}

int getEncoderDirection() {
  int dir = (int)encoder.getDirection();
  if (dir == (int)RotaryEncoder::Direction::CLOCKWISE) return 1;
  if (dir == (int)RotaryEncoder::Direction::COUNTERCLOCKWISE) return -1;
  return 0;
}

void checkAlarm() {
  if (!alertSet) return;

  int currentMins = theTime[2] * 60 + theTime[1];
  int baseAlarmMins = theAlarmTime[0] * 60 + theAlarmTime[1];

  if (currentMins == baseAlarmMins && lastTriggeredMin != currentMins) {
    isAlarmRinging = true;
    snoozeTargetMins = -1; 
    lastTriggeredMin = currentMins;
    myDFPlayer.playFolder(1, 1); 
    Serial.println(F("!!! REGULÄRER ALARM AUSGELÖST !!! MP3 gestartet."));
  }

  if (snoozeTargetMins != -1 && currentMins == snoozeTargetMins && lastTriggeredMin != currentMins) {
    isAlarmRinging = true;
    snoozeTargetMins = -1; 
    lastTriggeredMin = currentMins;
    myDFPlayer.playFolder(1, 1); 
    Serial.println(F("!!! SNOOZE ALARM AUSGELÖST !!! MP3 gestartet."));
  }
}

void updateDaylight() {
  if (!alertSet) return;

  int currentMins = theTime[2] * 60 + theTime[1];
  int baseAlarmMins = theAlarmTime[0] * 60 + theAlarmTime[1];
  
  int diff = baseAlarmMins - currentMins;
  if (diff < 0) diff += 1440; 

  if (isAlarmRinging) {
    analogWrite(lightPin, 255); 
  } else if (diff > 0 && diff <= daylightMinutes) {
    float progress = (float)(daylightMinutes - diff) / (float)daylightMinutes; 
    int brightness = (int)(progress * progress * progress * 255.0);
    brightness = constrain(brightness, 0, 255); 
    analogWrite(lightPin, brightness);
  } else {
    analogWrite(lightPin, 0); 
  }
}

Code-Erklärung: So funktioniert dein Lichtwecker Arduino

Der Code des Weckers arbeitet nach dem Prinzip des „Non-Blocking Code“ (blockierungsfreie Programmierung). Anstatt den Ablauf des Arduino mit starren delay()-Befehlen anzuhalten, durchläuft das Programm die loop()-Schleife rasend schnell immer wieder. Dabei arbeitet das System fünf zentrale Aufgaben parallel ab:

Ausfallsicherheit (EEPROM): Damit der Wecker nach einem Stromausfall oder beim Umstecken nicht alle Daten vergisst, speichert die Funktion saveAlarmTimeToEEPROM() die eingestellte Weckzeit und den Aktivierungsstatus (Wecker an/aus) im permanenten EEPROM-Speicher des Mikrocontrollers. Das setup() liest diese Daten beim Systemstart sofort wieder aus.

Asynchrone Timer (millis()): Alle zeitlichen Abläufe – vom sekündlichen Abfragen des RTC-Uhrzeitmoduls bis zum schnellen Blinken des Displays (250ms) beim Einstellen – werden über Zeitstempel gesteuert. Der Arduino vergleicht permanent die aktuelle Laufzeit (millis()) mit dem letzten gemerkten Zeitstempel. Das hält die Benutzeroberfläche extrem reaktionsschnell, sodass kein Dreh am Encoder verloren geht.

Die State-Machine (Zustandsautomat): Das Herzstück der Menüführung ist die Variable clockState. Sie definiert, in welchem Modus sich der Wecker gerade befindet:

  • 0: Normale Uhrzeit anzeigen
  • 1 & 2: Weckzeit einstellen (Stunden / Minuten)
  • 3 & 4: Systemzeit des RTC-Moduls einstellen (Stunden / Minuten)Abhängig von diesem Zustand leitet der Code die Eingaben des Rotary-Encoders an die richtigen Variablen weiter und entscheidet, welche Ziffern auf dem Display blinken.

Natürlicher Sonnenaufgang: Ein lineares Aufblenden einer LED wirkt auf das menschliche Auge anfangs viel zu abrupt. Die Funktion updateDaylight() nutzt daher eine kubische Kurve zur Berechnung der PWM-Werte ($Helligkeit = 255 \times Fortschritt^3$). Das sorgt dafür, dass das Licht zu Beginn der Aufwachphase extrem sanft glimmt und erst kurz vor dem Alarm stark ansteigt.

Präzise Alarm-Logik: Sobald die aktuelle Uhrzeit mit der Weckzeit (oder der berechneten Snooze-Zeit) übereinstimmt, löst der Alarm aus. Die Variable lastTriggeredMin stellt sicher, dass der MP3-Befehl für den DFPlayer exakt einmal gesendet wird. Ohne diese Sicherung würde der Arduino den Song in der ersten Alarm-Minute hunderte Male pro Sekunde neu starten.

Und hier noch die Bedienungsanleitung im CASIO Stil :D

BEDIENUNGSANLEITUNG: MODUL ARD-321 (Lichtwecker)

ALLGEMEINER LEITFADEN

  • Drücken Sie die Taste [MODE/SET] (Druck auf den Drehregler), um zwischen den Betriebsmodi zu wechseln oder Einstellungen zu bestätigen.
  • Drehen Sie das Rad [RAD] (Drehregler links/rechts), um blinkende Werte zu verändern.
  • Drücken Sie die Taste [SNOOZE] an der Oberseite, um die Schlummerfunktion zu aktivieren.
  • Das Gerät kehrt in jedem Einstellungs-Modus nach 6 Sekunden Inaktivität automatisch in den regulären UHRZEIT-MODUS zurück. Alle bis dahin gemachten Änderungen werden automatisch im internen EEPROM-Speicher gesichert.

1. WECKER EIN- UND AUSSCHALTEN

Um den täglichen Alarm zu aktivieren oder zu deaktivieren:

  1. Drücken Sie im regulären UHRZEIT-MODUS kurz die Taste [MODE/SET].
  2. Wenn der Wecker EINGESCHALTET wird: Die rote Indikator-LED leuchtet auf. Das Gerät wechselt automatisch in den ALARM-EINSTELL-MODUS (siehe Abschnitt 2).
  3. Wenn der Wecker AUSGESCHALTET wird: Die rote Indikator-LED erlischt. Der Alarm ist vollständig deaktiviert.

2. WECKZEIT EINSTELLEN (ALARM-MODUS)

Hinweis: Dieser Modus startet automatisch, sobald der Wecker über [MODE/SET] eingeschaltet wird.

  1. Die Stunden-Ziffern blinken schnell. Drehen Sie das [RAD], um die Stunde des Alarms einzustellen.
  2. Drücken Sie kurz [MODE/SET]. Die Minuten-Ziffern blinken.
  3. Drehen Sie das [RAD], um die Minute einzustellen. (Hinweis: Nach Minute 59 beginnt die Anzeige wieder bei 00, ohne die Stunde zu verändern).
  4. Drücken Sie kurz [MODE/SET] oder warten Sie 6 Sekunden, um den Vorgang abzuschließen. Die Zeit ist gespeichert.

3. ALARM STOPPEN & SCHLUMMERN (SNOOZE)

Wenn die eingestellte Weckzeit erreicht ist, ertönt das Audio-Signal und das Licht leuchtet mit maximaler Helligkeit.

  • ALARM FÜR HEUTE BEENDEN: Drücken Sie kurz [MODE/SET]. Ton und Licht werden sofort ausgeschaltet. Der Wecker bleibt für den nächsten Tag scharfgeschaltet (Indikator-LED leuchtet weiterhin).
  • SCHLUMMERN (SNOOZE): Drücken Sie die [SNOOZE]-Taste. Ton und Licht werden unterbrochen. Nach exakt 5 Minuten wird der Alarm erneut ausgelöst.

4. UHRZEIT EINSTELLEN (RTC-MODUS)

Um die interne Systemzeit der Uhr zu korrigieren:

  1. Halten Sie im UHRZEIT-MODUS die Taste [MODE/SET] für ca. 2 Sekunden ununterbrochen gedrückt.
  2. Die Stunden-Ziffern beginnen zu blinken. Drehen Sie das [RAD], um die aktuelle Stunde einzustellen.
  3. Drücken Sie kurz [MODE/SET]. Die Minuten-Ziffern blinken.
  4. Drehen Sie das [RAD], um die aktuelle Minute einzustellen.
  5. Drücken Sie kurz [MODE/SET] oder warten Sie 6 Sekunden, um die neue Systemzeit permanent im RTC-Modul zu speichern.

5. AUTOMATISCHE LICHT-FUNKTION (DAWN-SIMULATION)

Ist der Wecker scharfgeschaltet, berechnet der Mikroprozessor den herannahenden Alarm. Exakt 30 Minuten vor der eingestellten Weckzeit beginnt das LED-Modul stufenlos zu leuchten. Die Helligkeit nimmt nach einer logarithmischen Kurve zu, um ein natürliches, sanftes Aufwachen durch simuliertes Sonnenlicht zu gewährleisten. Wenn der akustische Alarm ertönt, ist die Helligkeit bei 100 %.


Wenn dir das Projekt gefallen hat und du von weiteren interessanten Projekten inspiriert werden willst, sieh dir doch mal mein neues E-Book »Arduino Projekte Volume 1« an!

  • Die beliebtesten Arduino-Projekte von StartHardware
  • Inklusive Schaltplan, Beschreibung und Code
  • Arduino-Schnellstart-Kapitel
  • Kompakter Programmierkurs


0 0 votes
Article Rating
Abonnieren
Benachrichtige mich bei
0 Comments
Newest
Oldest Most Voted
Inline Feedbacks
Alle Kommentare anzeigen
0
Ich würde mich über deine Meinung freuen.x