Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Manufacturing Technology >> Herstellungsprozess

Arduino Echtzeituhr LED-Uhr: Zuverlässige Zeitanzeige selbst bauen

Komponenten und Zubehör

Arduino UNO × 1
RTC-Modul (DS1307 / DS3231) × 1
Widerstand 1 kΩ × 15
Widerstand 120 Ω × 15
Spannungsregler 7805 (5 V) × 1
Keramik-Kondensator 22 pF × 1
Quarz 16 MHz × 1
Elektrolytkondensator 10 µF × 1
Knopfzelle CR2032 + Halter × 1
5 mm LED grün × 190
NPN-Transistor (z. B. 2N2222) × 10
PNP-Transistor (z. B. 2N2907) × 12
Taster (4 Stück) × 4
Netzteil 12 V / 5 A × 1

Benötigte Werkzeuge

Über dieses Projekt

Zuerst folgende Bibliotheken herunterladen:

  1. Wire.h (bereits in Arduino IDE enthalten)
  2. RTClib.h (von Adafruit / GitHub)

Video ansehen

Im Video wird der Aufbau Schritt für Schritt gezeigt.

RTC-Verdrahtung

Das RTC-Modul (DS1307/DS3231) wird über I2C (A4=SDA, A5=SCL) an den Arduino angeschlossen. Die Knopfzelle CR2032 sichert die Uhrzeit bei Stromausfall.

RTC-Schalter / Taster

Vier Taster dienen der Zeiteinstellung (Stunden, Minuten, 12/24h-Modus, Bestätigung).

Anode und Kathode identifizieren

Die 7-Segment-Anzeigen sind als Common Anode ausgeführt. Bei Common Cathode müssen die Logikpegel im Code invertiert werden (siehe unten).

Schaltplan (Common Anode)

Die 6-stellige 7-Segment-Anzeige wird multiplexet: 6 Ziffern (Digit 1–6) und 8 Segmente (A–G, DP) werden über Transistoren (NPN für Ziffern, PNP für Segmente) angesteuert.

Änderungen für Common Cathode

Im Code die Definitionen SEGMENT_ON / SEGMENT_OFF und DIGIT_ON / DIGIT_OFF vertauschen.

Netzteil

Ein 7805-Regler wandelt 12 V auf 5 V für Arduino und Logik. Die LEDs werden direkt aus der 12-V-Versorgung (über Vorwiderstände) gespeist, um Strom zu sparen.

Code

LED-Uhr Code (Arduino)

/* 4-stellige 7-Segment-Anzeige, multiplexed auf 6 Stellen
   Basierend auf SparkFun / niq_ro / BMIAK Basnayaka */

#include 
#include "RTClib.h"

RTC_DS1307 RTC;

// Pin-Belegung Segmente
int segA = 0, segB = 1, segC = 2, segD = 4;
int segE = 7, segF = 8, segG = 12, segDP = 13;

// Ziffern-Pins (Common Anode -> HIGH = aus, LOW = an über PNP)
int digit1 = 11, digit2 = 10, digit3 = 9;
int digit4 = 6, digit5 = 5, digit6 = 3;

// Taster
byte SW0 = A0, SW1 = A2, SW2 = A1, SWT = A3;

int Adhr = 0, Admnt = 0, D = 0, Z = 0;
long zh, uh, ore, zm, um, miniti;

void setup() {
  Wire.begin();
  RTC.begin();
  // RTC.adjust(DateTime(F(__DATE__), F(__TIME__))); // Einmalig zum Stellen aktivieren

  // SQW auf 1 Hz konfigurieren
  Wire.beginTransmission(0x68);
  Wire.write(0x07);
  Wire.write(0x10);  // 1 Hz Square Wave
  Wire.endTransmission();

  // Pins als Output
  for (int p : {segA, segB, segC, segD, segE, segF, segG, segDP,
                digit1, digit2, digit3, digit4, digit5, digit6}) {
    pinMode(p, OUTPUT);
  }

  // Taster mit Pullups
  for (byte sw : {SW0, SW1, SW2, SWT}) {
    pinMode(sw, INPUT);
    digitalWrite(sw, HIGH);
  }
  digitalWrite(segDP, LOW);
}

void loop() {
  DateTime now = RTC.now();
  long HR = now.hour() * 1000;
  long timp = HR * 10 + now.minute() * 100 + now.second();
  Adhr = now.hour();
  Admnt = now.minute();

  if (timp >= 250000) timp -= 240000;

  // 12/24h-Umschaltung per Taster SWT
  if (digitalRead(SWT) == 0) {
    delay(300);
    D = (D == 0) ? 1 : 0;
  }

  if (D == 0) {  // 24h-Modus
    if (timp >= 130000) {
      timp -= 120000;
      digitalWrite(segDP, HIGH);  // PM-Indikator
    }
  } else {       // 12h-Modus
    if (timp >= 130000) digitalWrite(segDP, LOW);
  }

  // Zeit einstellen per SW0 (gedrückt halten)
  if (digitalRead(SW0) == 0) {
    delay(100);
    Z = 1;
    set_time();
  }

  // Multiplexing: 6 Stellen nacheinander anzeigen
  for (int i = 100; i > 0; i--) {
    if (timp >= 100000) displayNumber01(timp);
    else displayNumber02(timp);
  }
  for (int i = 100; i > 0; i--) {
    if (timp >= 100000) displayNumber03(timp);
    else displayNumber04(timp);
  }
  for (int i = 100; i > 0; i--) {
    if (timp >= 100000) displayNumber05(timp);
    else displayNumber06(timp);
  }
}

void set_time() {
  byte hours = Adhr, minutes = Admnt;
  // BCD-Korrektur
  if ((hours & 0x0F) > 9) hours += 6;
  if (hours > 0x24) hours = 1;
  if ((minutes & 0x0F) > 9) minutes += 6;
  if (minutes > 0x59) minutes = 0;

  while (Z) {
    // Stunden einstellen (SW2)
    while (digitalRead(SW2) == 0) {
      hours++;
      if ((hours & 0x0F) > 9) hours += 6;
      if (hours > 0x24) hours = 1;
      // Anzeige aktualisieren...
      for (int i = 400; i > 0; i--) displayNumber01(/* berechneter Wert */);
    }
    // Minuten einstellen (SW1)
    while (digitalRead(SW1) == 0) {
      minutes++;
      if ((minutes & 0x0F) > 9) minutes += 6;
      if (minutes > 0x59) minutes = 0;
      for (int i = 400; i > 0; i--) displayNumber01(/* berechneter Wert */);
    }
    // In RTC schreiben
    Wire.beginTransmission(0x68);
    Wire.write(0);
    Wire.write(0x00);          // Sekunden
    Wire.write(minutes);       // Minuten
    Wire.write(0x80 | hours);  // Stunden (24h, Bit7=1)
    Wire.write(0x06); Wire.write(0x01); Wire.write(0x05); Wire.write(0x09); // Tag, Datum, Monat, Jahr
    Wire.write(0x10);          // Control: 1 Hz SQW
    Wire.endTransmission();
    delay(100);
    if (digitalRead(SW0) == 0) Z = 0;
    delay(300);
  }
}

// Anzeigefunktionen für jede Ziffer (multiplexed)
// displayNumber01 bis displayNumber06 steuern jeweils eine Ziffer
// lightNumber(ziffer) setzt die Segmente (0-9, 10=aus)
// Common Anode: SEGMENT_ON = HIGH, SEGMENT_OFF = LOW
// DIGIT_ON = HIGH (PNP-Basis), DIGIT_OFF = LOW

void displayNumber01(long toDisplay) { /* ... */ }
void displayNumber02(long toDisplay) { /* ... */ }
void displayNumber03(long toDisplay) { /* ... */ }
void displayNumber04(long toDisplay) { /* ... */ }
void displayNumber05(long toDisplay) { /* ... */ }
void displayNumber06(long toDisplay) { /* ... */ }

void lightNumber(int numberToDisplay) {
  #define SEGMENT_ON HIGH
  #define SEGMENT_OFF LOW
  // Für Common Cathode: #define SEGMENT_ON LOW / #define SEGMENT_OFF HIGH
  switch (numberToDisplay) {
    case 0: digitalWrite(segA, SEGMENT_ON); digitalWrite(segB, SEGMENT_ON); digitalWrite(segC, SEGMENT_ON);
            digitalWrite(segD, SEGMENT_ON); digitalWrite(segE, SEGMENT_ON); digitalWrite(segF, SEGMENT_ON);
            digitalWrite(segG, SEGMENT_OFF); break;
    case 1: digitalWrite(segA, SEGMENT_OFF); digitalWrite(segB, SEGMENT_ON); digitalWrite(segC, SEGMENT_ON);
            digitalWrite(segD, SEGMENT_OFF); digitalWrite(segE, SEGMENT_OFF); digitalWrite(segF, SEGMENT_OFF);
            digitalWrite(segG, SEGMENT_OFF); break;
    case 2: digitalWrite(segA, SEGMENT_ON); digitalWrite(segB, SEGMENT_ON); digitalWrite(segC, SEGMENT_OFF);
            digitalWrite(segD, SEGMENT_ON); digitalWrite(segE, SEGMENT_ON); digitalWrite(segF, SEGMENT_OFF);
            digitalWrite(segG, SEGMENT_ON); break;
    case 3: digitalWrite(segA, SEGMENT_ON); digitalWrite(segB, SEGMENT_ON); digitalWrite(segC, SEGMENT_ON);
            digitalWrite(segD, SEGMENT_ON); digitalWrite(segE, SEGMENT_OFF); digitalWrite(segF, SEGMENT_OFF);
            digitalWrite(segG, SEGMENT_ON); break;
    case 4: digitalWrite(segA, SEGMENT_OFF); digitalWrite(segB, SEGMENT_ON); digitalWrite(segC, SEGMENT_ON);
            digitalWrite(segD, SEGMENT_OFF); digitalWrite(segE, SEGMENT_OFF); digitalWrite(segF, SEGMENT_ON);
            digitalWrite(segG, SEGMENT_ON); break;
    case 5: digitalWrite(segA, SEGMENT_ON); digitalWrite(segB, SEGMENT_OFF); digitalWrite(segC, SEGMENT_ON);
            digitalWrite(segD, SEGMENT_ON); digitalWrite(segE, SEGMENT_OFF); digitalWrite(segF, SEGMENT_ON);
            digitalWrite(segG, SEGMENT_ON); break;
    case 6: digitalWrite(segA, SEGMENT_ON); digitalWrite(segB, SEGMENT_OFF); digitalWrite(segC, SEGMENT_ON);
            digitalWrite(segD, SEGMENT_ON); digitalWrite(segE, SEGMENT_ON); digitalWrite(segF, SEGMENT_ON);
            digitalWrite(segG, SEGMENT_ON); break;
    case 7: digitalWrite(segA, SEGMENT_ON); digitalWrite(segB, SEGMENT_ON); digitalWrite(segC, SEGMENT_ON);
            digitalWrite(segD, SEGMENT_OFF); digitalWrite(segE, SEGMENT_OFF); digitalWrite(segF, SEGMENT_OFF);
            digitalWrite(segG, SEGMENT_OFF); break;
    case 8: digitalWrite(segA, SEGMENT_ON); digitalWrite(segB, SEGMENT_ON); digitalWrite(segC, SEGMENT_ON);
            digitalWrite(segD, SEGMENT_ON); digitalWrite(segE, SEGMENT_ON); digitalWrite(segF, SEGMENT_ON);
            digitalWrite(segG, SEGMENT_ON); break;
    case 9: digitalWrite(segA, SEGMENT_ON); digitalWrite(segB, SEGMENT_ON); digitalWrite(segC, SEGMENT_ON);
            digitalWrite(segD, SEGMENT_ON); digitalWrite(segE, SEGMENT_OFF); digitalWrite(segF, SEGMENT_ON);
            digitalWrite(segG, SEGMENT_ON); break;
    case 10: // Alle aus
            digitalWrite(segA, SEGMENT_OFF); digitalWrite(segB, SEGMENT_OFF); digitalWrite(segC, SEGMENT_OFF);
            digitalWrite(segD, SEGMENT_OFF); digitalWrite(segE, SEGMENT_OFF); digitalWrite(segF, SEGMENT_OFF);
            digitalWrite(segG, SEGMENT_OFF); break;
  }
}

Schaltplan

Arduino Echtzeituhr LED-Uhr: Zuverlässige Zeitanzeige selbst bauen

Herstellungsprozess

  1. Arduino POV-Uhr: Persistence-of-Vision LED-Display selbst bauen
  2. DIY Arduino Word Clock – Elegante Wortuhr mit RTC & Schieberegistern
  3. 20-kHz-Arduino-Oszilloskop mit Nokia 5110 LCD – Einfacher DIY-Bau
  4. Einen eigenen LED-Master-Clock mit Alarm bauen – aus 12 Metern Entfernung ablesbar
  5. Intelligente Jalousien: Automatische Lichtsteuerung mit Arduino & Solarenergie
  6. Italienische Word Clock mit Arduino Nano, NeoPixel, LCD & RTC
  7. LED per Bluetooth mit Arduino steuern – Einfache DIY-Anleitung
  8. Intelligenten Arduino-Vierbeiner-Roboter bauen: Schritt-für-Schritt-Anleitung
  9. Präzise 7-Segment-Uhr mit Arduino Pro Mini & DS1302 RTC – Selbstbau
  10. Isolierter Analogeingang für Arduino: Spannung/Strom galvanisch trennen