Bouw een Berlijnse Klok met Arduino UNO – DIY LED-matrix klok
Onderdelen en benodigdheden
| Onderdeel | Aantal | Opmerking |
|---|---|---|
| Arduino UNO | 1 | |
| MAX7219 LED-displaydriver (IC) | 1 | Wordt ook in LED-matrix breakoutboards gebruikt |
| Real Time Clock (RTC) module | 1 | Bijv. DS1307 |
| 5mm LED: Geel | 13 | Voor uren/minuten rijen |
| 5mm LED: Rood | 11 | Voor seconden en accenten (RGB LEDs gebruikt) |
| Weerstand 10k ohm | 1 |
Over dit project
Dit is een project gebaseerd op een tutorial die ik schreef voor Instructables. Laten we beginnen met een niet-zoveel-daagse klok.
Intro: De Berlijnse Klok
De Berlijnse Klok (BerlinUhr of Mengenlehreuhr) was waarschijnlijk de allererste digitale klok. Hij bestaat sinds 1975. Meer info: Wikipedia.
Hoe werkt het? Er zijn vier rijen lampjes:
- Bovenste rij: uren × 5 (elke lamp = 5 uur)
- Tweede rij: enkele uren 1–4
- Derde rij: minuten × 5 (elke lamp = 5 minuten)
- Onderste rij: enkele minuten 1–4
De grote lamp bovenaan knippert elke seconde. Op de foto (één lamp is defect) is de tijd: 2×5 uur + 3 uur + 6×5 minuten + 2 minuten = 13:32. De klok gebruikt 24-uursformaat.
Stap 1: De elektronica
Benodigd: Arduino UNO, RTC-module (DS1307), 13 gele en 11 rode LEDs (5mm), breadboard/experimenteerprint, weerstanden (220Ω voor seconden-LED, 68kΩ voor MAX7219 stroombegrenzing), MAX7219 IC. De LedControl bibliotheek vereenvoudigt het sturen van de MAX7219: GitHub.
Stap 2: Opbouw
Arduino leest de RTC (via I2C: SDA/SCL op A4/A5), rekent de tijd om naar Berlijnse-klok formaat, en stuurt de data naar de MAX7219 (DataIn pin 12, CLK pin 11, LOAD pin 10). De seconden-LED zit op pin 13.
MAX7219 aansluiting:
- Pin 4, 9 → GND
- Pin 19 → VCC
- Pin 18 (ISet) → VCC via 68kΩ weerstand (stroombepaling voor outputs)
- Pin 1 (DataIn) → Arduino pin 12
- Pin 12 (LOAD) → Arduino pin 10
- Pin 13 (CLK) → Arduino pin 11
De 8 digit-uitgangen (DIG 0–7) sturen de LED-rijen aan. De segment-uitgangen (A–G, DP) krijgen binaire patronen via LedControl. Let op: DP is de MSB, niet de LSB – dit vereist aangepaste bitpatronen.
Stap 3: De LEDs
De LEDs worden per rij parallel geschakeld met gemeenschappelijke anode op de DIG-uitgangen en kathodes op de segment-lijnen. De seconden-LED rechtstreeks op pin 13 met 220Ω.
De foto toont 17:47. De onderste rij (minuten) is op breadboard minder duidelijk zichtbaar, maar werkt wel.
Stap 4: De code
#include
#include
const int DS1307 = 0x68; // A5=SCL, A4=SDA
const char* days[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
const char* months[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
byte second = 0, minute = 0, hour = 0, weekday = 0, monthday = 0, month = 0, year = 0;
byte lastMinute = 0, lastSecond = 0;
int Led = 13;
// Binaire patronen voor 0-11 LEDs aan (MSB = DP)
byte nul = B00000000;
byte een = B01000000;
byte twee = B01100000;
byte drie = B01110000;
byte vier = B01111000;
byte vijf = B01111100;
byte zes = B01111110;
byte zeven = B01111111;
byte acht = B11111111;
byte negen = B01000000; // 9 = 8+1
byte tien = B01100000; // 10 = 8+2
byte elf = B01110000; // 11 = 8+3
int a=0, b=0, c=0, vijfMinTwee=0;
int uitgang = LOW;
LedControl lc = LedControl(12, 11, 10, 1); // DataIn, CLK, LOAD, devices
unsigned long delaytime = 100;
void setup() {
Wire.begin();
Serial.begin(9600);
pinMode(Led, OUTPUT);
lc.shutdown(0, false);
lc.setIntensity(0, 8); // Helderheid
lc.clearDisplay(0);
}
void loop() {
readTime();
digitalWrite(Led, uitgang);
// Seconden knipperen
if (second != lastSecond) {
uitgang = (uitgang == LOW) ? HIGH : LOW;
digitalWrite(Led, uitgang);
lastSecond = second;
}
// Minuut gewijzigd? Display updaten
if (minute != lastMinute) {
printTime();
lastMinute = minute;
}
}
byte bcdToDec(byte val) {
return ((val/16*10) + (val%16));
}
void printTime() {
long minuten = minute;
long uren = hour;
int vijfmin = minuten / 5;
int eenminuut = minuten - (vijfmin * 5);
int vijfuren = uren / 5;
int eenuren = uren - (vijfuren * 5);
a = vijfmin; digitaal(); vijfmin = b; vijfMinTwee = c;
a = eenminuut; digitaal(); eenminuut = b;
a = vijfuren; digitaal(); vijfuren = b;
a = eenuren; digitaal(); eenuren = b;
lc.setRow(0, 4, vijfuren); // DIG 4: uren x5
lc.setRow(0, 3, eenuren); // DIG 3: enkele uren
lc.setRow(0, 1, vijfmin); // DIG 1: minuten x5 (deels)
lc.setRow(0, 2, vijfMinTwee); // DIG 2: minuten x5 (rest)
lc.setRow(0, 0, eenminuut); // DIG 0: enkele minuten
}
void readTime() {
Wire.beginTransmission(DS1307);
Wire.write(byte(0));
Wire.endTransmission();
Wire.requestFrom(DS1307, 7);
second = bcdToDec(Wire.read());
minute = bcdToDec(Wire.read());
hour = bcdToDec(Wire.read());
weekday = bcdToDec(Wire.read());
monthday = bcdToDec(Wire.read());
month = bcdToDec(Wire.read());
year = bcdToDec(Wire.read());
}
void digitaal() {
switch (a) {
case 0: b = nul; c = nul; break;
case 1: b = een; c = nul; break;
case 2: b = twee; c = nul; break;
case 3: b = drie; c = nul; break;
case 4: b = vier; c = nul; break;
case 5: b = vijf; c = nul; break;
case 6: b = zes; c = nul; break;
case 7: b = zeven; c = nul; break;
case 8: b = acht; c = nul; break;
case 9: b = acht; c = negen; break;
case 10: b = acht; c = tien; break;
case 11: b = acht; c = elf; break;
}
}
De code is helder gestructureerd. Een leuk bijvoordeel: je leert nu tellen in het Nederlands (nul tot elf)!
Code repository
Productieproces
- Koekeklok: geschiedenis, vakmanschap en moderne evolutie
- De Zandloper: Geschiedenis, Vakmanschap en Moderne Aantrekkingskracht
- De evolutie van tijdmeting: van zonnewijzers tot precisie kwarts horloges
- Rpibot: Een Laag-kost, Uitbreidbare Mobiele Robot voor Embedded Systems Leren
- Arduino POV-klok: Bouw een Persistence-of-Vision LED-display
- Oneindige Spiegel Klok: Oneindige Elegantie Trefst Nauwkeurige Tijd
- Time Constant Berekeningen Beheersen voor RC en RL Circuits
- Verilog Simulatie Technieken voor betrouwbare RTL-verificatie
- Verilog Clock Generator: Ontwerp & Implementatie Gids
- Python's time.sleep() onder de knie krijgen: best practices, multithreading en real-world voorbeelden
- Datums & Tijden in Python Beheersen: Een Praktische Gids