Mini horloge à matrice LED – Montre Arduino Nano
Composants et fournitures
| Composant | Quantité |
|---|---|
| Arduino Nano R3 | 1 |
| Maxim Integrated DS3231M - ±5ppm, I2C RTC | 1 |
| Bouton poussoir momentané | 2 |
| Module matrice LED 32x8 (MAX7219) | 1 |
Outils et machines nécessaires
- Fer à souder (standard)
Applications et services en ligne
- Arduino IDE
À propos de ce projet
Sur la page « Nick's LED Projects », j'ai trouvé un projet d'horloge affichant l'heure sur 4 matrices 8x8. Il l'a construit avec des matrices du magasin « ICStation » qui vend des kits de panneaux de matrices DIY.
Avec une modification minime du code, j'ai réalisé mon horloge avec un module matrice à points MAX7219 4-en-1 (32x8) complètement assemblé et bien moins cher. Acheté sur AliExpress.
L'horloge offre de nombreuses fonctionnalités :
- Mode basique avec grands chiffres
- Mode défilement où les chiffres défilent
- Mode petits chiffres avec secondes
- Heure en toutes lettres, ex: « dix heures douze »
- Affichage de la date
- Option 12/24 heures
- Option luminosité
- Mode aléatoire changeant le mode d'affichage toutes les quelques heures
- Menus pilotés par boutons poussoirs pour configuration et sélection d'affichage
Comme on le voit sur le schéma, hormis les matrices, il faut : une carte Arduino, un module RTC (horloge temps réel), et deux boutons poussoirs pour les réglages. Bibliothèques et code modifié disponibles aux liens ci-dessous.
Code
Code Arduino (Mini Clock v1.0, Juillet 2014 par Nick Hall, GPL)
/***********************************************************************
Mini Clock v1.0, Jul 2014 by Nick Hall
Distributed under the terms of the GPL.
For help on how to build the clock see my blog: https://123led.wordpress.com/
Tested on IDE v1.6.5
***********************************************************************/
// Bibliothèques :
#include "LedControl.h"
#include <FontLEDClock.h> // Bibliothèque de polices
#include <Wire.h> // Horloge DS1307
#include "RTClib.h" // Horloge DS1307
#include <Button.h> // Bibliothèque bouton par Alexander Brevig
// Configuration matrice LED
// Broche 12 = DataIn sur l'affichage
// Broche 11 = CLK sur l'affichage
// Broche 10 = LOAD sur l'affichage
LedControl lc = LedControl(12, 11, 10, 4); // 3 broches + 4 afficheurs (max 8)
// Variables globales
byte intensity = 7; // Luminosité par défaut (0-15)
byte clock_mode = 0; // Mode d'affichage par défaut. 0 = basic_mode
bool random_mode = 0; // Mode aléatoire - change le type d'affichage toutes les quelques heures. 0 = désactivé
byte old_mode = clock_mode; // Mémorise le mode précédent pour y revenir après date etc.
bool ampm = 0; // 12 ou 24h. 0 = 24h, 1 = 12h
byte change_mode_time = 0; // Heure du prochain changement de mode si mode aléatoire
unsigned long delaytime = 500; // Délai entre mises à jour affichage
int rtc[7]; // Sortie RTC
char days[7][4] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; // Jours abrégés (DS1307: 1-7)
char daysfull[7][9] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
char suffix[4][3] = { "st", "nd", "rd", "th" }; // Suffixe date (1st, 2nd...)
#define NUM_DISPLAY_MODES 3
#define NUM_SETTINGS_MODES 4
#define SLIDE_DELAY 20 // ms par caractère pour effet slide
#define cls clear_display
RTC_DS1307 ds1307;
Button buttonA = Button(2, BUTTON_PULLUP); // Bouton A (broche 2)
Button buttonB = Button(3, BUTTON_PULLUP); // Bouton B (broche 3)
void setup() {
digitalWrite(2, HIGH); // Pullup bouton broche 2
digitalWrite(3, HIGH); // Pullup bouton broche 3
digitalWrite(4, HIGH); // Pullup bouton broche 4
Serial.begin(9600);
// Initialisation 4 panneaux matrice
int devices = lc.getDeviceCount();
for (int address = 0; address < devices; address++) {
lc.shutdown(address, false); // Sortie mode économie
lc.setIntensity(address, intensity);
lc.clearDisplay(address);
}
// RTC DS1307
#ifdef AVR
Wire.begin();
#else
Wire1.begin(); // Shield I2C sur bus alt Arduino
#endif
ds1307.begin();
if (!ds1307.isrunning()) {
Serial.println("RTC ne tourne pas !");
ds1307.adjust(DateTime(__DATE__, __TIME__)); // RTC à l'heure de compilation
}
printver(); // Version + message bienvenue
digitalWrite(13, HIGH); // LED rouge
}
void loop() {
switch (clock_mode) {
case 0: basic_mode(); break;
case 1: small_mode(); break;
case 2: slide(); break;
case 3: word_clock(); break;
case 4: setup_menu(); break;
}
}
// Allumer/éteindre un point sur l'affichage
void plot(byte x, byte y, byte val) {
byte address;
if (x >= 0 && x <= 7) { address = 3; }
if (x >= 8 && x <= 15) { address = 2; x -= 8; }
if (x >= 16 && x <= 23) { address = 1; x -= 16; }
if (x >= 24 && x <= 31) { address = 0; x -= 24; }
if (val == 1) { lc.setLed(address, y, x, true); }
else { lc.setLed(address, y, x, false); }
}
// Effacer l'écran
void clear_display() {
for (byte address = 0; address < 4; address++) { lc.clearDisplay(address); }
}
// Fondu vers le noir
void fade_down() {
for (byte i = intensity; i > 0; i--) {
for (byte address = 0; address < 4; address++) { lc.setIntensity(address, i); }
delay(30);
}
clear_display();
for (byte address = 0; address < 4; address++) { lc.setIntensity(address, intensity); }
}
// Test LEDs + affichage version logicielle
void printver() {
byte i = 0;
char ver_a[9] = "Vers 1.0";
char ver_b[9] = " Hello! ";
// Test tous LEDs
for (byte x = 0; x <= 31; x++) {
for (byte y = 0; y <= 7; y++) { plot(x, y, 1); }
}
delay(500);
fade_down();
while (ver_a[i]) { puttinychar((i * 4), 1, ver_a[i]); delay(35); i++; }
delay(700);
fade_down();
i = 0;
while (ver_b[i]) { puttinychar((i * 4), 1, ver_b[i]); delay(35); i++; }
delay(700);
fade_down();
}
// Afficher un caractère tiny 3x5
void puttinychar(byte x, byte y, char c) {
byte dots;
if (c >= 'A' && c <= 'Z' || (c >= 'a' && c <= 'z')) { c &= 0x1F; }
else if (c >= '0' && c <= '9') { c = (c - '0') + 32; }
else if (c == ' ') { c = 0; }
else if (c == '.') { c = 27; }
else if (c == ':') { c = 28; }
else if (c == '\'') { c = 29; }
else if (c == '!') { c = 30; }
else if (c == '?') { c = 31; }
for (byte col = 0; col < 3; col++) {
dots = pgm_read_byte_near(&mytinyfont[c][col]);
for (char row = 0; row < 5; row++) {
if (dots & (16 >> row)) plot(x + col, y + row, 1);
else plot(x + col, y + row, 0);
}
}
}
// Afficher un caractère normal 5x7
void putnormalchar(byte x, byte y, char c) {
byte dots;
if (c >= 'A' && c <= 'Z') { c &= 0x1F; }
else if (c >= 'a' && c <= 'z') { c = (c - 'a') + 41; }
else if (c >= '0' && c <= '9') { c = (c - '0') + 31; }
else if (c == ' ') { c = 0; }
else if (c == '.') { c = 27; }
else if (c == '\'') { c = 28; }
else if (c == ':') { c = 29; }
else if (c == '>') { c = 30; }
else if (c >= -80 && c <= -67) { c *= -1; }
for (char col = 0; col < 5; col++) {
dots = pgm_read_byte_near(&myfont[c][col]);
for (char row = 0; row < 7; row++) {
if (dots & (64 >> row)) plot(x + col, y + row, 1);
else plot(x + col, y + row, 0);
}
}
}
// small_mode : heure en petits caractères 3x5 avec secondes
void small_mode() {
char textchar[8];
byte mins = 100;
byte secs = rtc[0];
byte old_secs = secs;
cls();
while (run_mode()) {
get_time();
if (buttonA.uniquePress()) { switch_mode(); return; }
if (buttonB.uniquePress()) { display_date(); return; }
secs = rtc[0];
if (secs != old_secs) {
char buffer[3];
itoa(secs, buffer, 10);
if (secs < 10) { buffer[1] = buffer[0]; buffer[0] = '0'; }
puttinychar(20, 1, ':'); puttinychar(24, 1, buffer[0]); puttinychar(28, 1, buffer[1]);
old_secs = secs;
}
if (mins != rtc[1]) {
mins = rtc[1];
byte hours = rtc[2];
if (hours > 12) hours -= ampm * 12;
if (hours < 1) hours += ampm * 12;
char buffer[3];
itoa(hours, buffer, 10);
if (hours < 10) { buffer[1] = buffer[0]; buffer[0] = ampm ? ' ' : '0'; }
textchar[0] = buffer[0]; textchar[1] = buffer[1]; textchar[2] = ':';
itoa(mins, buffer, 10);
if (mins < 10) { buffer[1] = buffer[0]; buffer[0] = '0'; }
textchar[3] = buffer[0]; textchar[4] = buffer[1];
textchar[5] = ':'; itoa(secs, buffer, 10);
if (secs < 10) { buffer[1] = buffer[0]; buffer[0] = '0'; }
textchar[6] = buffer[0]; textchar[7] = buffer[1];
for (byte x = 0; x < 6; x++) { puttinychar(x * 4, 1, textchar[x]); }
}
delay(50);
}
fade_down();
}
// basic_mode : heure en caractères 5x7
void basic_mode() {
cls();
char buffer[3];
byte offset = 0;
byte x, y;
byte hours = rtc[2];
if (hours > 12) hours -= ampm * 12;
if (hours < 1) hours += ampm * 12;
if (ampm && hours < 10) offset = 2;
byte secs = 100, mins = 100;
int count = 0;
while (run_mode()) {
get_time();
if (buttonA.uniquePress()) { switch_mode(); return; }
if (buttonB.uniquePress()) { display_date(); return; }
if (secs != rtc[0]) {
secs = rtc[0];
plot(15 - offset, 2, 1); plot(15 - offset, 5, 1);
count = 400;
}
if (count == 0) { plot(15 - offset, 2, 0); plot(15 - offset, 5, 0); }
else { count--; }
if (mins != rtc[1]) {
mins = rtc[1]; hours = rtc[2];
if (hours > 12) hours -= ampm * 12;
if (hours < 1) hours += ampm * 12;
itoa(hours, buffer, 10);
if (hours < 10) { buffer[1] = buffer[0]; buffer[0] = '0'; }
if (ampm && hours < 10) {
offset = 2;
if (hours == 1 && mins == 0) cls();
} else {
offset = 0;
if (hours == 10 && mins == 0) cls();
putnormalchar(1, 0, buffer[0]);
}
putnormalchar(7 - offset, 0, buffer[1]);
itoa(mins, buffer, 10);
if (mins < 10) { buffer[1] = buffer[0]; buffer[0] = '0'; }
putnormalchar(19 - offset, 0, buffer[0]);
putnormalchar(25 - offset, 0, buffer[1]);
}
}
fade_down();
}
// slide : comme basic_mode avec effet défilement
void slide() {
byte digits_old[4] = {99, 99, 99, 99};
byte digits_new[4];
byte digits_x_pos[4] = {25, 19, 7, 1};
char old_char[2], new_char[2];
cls();
putnormalchar(13, 0, ':');
byte old_secs = rtc[0];
while (run_mode()) {
get_time();
if (buttonA.uniquePress()) { switch_mode(); return; }
if (buttonB.uniquePress()) { display_date(); return; }
if (rtc[0] != old_secs) {
old_secs = rtc[0];
byte hours = rtc[2];
if (hours > 12) hours -= ampm * 12;
if (hours < 1) hours += ampm * 12;
digits_new[0] = rtc[1] % 10;
digits_new[1] = (rtc[1] / 10) % 10;
digits_new[2] = hours % 10;
digits_new[3] = (hours / 10) % 10;
for (byte i = 0; i <= 3; i++) {
if (digits_old[i] != digits_new[i]) {
for (byte seq = 0; seq <= 8; seq++) {
itoa(digits_old[i], old_char, 10);
itoa(digits_new[i], new_char, 10);
if (ampm && i == 3) {
if (digits_new[3] == 0) new_char[0] = ' ';
if (digits_old[3] == 0) old_char[0] = ' ';
}
slideanim(digits_x_pos[i], 0, seq, old_char[0], new_char[0]);
delay(SLIDE_DELAY);
}
}
}
for (byte i = 0; i <= 3; i++) digits_old[i] = digits_new[i];
}
}
fade_down();
}
// Animation slide pour un caractère
void slideanim(byte x, byte y, byte sequence, char current_c, char new_c) {
if (sequence < 7) {
byte dots;
if (current_c >= 'A' && current_c <= 'Z') current_c &= 0x1F;
else if (current_c >= 'a' && current_c <= 'z') current_c = (current_c - 'a') + 41;
else if (current_c >= '0' && current_c <= '9') current_c = (current_c - '0') + 31;
else if (current_c == ' ') current_c = 0;
else if (current_c == '.') current_c = 27;
else if (current_c == '\'') current_c = 28;
else if (current_c == ':') current_c = 29;
else if (current_c == '>') current_c = 30;
byte curr_char_row_max = 7 - sequence;
byte start_y = sequence;
for (byte curr_char_row = 0; curr_char_row <= curr_char_row_max; curr_char_row++) {
for (byte col = 0; col < 5; col++) {
dots = pgm_read_byte_near(&myfont[current_c][col]);
if (dots & (64 >> curr_char_row)) plot(x + col, y + start_y, 1);
else plot(x + col, y + start_y, 0);
}
start_y++;
}
}
if (sequence >= 1 && sequence <= 8) {
for (byte col = 0; col < 5; col++) plot(x + col, y + (sequence - 1), 0);
}
if (sequence >= 2) {
byte dots;
if (new_c >= 'A' && new_c <= 'Z') new_c &= 0x1F;
else if (new_c >= 'a' && new_c <= 'z') new_c = (new_c - 'a') + 41;
else if (new_c >= '0' && new_c <= '9') new_c = (new_c - '0') + 31;
else if (new_c == ' ') new_c = 0;
else if (new_c == '.') new_c = 27;
else if (new_c == '\'') new_c = 28;
else if (new_c == ':') new_c = 29;
else if (new_c == '>') new_c = 30;
byte newcharrowmin = 6 - (sequence - 2);
byte start_y = 0;
for (byte newcharrow = newcharrowmin; newcharrow <= 6; newcharrow++) {
for (byte col = 0; col < 5; col++) {
dots = pgm_read_byte_near(&myfont[new_c][col]);
if (dots & (64 >> newcharrow)) plot(x + col, y + start_y, 1);
else plot(x + col, y + start_y, 0);
}
start_y++;
}
}
}
// word_clock : heure en mots
void word_clock() {
cls();
char numbers[19][10] = { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" };
char numberstens[5][7] = { "ten", "twenty", "thirty", "forty", "fifty" };
char str_a[8], str_b[8], str_c[8];
byte hours = rtc[2];
if (hours > 12) hours -= ampm * 12;
if (hours < 1) hours += ampm * 12;
get_time();
byte old_mins = 100;
byte mins;
while (run_mode()) {
if (buttonA.uniquePress()) { switch_mode(); return; }
if (buttonB.uniquePress()) { display_date(); }
get_time();
mins = rtc[1];
if (mins != old_mins) {
old_mins = mins; mins = rtc[1]; hours = rtc[2];
if (hours > 12) hours -= 12;
if (hours == 0) hours = 12;
int minsdigit = rtc[1] % 10;
byte minsdigitten = (rtc[1] / 10) % 10;
if (mins < 10) { strcpy(str_a, numbers[minsdigit - 1]); strcpy(str_b, "PAST"); strcpy(str_c, numbers[hours - 1]); }
else if (mins == 10) { strcpy(str_a, numbers[9]); strcpy(str_b, " PAST"); strcpy(str_c, numbers[hours - 1]); }
else if (minsdigitten != 0 && minsdigit != 0) {
strcpy(str_a, numbers[hours - 1]);
if (mins <= 19) strcpy(str_b, numbers[mins - 1]);
else { strcpy(str_b, numberstens[minsdigitten - 1]); strcpy(str_c, numbers[minsdigit - 1]); }
}
else if (minsdigitten != 0 && minsdigit == 0) { strcpy(str_a, numbers[hours - 1]); strcpy(str_b, numberstens[minsdigitten - 1]); strcpy(str_c, ""); }
else if (minsdigitten == 0 && minsdigit == 0) { strcpy(str_a, numbers[hours - 1]); strcpy(str_b, "O'CLOCK"); strcpy(str_c, ""); }
// Affichage ligne par ligne avec attente
byte len = 0, i = 0, offset_top;
while (str_a[len]) len++;
offset_top = (31 - ((len - 1) * 4)) / 2;
i = 0; while (str_a[i]) { puttinychar((i * 4) + offset_top, 1, str_a[i]); i++; }
int counter = 1000;
while (counter > 0) { if (buttonA.uniquePress()) { switch_mode(); return; } if (buttonB.uniquePress()) { display_date(); } delay(1); counter--; }
fade_down();
len = 0; while (str_b[len]) len++; offset_top = (31 - ((len - 1) * 4)) / 2;
i = 0; while (str_b[i]) { puttinychar((i * 4) + offset_top, 1, str_b[i]); i++; }
counter = 1000; while (counter > 0) { if (buttonA.uniquePress()) { switch_mode(); return; } if (buttonB.uniquePress()) { display_date(); } delay(1); counter--; }
fade_down();
len = 0; while (str_c[len]) len++; offset_top = (31 - ((len - 1) * 4)) / 2;
i = 0; while (str_c[i]) { puttinychar((i * 4) + offset_top, 1, str_c[i]); i++; }
counter = 1000; while (counter > 0) { if (buttonA.uniquePress()) { switch_mode(); return; } if (buttonB.uniquePress()) { display_date(); } delay(1); counter--; }
fade_down();
counter = 1000; while (counter > 0) { if (buttonA.uniquePress()) { switch_mode(); return; } if (buttonB.uniquePress()) { display_date(); } delay(1); counter--; }
}
}
fade_down();
}
// display_date : jour, date, mois avec curseur clignotant
void display_date() {
cls();
byte dow = rtc[3]; byte date = rtc[4]; byte month = rtc[5] - 1;
char monthnames[12][9] = { "January", "February", "March", "April", "May", "June", "July", "August", "Sept", "October", "November", "December" };
byte len = 0, offset = 0, i = 0;
while (daysfull[dow][len]) len++;
offset = (31 - ((len - 1) * 4)) / 2;
i = 0; while (daysfull[dow][i]) { puttinychar((i * 4) + offset, 1, daysfull[dow][i]); i++; }
delay(1000); fade_down(); cls();
char buffer[3]; itoa(date, buffer, 10);
offset = 10; byte s = 3;
if (date == 1 || date == 21 || date == 31) s = 0;
else if (date == 2 || date == 22) s = 1;
else if (date == 3 || date == 23) s = 2;
byte suffixposx = 4;
if (date > 9) { suffixposx = 8; puttinychar(4 + offset, 1, buffer[1]); offset = 8; }
puttinychar(suffixposx + offset, 1, suffix[s][0]);
puttinychar(suffixposx + 4 + offset, 1, suffix[s][1]);
delay(1000); fade_down();
len = 0; while (monthnames[month][len]) len++;
offset = (31 - ((len - 1) * 4)) / 2;
i = 0; while (monthnames[month][i]) { puttinychar((i * 4) + offset, 1, monthnames[month][i]); i++; }
delay(1000); fade_down();
}
// Menu changement mode
void switch_mode() {
old_mode = clock_mode;
char* modes[] = { "Basic", "Small", "Slide", "Words", "Setup" };
byte next_clock_mode; byte firstrun = 1;
for (int count = 0; count < 35; count++) {
if (buttonA.uniquePress() || firstrun == 1) {
count = 0; cls();
if (firstrun == 0) clock_mode++;
if (clock_mode > NUM_DISPLAY_MODES + 1) clock_mode = 0;
char str_top[9]; strcpy(str_top, modes[clock_mode]);
next_clock_mode = clock_mode + 1;
if (next_clock_mode > NUM_DISPLAY_MODES + 1) next_clock_mode = 0;
byte i = 0; while (str_top[i]) { putnormalchar(i * 6, 0, str_top[i]); i++; }
firstrun = 0;
}
delay(50);
}
}
// Vérification mode aléatoire
byte run_mode() {
if (random_mode) {
if (change_mode_time == rtc[2]) { set_next_random(); return 0; }
}
return 1;
}
// Prochain changement mode aléatoire
void set_next_random() {
get_time();
change_mode_time = rtc[2] + random(1, 5);
if (change_mode_time > 23) change_mode_time = random(1, 4);
clock_mode = random(0, NUM_DISPLAY_MODES + 1);
}
// Menu réglages
void setup_menu() {
char* set_modes[] = { "Random", "24 Hr", "Set", "Bright", "Exit" };
if (ampm == 0) set_modes[1] = "12 Hr";
byte setting_mode = 0, next_setting_mode, firstrun = 1;
for (int count = 0; count < 35; count++) {
if (buttonA.uniquePress() || firstrun == 1) {
count = 0; cls();
if (firstrun == 0) setting_mode++;
if (setting_mode > NUM_SETTINGS_MODES) setting_mode = 0;
char str_top[9]; strcpy(str_top, set_modes[setting_mode]);
next_setting_mode = setting_mode + 1;
if (next_setting_mode > NUM_SETTINGS_MODES) next_setting_mode = 0;
byte i = 0; while (str_top[i]) { putnormalchar(i * 6, 0, str_top[i]); i++; }
firstrun = 0;
}
delay(50);
}
switch (setting_mode) {
case 0: set_random(); break;
case 1: set_ampm(); break;
case 2: set_time(); break;
case 3: set_intensity(); break;
case 4: break;
}
clock_mode = old_mode;
}
// Basculer mode aléatoire
void set_random() {
cls();
char text_a[9] = "Off"; char text_b[9] = "On"; byte i = 0;
if (random_mode) { random_mode = 0; while (text_a[i]) { putnormalchar((i * 6), 0, text_a[i]); i++; } }
else { random_mode = 1; set_next_random(); while (text_b[i]) { putnormalchar((i * 6), 0, text_b[i]); i++; } }
delay(1500);
}
// 12/24h
void set_ampm() { ampm ^= 1; cls(); }
// Luminosité
void set_intensity() {
cls(); byte i = 0; char text[7] = "Bright";
while (text[i]) { puttinychar((i * 4) + 4, 0, text[i]); i++; }
while (!buttonA.uniquePress()) {
levelbar(0, 6, (intensity * 2) + 2, 2);
while (buttonB.isPressed()) {
if (intensity == 15) { intensity = 0; cls(); }
else { intensity++; }
i = 0; while (text[i]) { puttinychar((i * 4) + 4, 0, text[i]); i++; }
levelbar(0, 6, (intensity * 2) + 2, 2);
for (byte address = 0; address < 4; address++) lc.setIntensity(address, intensity);
delay(150);
}
}
}
// Barre horizontale
void levelbar(byte xpos, byte ypos, byte xbar, byte ybar) {
for (byte x = 0; x < xbar; x++) for (byte y = 0; y <= ybar; y++) plot(x + xpos, y + ypos, 1);
}
// Réglage heure/date
void set_time() {
cls(); get_time();
byte set_min = rtc[1], set_hr = rtc[2], set_date = rtc[4], set_mnth = rtc[5]; int set_yr = rtc[6];
set_date = set_value(2, set_date, 1, 31);
set_mnth = set_value(3, set_mnth, 1, 12);
set_yr = set_value(4, set_yr, 2013, 2099);
set_hr = set_value(1, set_hr, 0, 23);
set_min = set_value(0, set_min, 0, 59);
ds1307.adjust(DateTime(set_yr, set_mnth, set_date, set_hr, set_min));
cls();
}
// Fonction générique de réglage valeur
int set_value(byte message, int current_value, int reset_value, int rollover_limit) {
cls();
char messages[6][17] = { "Set Mins", "Set Hour", "Set Day", "Set Mnth", "Set Year" };
byte i = 0; while (messages[message][i]) { puttinychar(i * 4, 1, messages[message][i]); i++; }
delay(2000); cls();
char buffer[5] = " "; itoa(current_value, buffer, 10);
puttinychar(0, 1, buffer[0]); puttinychar(4, 1, buffer[1]); puttinychar(8, 1, buffer[2]); puttinychar(12, 1, buffer[3]);
delay(300);
while (!buttonA.uniquePress()) {
while (buttonB.isPressed()) {
if (current_value < rollover_limit) current_value++; else current_value = reset_value;
itoa(current_value, buffer, 10);
puttinychar(0, 1, buffer[0]); puttinychar(4, 1, buffer[1]); puttinychar(8, 1, buffer[2]); puttinychar(12, 1, buffer[3]);
delay(150);
}
}
return current_value;
}
// Lecture RTC
void get_time() {
DateTime now = ds1307.now();
rtc[6] = now.year(); rtc[5] = now.month(); rtc[4] = now.day();
rtc[3] = now.dayOfWeek(); // 0-6, 0=Dimanche
rtc[2] = now.hour(); rtc[1] = now.minute(); rtc[0] = now.second();
}
Bibliothèques
Téléchargement uniquement (pas d'aperçu).
Schéma électrique
Processus de fabrication
- Séquenceur LED avec timer 555 et compteur 4017 — Division de fréquence et anti-rebond
- L'Horloge à Coucou : Histoire, Artisanat et Évolution Moderne
- Maîtriser les matrices MATLAB : Création, indexation et manipulation
- Jeu Arduino "Mini Boss Battle" – Projet rétro inspiré
- Construire une horloge maître LED personnalisée avec alarme – Visible à 12 mètres
- Construire une Horloge de Berlin avec Arduino UNO – Horloge à Matrice LED DIY
- Horloge à persistance rétinienne (POV) style analogique — Arduino Nano 17 LEDs
- Affichage LED matrice interactif porte avec capteur PIR - Salutations fêtes Arduino
- Affichage lumineux 8 LED activé par le son