Arduino Flip Clock mit 8×8 LED-Matrix – DIY Echtzeituhr-Projekt
Komponenten und Materialien
- Arduino Nano R3 (×1)
- Maxim DS3231M RTC (±5 ppm, I²C) (×1)
- 8×8 LED-Matrix mit MAX7219 Treiber (×1)
- RGB-LED (gemeinsame Kathode) (×1)
- Widerstand 220 Ω (×2)
- Drehgeber mit Taster (×1)
Benötigte Werkzeuge
- Lötkolben
Software & Online-Dienste
- Arduino IDE
Projektbeschreibung
Diese Uhr basiert auf einem 8×8-LED-Matrix-Modul und zeigt die Zeit durch horizontales oder vertikales Scrollen an. Jede Ziffer schiebt sich von rechts ein, bleibt kurz zentriert und heller, dann scrollt sie weiter nach links. Der Code stammt von Adrian Jones (März 2014) und bietet viele Anpassungsmöglichkeiten:
- Scrollrichtung: horizontal (
false) oder vertikal (true) übertop2bottom - Scrollgeschwindigkeit, Leerzeilen zwischen Zeichen, 12/24-Stunden-Format, Helligkeit etc.
Die Zeit wird per Drehgeber eingestellt. Eine zweifarbige LED signalisiert den Einstellmodus (Stunden, Minuten, Normalbetrieb). Das Gehäuse besteht aus zwei Teilen für einfachen Zugang.
Funktionsweise
Zeitanzeige
Die Bibliothek RTClib liest die DS3231-RTC aus. Die Zeit wird als String formatiert und in ein Byte-Array für die MAX7219-Matrix umgewandelt. Der Scroll-Effekt wird durch schrittweises Verschieben der Spaltendaten erzeugt.
Zeiteinstellung per Drehgeber
- Interrupt an Pin 2 (Encoder A) und Pin 3 (Taster).
- Drehrichtung erkennt Inkrement/Dekrement.
- Taster wechselt Modus: 0 = Normal, 1 = Stunden, 2 = Minuten.
- Zwei LEDs zeigen aktiven Modus an.
Code
//*****************************************************************************************//
// MATRIX CLOCK – Adrian Jones, März 2014
// Unterstützt Links-rechts und Oben-unten Scrollen
//*****************************************************************************************//
#include <Wire.h>
#include <RTClib.h>
// MAX7219 Register
#define max7219_reg_noop 0x00
#define max7219_reg_digit0 0x01
// ... (weitere Register)
#define max7219_reg_intensity 0x0a
#define max7219_reg_scanLimit 0x0b
#define max7219_reg_shutdown 0x0c
#define max7219_reg_displayTest 0x0f
#define dataIn 12 // DIN
#define load 10 // CS
#define clock 11 // CLK
// Zeichensatz (ASCII 32-126, plus Sonderzeichen)
char alphanum[][8] = {
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // Space
{0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x10}, // !
// ... (alle Zeichen wie im Original)
{0xE0,0xA0,0xE0,0x80,0x8A,0x15,0x15,0x11} // pm (~)
};
RTC_DS1307 RTC; // Tiny RTC (DS1307) an A4/A5
// Drehgeber
#define enc_PinA 2
#define enc_PinB 4
#define enc_Switch 3
#define mode_Pin 8
#define min_Pin 9
volatile boolean rotating = false;
volatile boolean clockwise = false;
volatile boolean updateFlag = false;
static int mode = 0; // 0=nichts, 1=Stunden, 2=Minuten
// Anzeige-Parameter
#define delay_line 75 // ms zwischen Zeilen
#define delay_char 400 // ms zwischen Zeichen
#define delay_mess 500 // ms zwischen Nachrichten
#define cblanks 1 // Leerzeilen zwischen Zeichen
#define eblanks 0 // Zusätzliche Leerzeilen am Ende
static boolean top2bottom = false; // true = vertikal
static boolean hour24 = false; // true = 24h
static boolean charHI = true; // Zeichen hervorheben
static boolean doSerial = true; // Serielle Ausgabe
void setup() {
Wire.begin();
Serial.begin(57600);
if (doSerial) Serial.print("MATRIX Clock - Adrian Jones, Mar. 2014");
pinMode(dataIn, OUTPUT);
pinMode(clock, OUTPUT);
pinMode(load, OUTPUT);
initMatrix();
pinMode(mode_Pin, OUTPUT); digitalWrite(mode_Pin, 1);
pinMode(min_Pin, OUTPUT); digitalWrite(min_Pin, 1);
pinMode(enc_PinA, INPUT_PULLUP);
pinMode(enc_PinB, INPUT_PULLUP);
pinMode(enc_Switch, INPUT_PULLUP);
attachInterrupt(0, rotEncoder, CHANGE);
attachInterrupt(1, swEncoder, CHANGE);
RTC.begin();
if (!RTC.isrunning()) {
RTC.adjust(DateTime(__DATE__, __TIME__));
if (doSerial) Serial.println(" (RTC reset)");
} else {
if (doSerial) Serial.println(" (RTC running)");
}
}
void loop() {
DateTime now = RTC.now();
String display_message = createMessage(now);
int arraylen = initDisplayString(display_message);
if (updateFlag) { show_time_and_date(now); updateFlag = false; }
while (rotating) {
delay(1);
adjTime(now, clockwise);
show_time_and_date(RTC.now());
display_message = createMessage(now);
arraylen = initDisplayString(display_message);
delay(1);
rotating = false;
}
delay(5);
for (int i = 0; i < (arraylen - 7); i++) {
for (int j = 1; j < 9; j++) {
maxSingle(j, ac[i + 8 - j]);
}
if (i % (8 + cblanks) == 0) {
if (charHI) maxSingle(max7219_reg_intensity, 0x01);
newDelay(delay_char);
} else {
maxSingle(max7219_reg_intensity, 0x00);
newDelay(delay_line);
}
}
if (mode == 0) newDelay(delay_mess);
}
// Interrupt-Routinen, Hilfsfunktionen (newDelay, initMatrix, adjTime, rotChar, show_time_and_date,
// createMessage, initDisplayString, maxSingle, putByte) – siehe Originalcode für Details.
Schaltplan
Anpassungstipps
- Vertikales Scrollen:
static boolean top2bottom = true; - 24h-Format:
static boolean hour24 = true; - Helligkeit:
maxSingle(max7219_reg_intensity, 0x0F);(0x00–0x0F) - Eigene Zeichen: Array
alphanumerweitern.
Herstellungsprozess
- Arduino POV-Uhr: Persistence-of-Vision LED-Display selbst bauen
- Retro-Numitron-Uhr mit Arduino bauen: Einfach, zuverlässig & energieeffizient
- Einen eigenen LED-Master-Clock mit Alarm bauen – aus 12 Metern Entfernung ablesbar
- Tetris-Spiel mit Arduino Nano auf selbstgebauter 16×8 LED-Matrix
- MotionSense: Smarte Einbruchserkennung mit Arduino & ESP8266
- Interaktive LED-Matrix Tür-Anzeige mit PIR-Bewegungssensor – Arduino Feiertagsgruß
- Intelligenten Arduino-Vierbeiner-Roboter bauen: Schritt-für-Schritt-Anleitung
- Stufenlose LED-Helligkeitssteuerung mit Bolt IoT und Arduino UNO
- Web-fähigen IoT-Messer mit Arduino, Yaler und IFTTT bauen
- Arduino-basierte abstoßende Magnetschwebung: Einfache Schaltung & DIY-Anleitung