In diesem Artikel möchte ich zeigen, wie die Erstellung einer eigenen digitalen Uhr mit Hilfe eines Arduino Mikrocontrollers, einem LED-Ring und einem RTC-Modul (Echtzeituhr) umgesetzt wird.
Der LED Ring soll lediglich mit drei unterschiedlichen Farben die Stunde, Minute und Sekunde auf den 60 Neopixel anzeigen. Da das Entwicklungsboard aber nicht ausreichend Spannung für die LED‘s bereitstellt, wird ein zusätzliches Netzteil mit 5 Volt und mindestens 3,6 Ampere verwendet, da jede LED 0,06A benötigt. Auch daran denken, den GND-Pin des LED-Ring mit dem GND-Pin des Arduino zu verbinden, um eine gemeinsame Masse zu haben.

Das RTC-Modul stellt mit seiner mitgelieferten 3V Knopfzelle sicher, dass die Uhrzeit auch bei Stromausfall, weiterhin über die i2c Schnittstelle bereitstellt wird. Genauigkeit bei gleichbleibender Raumtemperatur etwa ± 2 Minuten pro Jahr.
Auch enthält dieser RTC einen Temperatursensor und eine Schaltung, der die Frequenz des Quarzes anpasst, um die durch Temperaturänderungen verursachten Fehler zu korrigieren, da die Auswirkungen von Temperaturschwankungen auf die Genauigkeit der Uhr einwirken.
Es gibt auch noch günstigere Echtzeituhren Module ohne Temperatursensoren, einmal den DS1302 der über eine 3-adrige serielle Schnittstelle kommuniziert oder den DS1307 der per I2C kommuniziert.
Leider sind aber diese beiden deutlich ungenauer mit den Zeitabweichungen und besitzen keine Alarmfunktion.
Dieser verbaute Temperatursensor (±3°C Genauigkeit) kann wie im Beispiel Sketch zu sehen ist, mit RTC.getTemp() ausgelesen werden.
Zwei weitere Erweiterungsmöglichkeiten der Uhr wären die Datumsausgabe und die Alarmfunktion, die hier nur im seriellen Monitor derzeit sichtbar sind.

Benötigte Hardware:
Arduino Uno Clone mit folgenden Teilen:
Arduino PIN 3,3V = RTC PIN VCC
Arduino PIN GND = RTC PIN GND
Arduino PIN A5 = RTC PIN SCL
Arduino PIN A4 = RTC PIN SDA
NEOPixel PIN 5 Volt = separates Netzteil mit 3,6 Ampere (Berechnung 0,06A pro LED)
NEOPixel PIN GND = Arduino PIN GND
NEOPixel PIN Data = Arduino PIN 6
Verdrahtung:

Quellcode (lang mit Setzen der Zeit und Serieller Ausgabe):
#include <Wire.h>
#include <I2C_RTC.h>
#include <Adafruit_NeoPixel.h>
#define LED_PIN 6 // Ändern Sie dies auf den Pin, an dem Ihre WS2812B LED's angeschlossen sind.
#define NUM_LEDS 60 // Anzahl der LED's in Ihrer Anordnung
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
static DS3231 RTC;
void setup()
{
strip.begin();
strip.show(); // Alle LED's ausschalten
Serial.begin(9600);
RTC.begin();
RTC.adjust(DateTime(F(__DATE__), F(__TIME__)));stellt die Uhr beim Upload wie Personal Computer
RTC.setHourMode(CLOCK_H12);
//RTC.setHourMode(CLOCK_H24);
RTC.setDay(17);//einmal zum starten die aktuellen Werte setzen
RTC.setMonth(9);//einmal zum starten die aktuellen Werte setzen
RTC.setYear(2023);//einmal zum starten die aktuellen Werte setzen
RTC.setHours(12);//einmal zum starten die aktuellen Werte setzen
RTC.setMinutes(59);//einmal zum starten die aktuellen Werte setzen
RTC.setSeconds(26);
DateTime A1, A2;
Serial.println();
Serial.println("*** RTC DS3231 ***");
Serial.print("Is Clock Running : ");
if (RTC.isRunning())
Serial.println("Yes");
else
Serial.println("No. Time may be Inaccurate");
Serial.print("Hour Mode :");
if (RTC.getHourMode() == CLOCK_H12)
Serial.println("12 Hours");
else
Serial.println("24 Hours");
//Alarms1
A1 = RTC.getAlarm1();
Serial.print("Alarm1 Time : ");
Serial.print(A1.hours);
Serial.print(":");
Serial.print(A1.minutes);
Serial.print(":");
Serial.print(A1.seconds);
if (RTC.getHourMode() == CLOCK_H12)
{
switch (RTC.getMeridiem())
{
case HOUR_AM :
Serial.print(" AM");
break;
case HOUR_PM :
Serial.print(" PM");
break;
}
}
Serial.println();
//Alarms Trigger Status
Serial.print("Alarm1 Tiggered : ");
if (RTC.isAlarm1Tiggered())
Serial.println("Yes");
else
Serial.println("No");
Serial.print("Alarm2 Tiggered : ");
if (RTC.isAlarm2Tiggered())
Serial.println("Yes");
else
Serial.println("No");
Serial.print("INT/SQW Pin Mode : ");
if (RTC.getINTPinMode())
Serial.println("Alarm");
else
Serial.println("SQW");
//Aging Offset Value
Serial.print("Aging Offset : ");
Serial.print(RTC.getAgingOffset());
Serial.println();
Serial.print("RTC Temperature : ");
Serial.print(RTC.getTemp());
Serial.print("'C");
Serial.println();
Serial.println();
}
void loop()
{
int stunde = RTC.getHours();
int minute = RTC.getMinutes();
int sekunde = RTC.getSeconds();
int stundenLED = map(stunde, 0, 12, 0, NUM_LEDS - 1);
int minutenLED = map(minute, 0, 59, 0, NUM_LEDS - 1);
int sekundenLED = map(sekunde, 0, 59, 0, NUM_LEDS - 1);
for (int i = 0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, 0, 0, 0);
}
// Die entsprechenden LED's für Stunden, Minuten und Sekunden einschalten
strip.setPixelColor(stundenLED, 255, 0, 0); // Rote LED für Stunden
strip.setPixelColor(minutenLED, 0, 255, 0); // Grüne LED für Minuten
strip.setPixelColor(sekundenLED, 0, 0, 255); // Blaue LED für Sekunden
strip.show();
switch (RTC.getWeek())
{
case 1:
Serial.print("SUN");
break;
case 2:
Serial.print("MON");
break;
case 3:
Serial.print("TUE");
break;
case 4:
Serial.print("WED");
break;
case 5:
Serial.print("THU");
break;
case 6:
Serial.print("FRI");
break;
case 7:
Serial.print("SAT");
break;
}
Serial.print(" ");
Serial.print(RTC.getDay());
Serial.print("-");
Serial.print(RTC.getMonth());
Serial.print("-");
Serial.print(RTC.getYear());
Serial.print(" ");
Serial.print(RTC.getHours());
Serial.print(":");
Serial.print(RTC.getMinutes());
Serial.print(":");
Serial.print(RTC.getSeconds());
if (RTC.getHourMode() == CLOCK_H12)
{
switch (RTC.getMeridiem())
{
case HOUR_AM :
Serial.print(" AM");
break;
case HOUR_PM :
Serial.print(" PM");
break;
}
}
Serial.println();
delay(1000);
}