Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Mini Reloj Matriz LED – Timepiece con Arduino Nano

Componentes y suministros

Arduino Nano R3 1
Maxim Integrated DS3231M - ±5ppm, I2C Real-Time Clock 1
Pulsador momentáneo 2
Módulo matriz LED 32x8 (MAX7219) 1

Herramientas necesarias

Aplicaciones y servicios online

Sobre este proyecto

En la página "Nick's LED Projects" encontré un proyecto de reloj que muestra la hora en 4 matrices de 8x8 LEDs. Lo construyó con matrices del kit DIY de "ICStation".

Con un cambio mínimo en el código, hice mi reloj con el módulo de matriz de puntos MAX7219 32x8 (cuatro en uno) que viene completamente plegado y es mucho más barato. Lo compré en AliExpress.

El reloj tiene muchas funciones:

Mini Reloj Matriz LED – Timepiece con Arduino Nano

Como ves en el circuito, aparte de las matrices necesitamos una placa Arduino, un módulo RTC (reloj tiempo real) y dos pulsadores para ajustes. Puedes descargar librerías y código modificado en los enlaces de abajo.

Código

Código principal (Arduino)

/*********************************************************************** 
 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
 ***********************************************************************/
// Librerías:
#include "LedControl.h"
#include <FontLEDClock.h> // Librería fuentes
#include <Wire.h>         // DS1307 clock
#include "RTClib.h"        // DS1307 clock
#include <Button.h>       // Librería Botón por Alexander Brevig

// Configuración Matriz LED
// pin 12 → DataIn display
// pin 11 → CLK display
// pin 10 → LOAD display
LedControl lc = LedControl(12, 11, 10, 4); // 3 pines y 4 displays (máx 8)

// Variables globales
byte intensity = 7;        // Brillo por defecto (0-15)
byte clock_mode = 0;       // Modo reloj por defecto. 0 = basic_mode
bool random_mode = 0;      // Modo aleatorio - cambia display cada pocas horas. 0 = off
byte old_mode = clock_mode; // Guarda modo previo para volver tras mostrar fecha
bool ampm = 0;             // 12 o 24 horas. 0 = 24h, 1 = 12h
byte change_mode_time = 0; // Hora en que cambiará modo si random_mode
unsigned long delaytime = 500;
int rtc[7];                // Array para salida RTC
char days[7][4] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
char daysfull[7][9] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
char suffix[4][3] = { "st", "nd", "rd", "th" }; // Sufijos fecha: 1st, 2nd...

#define NUM_DISPLAY_MODES 3
#define NUM_SETTINGS_MODES 4
#define SLIDE_DELAY 20 // ms por carácter en slide
#define cls clear_display

RTC_DS1307 ds1307;
Button buttonA = Button(2, BUTTON_PULLUP);
Button buttonB = Button(3, BUTTON_PULLUP);

void setup() {
  digitalWrite(2, HIGH); digitalWrite(3, HIGH); digitalWrite(4, HIGH);
  Serial.begin(9600);
  int devices = lc.getDeviceCount();
  for (int address = 0; address < devices; address++) {
    lc.shutdown(address, false);
    lc.setIntensity(address, intensity);
    lc.clearDisplay(address);
  }
  #ifdef AVR
  Wire.begin();
  #else
  Wire1.begin(); // Shield I2C pines en bus alternativo Arduino
  #endif
  ds1307.begin();
  if (!ds1307.isrunning()) {
    Serial.println("RTC NO funciona!");
    ds1307.adjust(DateTime(__DATE__, __TIME__));
  }
  printver();
  digitalWrite(13, HIGH); // LED rojo encendido
}

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;
  }
}

// Dibuja un punto en display
void plot(byte x, byte y, byte val) {
  byte address;
  if (x >= 0 && x <= 7) address = 3;
  else if (x >= 8 && x <= 15) { address = 2; x -= 8; }
  else if (x >= 16 && x <= 23) { address = 1; x -= 16; }
  else if (x >= 24 && x <= 31) { address = 0; x -= 24; }
  lc.setLed(address, y, x, val == 1);
}

void clear_display() {
  for (byte address = 0; address < 4; address++) lc.clearDisplay(address);
}

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);
}

void printver() {
  byte i = 0;
  char ver_a[9] = "Vers 1.0";
  char ver_b[9] = " Hello! ";
  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();
}

// puttinychar - copia glifo 3x5 de myfont a memoria display
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);
    }
  }
}

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 - hora en caracteres 3x5 con segundos
void small_mode() {
  char textchar[8];
  byte mins = 100, secs = rtc[0], 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 - hora en caracteres 5x7
void basic_mode() {
  cls();
  char buffer[3];
  byte offset = 0, 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 - como basic_mode pero con efecto deslizante
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();
}

// slideanim - dibuja frame de animación deslizante
void slideanim(byte x, byte y, byte sequence, char current_c, char new_c) {
  if (sequence < 7) {
    byte dots, curr_char_row_max = 7 - sequence, start_y = sequence;
    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;
    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, newcharrowmin = 6 - (sequence - 2), start_y = 0;
    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;
    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 - reloj con palabras en lugar de números
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, 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 {
        strcpy(str_a, numbers[hours - 1]);
        strcpy(str_b, "O'CLOCK");
        strcpy(str_c, "");
      }
      byte len = 0, offset_top, i = 0, counter;
      while (str_a[len]) len++;
      offset_top = (31 - ((len - 1) * 4)) / 2;
      while (str_a[i]) { puttinychar((i * 4) + offset_top, 1, str_a[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_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 - muestra día, fecha y mes con cursor parpadeante
void display_date() {
  cls();
  byte dow = rtc[3], date = rtc[4], month = rtc[5] - 1;
  char monthnames[12][9] = { "January", "February", "March", "April", "May", "June", "July", "August", "Sept", "October", "November", "December" };
  byte len = 0, offset, i = 0;
  while (daysfull[dow][len]) len++;
  offset = (31 - ((len - 1) * 4)) / 2;
  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;
  puttinychar(0 + offset, 1, buffer[0]);
  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();
}

// switch_mode - menú para cambiar modo reloj
void switch_mode() {
  old_mode = clock_mode;
  char* modes[] = { "Basic", "Small", "Slide", "Words", "Setup" };
  byte next_clock_mode, 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);
  }
}

byte run_mode() {
  if (random_mode) {
    if (change_mode_time == rtc[2]) {
      set_next_random();
      return 0;
    }
  }
  return 1;
}

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);
}

// setup_menu - menú ajustes
void setup_menu() {
  char* set_modes[] = { "Rndom", "24 Hr", "Set", "Brght", "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;
}

void set_random() {
  cls();
  char text_a[9] = "Off", 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);
}

void set_ampm() {
  ampm ^= 1;
  cls();
}

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; else intensity++;
      cls();
      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);
    }
  }
}

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);
}

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();
}

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;
}

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=Domingo
  rtc[2] = now.hour(); rtc[1] = now.minute(); rtc[0] = now.second();
}

Librerías

Descarga directa (sin previsualización).

Esquemático

Mini Reloj Matriz LED – Timepiece con Arduino Nano

Proceso de manufactura

  1. Reloj de cuco: historia, artesanía y evolución moderna
  2. Juego de Batalla Contra Jefe con Arduino Mini – Proyecto Retro
  3. Construye un Reloj Maestro LED Personalizado con Alarma – Visible desde 12 Metros
  4. Construye un Reloj Berlín con Arduino UNO – Reloj de Matriz LED DIY
  5. Reloj analógico por persistencia de visión (POV) con Arduino Nano – Proyecto DIY
  6. Pantalla LED Matricial Interactiva en Puerta con Sensor PIR - Saludo Navideño Arduino
  7. Pantalla de 8 LED activada por sonido con Arduino
  8. Construye un Robot Cuadrúpedo Inteligente con Arduino: Guía Paso a Paso
  9. Lámpara Matriz LED con Pistola de Pegamento Caliente – Construye tu Propia Pantalla Colorida
  10. Construye un Secuenciador LED con Temporizador 555 y Contador 4017 – División de Frecuencia y Antirrebote
  11. Matrices en MATLAB: Creación, Referenciación y Manipulación de Datos