Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

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

Applications et services en ligne

À 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 :

Mini horloge à matrice LED – Montre Arduino Nano

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

Mini horloge à matrice LED – Montre Arduino Nano

Processus de fabrication

  1. Séquenceur LED avec timer 555 et compteur 4017 — Division de fréquence et anti-rebond
  2. L'Horloge à Coucou : Histoire, Artisanat et Évolution Moderne
  3. Maîtriser les matrices MATLAB : Création, indexation et manipulation
  4. Jeu Arduino "Mini Boss Battle" – Projet rétro inspiré
  5. Construire une horloge maître LED personnalisée avec alarme – Visible à 12 mètres
  6. Construire une Horloge de Berlin avec Arduino UNO – Horloge à Matrice LED DIY
  7. Horloge à persistance rétinienne (POV) style analogique — Arduino Nano 17 LEDs
  8. Affichage LED matrice interactif porte avec capteur PIR - Salutations fêtes Arduino
  9. Affichage lumineux 8 LED activé par le son