Сборка Берлинских часов на Arduino UNO — LED-матричные часы своими руками
Компоненты и материалы
| Компонент | Количество | Примечание |
|---|---|---|
| Arduino UNO | 1 | |
| MAX7219 (драйвер LED-матриц) | 1 | Только сама микросхема, используется в модулях матриц |
| Модуль RTC (DS1307) | 1 | Часы реального времени |
| LED 5 мм жёлтый | 13 | Ряды часов и минут×5 |
| LED 5 мм красный | 11 | Ряды единичных часов и минут (можно RGB) |
| Резистор 10 кОм | 1 | Для установки тока MAX7219 (Iset) |
О проекте
Это адаптация туториала с Instructables. Берлинские часы (Mengenlehreuhr) — вероятно, первые цифровые часы в истории (с 1975 г.). Подробности: Wikipedia.
Как читать время
Четыре ряда ламп:
- Верхний ряд — часы ×5 (каждая лампа = 5 часов)
- Второй ряд — единичные часы (1–4)
- Третий ряд — минуты ×5 (каждая = 5 мин, 11 ламп)
- Нижний ряд — единичные минуты (1–4)
- Крупная лампа сверху мигает каждую секунду
Пример на фото: 2×5 + 3 = 13 часов; 6×5 + 2 = 32 минуты → 13:32. Формат 24-часовой.
Шаг 1: Электроника
- Arduino UNO
- RTC DS1307 (I2C: A4=SDA, A5=SCL)
- Светодиоды: 13 жёлтых, 11 красных (или RGB вместо красных)
- Макетная плата / пайка на дырковую плату (Eurocard)
- Резисторы: 220 Ом (секундная LED), 68 кОм (Iset MAX7219)
- MAX7219 — драйвер 8-разрядных 7-сегментных индикаторов, здесь управляет строками LED
- Библиотека LedControl
Шаг 2: Подключение
Схема подключения MAX7219:
- Пины 4, 9 → GND
- Пин 19 → VCC
- Пин 18 (Iset) → VCC через 68 кОм (ограничение тока выходов). С 20 кОм через 10 мин гасло, 68 кОм работает сутками. Яркость красных и жёлтых немного отличается (красные — RGB).
- Пин 1 (DIN) → Arduino D12
- Пин 12 (LOAD/CS) → Arduino D10
- Пин 13 (CLK) → Arduino D11
Выходы MAX7219:
- DIG 0–4 — управление строками LED (строка минут×5 использует DIG 1 и DIG 2, так как 11 LED)
- SEG A–G, DP — сегменты, получают байты-маски (например, B01010100). Важно: DP — старший бит (MSB), а не младший!


Шаг 3: Схема светодиодов
Все LED в строке соединены общим анодом к DIG-выходу, катоды — к соответствующим SEG-выходам через токоограничивающие резисторы (не показаны на схеме, но нужны). Секундная LED — прямо на D13 через 220 Ом.


Шаг 4: Программный код
#include <LedControl.h>
#include <Wire.h>
const int DS1307 = 0x68;
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;
byte nul=B0000000, een=B01000000, twee=B01100000, drie=B01110000, vier=B01111000;
byte vijf=B01111100, zes=B01111110, zeven=B01111111, acht=B11111111;
byte negen=B01000000, tien=B01100000, elf=B01110000;
int a=0, b=0, c=0, vijfMinTwee=0, uitgang=LOW;
LedControl lc=LedControl(12, 11, 10, 1); // DIN, 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);
lc.clearDisplay(0);
}
void loop() {
readTime();
digitalWrite(Led, uitgang);
if (second != lastSecond) {
uitgang = (uitgang == LOW) ? HIGH : LOW;
digitalWrite(Led, uitgang);
lastSecond = second;
}
if (minute != lastMinute) {
printTime();
lastMinute = minute;
}
}
byte bcdToDec(byte val) { return (val/16*10) + (val%16); }
void printTime() {
long minuten = minute, uren = hour;
int vijfmin = minuten/5, eenminuut = minuten - vijfmin*5;
int vijfuren = uren/5, 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);
lc.setRow(0, 3, eenuren);
lc.setRow(0, 1, vijfmin);
lc.setRow(0, 2, vijfMinTwee);
lc.setRow(0, 0, eenminuut);
}
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;
}
}
Код читает RTC, переводит время в формат Берлинских часов и отправляет битовые маски в MAX7219 через LedControl. Переменные на holandском: vijfuren (пять часов), vijfminuten (пять минут) и т.д. В качестве бонуса — учитесь считать по-холландски от 0 до 11! 😉
Библиотека LedControl
https://github.com/wayoda/LedControl
Производственный процесс
- Освоение расчётов временной постоянной для RC и RL цепей
- Кукушка: история, мастерство и современная эволюция
- Песочные часы: история, ремесло и современная привлекательность
- Эволюция хронометрии: от солнечных часов к точным кварцевым часам
- Освоение Python time.sleep(): лучшие практики, многопоточность и реальные примеры
- Rpibot: Дешёвая расширяемая мобильная платформа для изучения встроенных систем
- Arduino POV-часы: сборка дисплея на эффекте сохранения образа
- Генератор тактового сигнала в Verilog: проектирование и реализация
- Работа с датами и временем в Python: Практическое руководство
- Бесконечное зеркало-часы: элегантный дизайн и точное время