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

Reloj de matriz de 7 segmentos

Componentes y suministros

SparkFun Arduino Pro Mini 328 - 5V / 16MHz
× 1
Reloj en tiempo real (RTC)
Compre un "Módulo de reloj en tiempo real DS1302 para Arduino" y desolde el zócalo ic y el cristal.
× 1
batería CR1220 y soporte
Busque "5 piezas, carcasa negra CR1220 CR1225 Soporte de enchufe para pilas de botón BS-1220-1"
× 1
Condensador 0.1uf 1206 SMD
× 1
Condensador 10uF 1206 SMD Cerámico
× 1
Interruptor táctil, accionado por la parte superior
variante de 12 mm con botones en la parte superior
× 4
Módulo convertidor reductor 3A Mini DC-DC
× 1
Pantalla de cátodo común de 4 dígitos y 7 segmentos de 0,28 pulgadas
× 36
MAX7219 DIP IC
× 18
Buzzer
× 1
Encabezado de la máquina
Necesitas encabezados masculinos y femeninos; por lo general, vienen en tiras de 40, por lo que tendrás 8 tiras de hombre pasadores mecanizados y 8 tiras de enchufes mecanizados hembra
× 1
Toma de corriente CC
Busque "12V DC Power Supply Jack Socket Conector hembra de montaje en panel 5.5 x 2.ODZ2"
× 1

Herramientas y máquinas necesarias

Soldador (genérico)
Impresora 3D (genérica)

Aplicaciones y servicios en línea

Arduino IDE

Acerca de este proyecto

Mientras navegaba por Hackaday.io, me encontré con un hermoso reloj hecho con una serie de pantallas de 7 segmentos de Frugha. Tenía muchas ganas de construir esto, pero la versión de Frugha es bastante grande debido a que usa pantallas de 7 segmentos de 0.56 ". Mi diseño usa pantallas de 7 segmentos de 0.28", lo que lo hace solo una cuarta parte del tamaño.

El software ha sido reescrito para incorporar un despertador y una pantalla de configuración para fijar la hora, la fecha y la alarma.

Video

Pantalla de configuración

El reloj está controlado por cuatro botones. El botón SELECT (superior) mostrará la pantalla de configuración. La selección actual parpadeará. Al presionar el botón SELECT nuevamente, se recorrerán las diferentes secciones de configuración (es decir, Hora, Fecha, Alarma, Sintonización, Brillo, Formato de fecha y Reloj).

Si presiona el botón ENTER (segundo desde arriba) mientras uno de los elementos del menú está seleccionado, podrá cambiar su configuración. Cuando haya más de una configuración para un elemento de menú, el botón ENTER alternará entre ellas. La configuración activa parpadeará.

Cuando una configuración está parpadeando, los botones ARRIBA y ABAJO (dos botones inferiores) cambiarán la configuración.

Pantalla de fecha

Si presiona el botón ENTER (segundo desde arriba) mientras se muestra el reloj, se mostrará la pantalla de fecha durante cinco segundos.

La sección Formato de fecha en la pantalla de configuración le permite establecer el formato de fecha (DD-MM o MM-DD) y la fuente utilizada.

Consideraciones de diseño

Para simplificar el diseño de la placa, mi versión utiliza pantallas de 4 dígitos en lugar de las pantallas de un solo dígito utilizadas en la versión original. Debido a que las pantallas de 0,28 "son pequeñas, tuve que colocar los chips MAX7219 en una placa separada. Para simplemente cablear, se utilizan conectores de clavija macho y hembra mecanizados para conectar las placas,

Los archivos Eagle se han incluido si desea que los tableros se fabriquen comercialmente o haga lo que yo hice y los haga usted mismo. Usé el método Toner para hacer el mío.

Los tableros de la columna

Se deben fabricar seis tableros de columnas que sostienen todas las pantallas. Al soldar los cabezales de la máquina macho, comience con el conjunto del medio y trabaje hasta el borde exterior. Use una cerilla o algo similar para levantar el zócalo lo suficiente para que pueda soldar los pines fácilmente. Utilice un soldador pequeño con una punta fina y una soldadura de 0,5 mm.

Una vez que haya creado los módulos de columna, le recomiendo que pinte el borde de la pantalla con pintura negra mate. Esto evitará que se muestren los bordes blancos si una pantalla no está perfectamente alineada con su vecina. También usando un rotulador, numere cada módulo de columna. Esto ayuda cuando se insertan en la placa base MAX7219.

La placa base MAX7219

Al diseñar la placa base y las placas de columna, no asigné los segmentos o dígitos correctos del MAX7219 a sus pines de visualización correspondientes. Quería mantener el diseño de la PCB lo más simple posible y ajustar cualquier diferencia en el software.

Cuando se trata de enchufes hembra mecanizados, recomiendo que los coloque primero en los pines macho de las placas de la columna y luego suelde el conjunto en su lugar mientras están conectados. Esto significará que los pines de la columna se alinearán exactamente con sus enchufes correspondientes. Si necesita eliminarlos, tener los módulos de columna numerados garantizará que vuelvan a estar en la misma posición.

La placa MPU

La placa del microprocesador contiene todos los demás componentes. Los cuatro botones y dos condensadores SMD están montados en la parte posterior de la placa y todos los demás componentes están montados en la parte frontal de la placa. Para mantener un perfil bajo, el encabezado de clavija FTDI que generalmente está soldado al Arduino Pro Mini ahora está soldado directamente a la PCB. Dos cables van desde los pines DTR y VCC directamente a la PCB.

Exponiendo el caso

Se han incluido los archivos STL para el anverso y el reverso. Ambos se imprimieron con una altura de capa de 0,2 y un borde. El frente también tiene soportes habilitados que solo tocaban la placa de construcción.

La placa base MAX7219 con sus módulos de columna se deslizan desde el frente. Si lo encuentra un poco flojo, use una capa o dos de cinta adhesiva como embalaje.

La placa MPU está pegada en caliente a la parte posterior.

Software

El software requiere que la biblioteca MD_MAX72XX se haya instalado en su IDE de Arduino. He proporcionado mi boceto Hardware_Test_V1 para probarlo. Iluminará cada segmento para que pueda verificar si hay cortocircuitos o cableado roto. Una vez que la pantalla funcione, cargue el boceto Clock_V4.

Código

  • Clock_V4.ino
  • Digits.h
  • Tunes.h
  • Button.h
  • Button.cpp
  • Hardware_Test_V1.zip
Clock_V4.ino C / C ++
 / * --------------------------------------------- ------ * Reloj de matriz de 7 segmentos * * Basado en el reloj de Frugha (https://hackaday.io/project/169632-7-segment-display-array-clock) * * Modificaciones de John Bradnam (jbrad2089 @ gmail.com) * - Se cambió el hardware para usar pantallas de 7 segmentos de 0.28 ". * - El dispositivo MAX7219, el orden de dígitos y segmentos se ha cambiado a simplemente un enrutamiento de placa PCB complejo de otra manera *. * - El hardware usa Arduino Mini Pro, DS1302 RTC y 4 botones pulsadores * - Función de alarma agregada con usic de alarma seleccionable * - Configuración de brillo agregada * - Pantalla de configuración agregada para configurar la hora, la fecha, la alarma, la música y el brillo * - Pantalla de fecha agregada (se muestra durante dos segundos cuando se presiona el botón ENTER * Actualización 2020 -06-16 * - Se agregó la opción de formato de fecha en la pantalla de configuración * - Se aumentó el tiempo de espera de la pantalla de fecha de 2 a 5 segundos * - Se agregó una opción configurable de fuente para la visualización de la fecha * -------------- ------------------------------------ * / #include  #include  #include  # include  #include  #include "button.h" #include "Tunes.h" #include "Digits.h" #define HARDWARE_TYPE MD_MAX72XX ::GENERIC_HW # define MAX_DEVICES 18 # define LED_CLK 13 / / o SCK (WHI) #define LED_DATA 11 // o MOSI (BRN) #define LED_CS 10 // o SS (YEL) #define SPEAKER 2 # define SW_UP 3 # define SW_DOWN 4 # define RTC_CLK 5 # define RTC_IO 6 # define SW_ENTER 7 # define RTC_CE 8 # define SW_SELECT 9DS1302RTC rtc (RTC_CE, RTC_IO, RTC_CLK); // Interfaz de hardware SPIMD_MAX72XX mx =MD_MAX72XX (HARDWARE_TYPE, LED_CS, MAX_DEVICES); // =ArbitXrary_MAX_MD72 LED_CLK, LED_CS, MAX_DEVICES); // Manejo de EEPROM # definir EEPROM_ADDRESS 0 # definir EEPROM_MAGIC 0x0BAD0DADtypedef struct {uint32_t magic; alarma bool; uint8_t minutos; uint8_t horas; bool format12hr; uint8_t brillo; uint8_t tune; bool formatDmy; bool squareFont;} EEPROM_DATA; EEPROM_DATA EepromData; // Configuración actual de EEPROMvoid clockButtonPressed (void); void enterButtonPressed (void); void downButtonPressed (void); void upButtonPressed (void); Button * clockButton; Button * enterButton; Button * downButton; Button * upButton; // Modos de funcionamientobool =inSubMenu false; #define SETUP_FLASH_RATE 200; unsigned long setupTimeout; bool setupDisplayState =false; enum ClockButtonModesEnum {CLOCK, TIME_SET, DATE_SET, ALARM_SET, TUNE_SET, BRIGHT_SET, FORMAT_SET}; ClockButton_SET, FORMAT_SET}; ClockButton_Menum; Enum TimeSET}; timeSetMode =TIME_HOUR; enum DateSetMenuEnum {DATE_YEAR, DATE_MONTH, DATE_DAY}; DateSetMenuEnum dateSetMode =DATE_YEAR; enum AlarmSetMenuEnum {ALARM_HOUR, ALARM_MIN, ALARM_STATE}; AlarmSetMenuEnum alarmSetMode =ALARM_HOUR; enum FormatSetMenuEnum {DAY_MONTH, FONT_STYLE}; FormatSetMenuEnum formatSetMode =DAY_MONTH; int lastSeconds =-1; bool alarmRinging =false; // verdadero cuando la alarma está activada alarmCancelled =false; // alarma cancelada por userbool musicPlaying =false; // verdadero si se reproduce un songbool clockColon =false; // mostrar / ocultar colonint8_t dom [] ={31,28,31,30,31,30,31,31,30,31,30,31}; tmElements_t newTime; // Se usa para almacenar el nuevo timevoid setup () {Serial.begin (115200); // Eprom readEepromData (); // Inicializar botones clockButton =new Button (SW_SELECT); enterButton =nuevo botón (SW_ENTER); downButton =nuevo botón (SW_DOWN); downButton-> Repeat (downButtonPressed); upButton =nuevo botón (SW_UP); upButton-> Repeat (upButtonPressed); // Inicializar el sonido pinMode (ALTAVOZ, SALIDA); mx.begin (); mx.control (MD_MAX72XX ::INTENSIDAD, EepromData.brightness); //0..MAX_INTENSITY mx.update (MD_MAX72XX ::APAGADO); // Sin actualización automática setSyncProvider (rtc.get); // la función para obtener la hora del RTC if (timeStatus ()! =timeSet) {Serial.println ("RTC Sync Bad"); newTime.Year =CalendarYrToTm (2020); newTime.Month =5; newTime.Day =30; newTime.Hour =14; newTime.Minute =53; newTime.Second =0; time_t t =makeTime (hora nueva); setTime (t); rtc.set (t); if (rtc.set (t)! =0) {Serial.println ("Falló la configuración del tiempo"); }} newTime.Year =CalendarYrToTm (año ()); newTime.Month =mes (); newTime.Day =día (); newTime.Hour =hora (); newTime.Minute =minuto (); newTime.Second =segundo (); Serial.println ("Hora:" + Cadena (nuevaHora.Hora) + ":" + Cadena (nuevaTiempo.Minuto) + ":" + Cadena (nuevaTiempo.Segundo)); Serial.println ("Fecha:" + String (newTime.Day) + "/" + String (newTime.Month) + "/" + String (tmYearToCalendar (newTime.Year))); clockMode =CLOCK; showTime (verdadero);} void loop () {testButtons (); if (clockMode ==CLOCK) {showTime (falso); if (EepromData.alarm &&EepromData.hours ==hora () &&EepromData.minutes ==minuto ()) {if (! alarmCancelled) {alarmRinging =true; playSong (melodías [EepromData.tune]); }} else {alarmCancelled =false; alarmRinging =falso; }} else {showSetup (falso); } retraso (100);} // ----------------------------------------- ---------------------- // Prueba si se ha presionado algún botón void testButtons () {// Botones de presión única if (clockButton-> Pressed ()) { clockButtonPressed (); } if (enterButton-> Pressed ()) {enterButtonPressed (); } // No es necesario verificar el resultado de presionado ya que el manejador de botones invocará su función de repetición upButton-> Pressed (); downButton-> Pressed ();} // ---------------------------------------- ----------------------- // Manejar CLOCK bttonvoid clockButtonPressed () {if (cancelAlarm ()) return; inSubMenu =falso; clockMode =(clockMode ==FORMAT_SET)? RELOJ:(ClockButtonModesEnum) ((int) clockMode + 1); if (clockMode ==CLOCK) {Serial.println ("Ahorro de tiempo:" + String (newTime.Hour) + ":" + String (newTime.Minute)); Serial.println ("Desde:" + Cadena (hora ()) + ":" + Cadena (minuto ())); if (newTime.Year! =CalendarYrToTm (year ()) || newTime.Month! =month () || newTime.Day! =day () || newTime.Hour! =hour () || newTime.Minute! =minuto ()) {// Hora de actualización Serial.println ("Actualizando RTC"); newTime.Second =segundo (); time_t t =makeTime (hora nueva); setTime (t); rtc.set (t); if (rtc.set (t)! =0) {Serial.println ("Falló la configuración del tiempo"); }} writeEepromData (); showTime (verdadero); } else {if (clockMode ==TIME_SET) {newTime.Year =CalendarYrToTm (año ()); newTime.Month =mes (); newTime.Day =día (); newTime.Hour =hora (); newTime.Minute =minuto (); newTime.Second =segundo (); Serial.println ("Tiempo de carga:" + Cadena (hora ()) + ":" + Cadena (minuto ())); } showSetup (verdadero); }} // ---------------------------------------------- ----------------- // Manejar ENTER bttonvoid enterButtonPressed () {if (cancelAlarm ()) return; if (clockMode! =CLOCK) {if (! inSubMenu) {timeSetMode =TIME_HOUR; dateSetMode =DATE_YEAR; alarmSetMode =HORA_ALARMA; formatSetMode =DAY_MONTH; inSubMenu =verdadero; } else {switch (clockMode) {case TIME_SET:timeSetMode =(timeSetMode ==TIME_FORMAT)? HORA_HORA:(TimeSetMenuEnum) ((int) timeSetMode + 1); descanso; case DATE_SET:dateSetMode =(dateSetMode ==DATE_DAY)? DATE_YEAR:(DateSetMenuEnum) ((int) dateSetMode + 1); descanso; case ALARM_SET:alarmSetMode =(alarmSetMode ==ALARM_STATE)? HORA_ALARMA:(AlarmSetMenuEnum) ((int) alarmSetMode + 1); descanso; case FORMAT_SET:formatSetMode =(formatSetMode ==FONT_STYLE)? DAY_MONTH:(FormatSetMenuEnum) ((int) formatSetMode + 1); descanso; }} showSetup (verdadero); } else {showDate (día (), mes (), año ()); retraso (5000); }} // ---------------------------------------------- ----------------- // Manejar ABAJO bttonvoid downButtonPressed () {if (cancelAlarm ()) return; switch (clockMode) {case TIME_SET:if (inSubMenu) {switch (timeSetMode) {case TIME_HOUR:newTime.Hour =(newTime.Hour + 24 - 1)% 24; descanso; case TIME_MIN:newTime.Minute =(newTime.Minute + 60 - 1)% 60; descanso; case TIME_FORMAT:EepromData.format12hr =! EepromData.format12hr; descanso; } showSetup (verdadero); } descanso; case DATE_SET:if (inSubMenu) {switch (dateSetMode) {case DATE_YEAR:newTime.Year =((newTime.Year - 30 + 100) - 1)% 100 + 30; descanso; case DATE_MONTH:newTime.Month =((newTime.Month - 1 + 12) - 1)% 12 + 1; descanso; case DATE_DAY:uint8_t md =daysInMonth (newTime.Year, newTime.Month); nuevoDíaHora =((nuevoDíaHora - 1 + md) - 1)% md + 1; descanso; } showSetup (verdadero); } descanso; case ALARM_SET:if (inSubMenu) {switch (alarmSetMode) {case ALARM_HOUR:EepromData.hours =(EepromData.hours + 24 - 1)% 24; descanso; caso ALARM_MIN:EepromData.minutes =(EepromData.minutes + 60 - 1)% 60; descanso; case ALARM_STATE:EepromData.alarm =! EepromData.alarm; descanso; } showSetup (verdadero); } descanso; case TUNE_SET:EepromData.tune =(EepromData.tune + NUM_OF_MELODIES - 1)% NUM_OF_MELODIES; showSetup (verdadero); descanso; case BRIGHT_SET:EepromData.brightness =(EepromData.brightness + MAX_INTENSITY - 1)% MAX_INTENSITY; mx.control (MD_MAX72XX ::INTENSIDAD, EepromData.brightness); //0..MAX_INTENSITY showSetup (verdadero); descanso; case FORMAT_SET:if (inSubMenu) {switch (formatSetMode) {case DAY_MONTH:EepromData.formatDmy =! EepromData.formatDmy; descanso; case FONT_STYLE:EepromData.squareFont =! EepromData.squareFont; descanso; }} showSetup (verdadero); descanso; }} // ---------------------------------------------- ----------------- // Manejar ARRIBA bttonvoid upButtonPressed () {if (cancelAlarm ()) return; switch (clockMode) {case TIME_SET:if (inSubMenu) {switch (timeSetMode) {case TIME_HOUR:newTime.Hour =(newTime.Hour + 1)% 24; descanso; case TIME_MIN:newTime.Minute =(newTime.Minute + 1)% 60; descanso; case TIME_FORMAT:EepromData.format12hr =! EepromData.format12hr; descanso; } showSetup (verdadero); } descanso; case DATE_SET:if (inSubMenu) {switch (dateSetMode) {case DATE_YEAR:newTime.Year =((newTime.Year - 30) + 1)% 100 + 30; descanso; case DATE_MONTH:newTime.Month =((newTime.Month - 1) + 1)% 12 + 1; descanso; case DATE_DAY:uint8_t md =daysInMonth (newTime.Year, newTime.Month); newTime.Day =(newTime.Day% md) + 1; descanso; } showSetup (verdadero); } descanso; case ALARM_SET:if (inSubMenu) {switch (alarmSetMode) {case ALARM_HOUR:EepromData.hours =(EepromData.hours + 1)% 24; descanso; caso ALARM_MIN:EepromData.minutes =(EepromData.minutes + 1)% 60; descanso; case ALARM_STATE:EepromData.alarm =! EepromData.alarm; descanso; } showSetup (verdadero); } descanso; case TUNE_SET:EepromData.tune =(EepromData.tune + 1)% NUM_OF_MELODIES; showSetup (verdadero); descanso; case BRIGHT_SET:EepromData.brightness =(EepromData.brightness + 1)% MAX_INTENSITY; mx.control (MD_MAX72XX ::INTENSIDAD, EepromData.brightness); //0..MAX_INTENSITY showSetup (verdadero); descanso; case FORMAT_SET:if (inSubMenu) {switch (formatSetMode) {case DAY_MONTH:EepromData.formatDmy =! EepromData.formatDmy; descanso; case FONT_STYLE:EepromData.squareFont =! EepromData.squareFont; descanso; }} showSetup (verdadero); descanso; }} // ---------------------------------------------- ----------------- // Apaga la alarma si está sonando un tunebool cancelAlarm () {if (musicPlaying) {musicPlaying =false; alarmCancelled =alarmRinging; devuelve verdadero; } producir(); falso retorno;}//-------------------------------------------- ------------------- // Muestra el menú de configuración y muestra el elemento actual seleccionadovoid showSetup (bool force) {setupDisplayState =setupDisplayState | fuerza; fuerza =fuerza || (millis ()> setupTimeout); if (forzar) {setupTimeout =millis () + SETUP_FLASH_RATE; bool on =setupDisplayState; setupDisplayState =! setupDisplayState; mx.clear (); if (en ||! (clockMode ==TIME_SET &&! inSubMenu)) displayString (0,7, "TINE"); if (en ||! (clockMode ==TIME_SET &&inSubMenu &&timeSetMode ==TIME_HOUR)) displayNumber (0,13, newTime.Hour, 2, true); if (en ||! (clockMode ==TIME_SET &&inSubMenu &&timeSetMode ==TIME_MIN)) displayNumber (0,16, newTime.Minute, 2, true); if (en ||! (clockMode ==TIME_SET &&inSubMenu &&timeSetMode ==TIME_FORMAT)) displayString (0,19, (EepromData.format12hr)? "12HR":"24HR"); if (en ||! (clockMode ==DATE_SET &&! inSubMenu)) displayString (1,7, "FECHA"); if (en ||! (clockMode ==DATE_SET &&inSubMenu &&dateSetMode ==DATE_YEAR)) displayNumber (1,13, tmYearToCalendar (newTime.Year), 4, true); if (en ||! (clockMode ==DATE_SET &&inSubMenu &&dateSetMode ==DATE_MONTH)) displayNumber (1,18, newTime.Month, 2, true); if (en ||! (clockMode ==DATE_SET &&inSubMenu &&dateSetMode ==DATE_DAY)) displayNumber (1,21, newTime.Day, 2, true); if (en ||! (clockMode ==ALARM_SET &&! inSubMenu)) displayString (2,6, "ALARN"); if (en ||! (clockMode ==ALARM_SET &&inSubMenu &&alarmSetMode ==ALARM_HOUR)) displayNumber (2,13, EepromData.horas, 2, verdadero); if (en ||! (clockMode ==ALARM_SET &&inSubMenu &&alarmSetMode ==ALARM_MIN)) displayNumber (2,16, EepromData.minutes, 2, true); if (en ||! (clockMode ==ALARM_SET &&inSubMenu &&alarmSetMode ==ALARM_STATE)) displayString (2,19, (EepromData.alarm)? "ON":"OFF"); if (en ||! (clockMode ==TUNE_SET &&! inSubMenu)) displayString (3,7, "TUNE"); if (en ||! (clockMode ==TUNE_SET &&inSubMenu)) {switch (EepromData.tune) {case 0:displayString (3,13, "ELISE"); descanso; caso 1:displayString (3,13, "RANGE"); descanso; caso 2:displayString (3,13, "SOL"); descanso; }} if (en ||! (clockMode ==BRIGHT_SET &&! inSubMenu)) displayString (4,1, "BRIGHTNESS"); if (en ||! (clockMode ==BRIGHT_SET &&inSubMenu)) displayNumber (4,13, EepromData.brightness, 0, false); if (en ||! (clockMode ==FORMAT_SET &&! inSubMenu)) displayString (5,0, "DATE ​​FORNAT"); if (en ||! (clockMode ==FORMAT_SET &&inSubMenu &&formatSetMode ==DAY_MONTH)) displayString (5,13, ​​(EepromData.formatDmy)? "DD-NN":"NN-DD"); if (en ||! (clockMode ==FORMAT_SET &&inSubMenu &&formatSetMode ==FONT_STYLE)) displayString (5,19, (EepromData.squareFont)? "FONT1":"FONT2"); mx.update (); }} // ---------------------------------------------- ----------------- // Mostrar la hora actual en la pantalla si se cambia // forzar - mostrar siempre la hora incluso si no ha cambiadovoid showTime (bool force) {force =force || (últimos segundos! =segundo ()); if (forzar) {lastSeconds =segundo (); showTime (hora (), minuto (), verdadero, verdadero, (segundo () y 0x01), (clockMode! =CLOCK ||! EepromData.format12hr)); }} // ---------------------------------------------- ----------------- // Muestra la hora en la pantalla // h - hora // m - minuto // he - hora habilita // me - minuto habilita // ce - los dos puntos habilitan void showTime (int h, int m, bool he, bool me, bool ce, bool f24) {mx.clear (); si (él) {si (! f24 &&h> 12) {h =h - 12; } si (h> 9 || f24) {displayLargeDigit (0, h / 10); } displayLargeDigit (5, h% 10); } if (yo) {displayLargeDigit (13, m / 10); displayLargeDigit (18, m% 10); } if (ce) {displayLargeDigit (11, 10); } mx.update ();} // ---------------------------------------- ----------------------- void showDate (int d, int m, int y) {#define XOFS 3 mx.clear (); if (EepromData.formatDmy) {displayDateDigit (XOFS + 0, d / 10); displayDateDigit (XOFS + 4, d% 10); displayDateDigit (XOFS + 8, 10); // dos puntos displayDateDigit (XOFS + 12, m / 10); displayDateDigit (XOFS + 16, m% 10); } else {displayDateDigit (XOFS + 0, m / 10); displayDateDigit (XOFS + 4, m% 10); displayDateDigit (XOFS + 8, 10); // dos puntos displayDateDigit (XOFS + 12, d / 10); displayDateDigit (XOFS + 16, d% 10); } displayNumber (5, 10, y, 0, falso); mx.update ();} // ----------------------------------------- ---------------------- // Escriba un dígito cuadrado o pequeño según el ajuste de configuración // x =0 a 23 // v =dígito grande o cuadrado para display (0..10) void displayDateDigit (uint8_t x, uint8_t v) {if (EepromData.squareFont) {displaySquareDigit (x, v); } else {displaySmallDigit (x, v); }} // ---------------------------------------------- ----------------- // Escriba una máscara de bits de segmento // x =0 a 23 // v =dígito grande para mostrar (0..10) void displayLargeDigit (uint8_t x , uint8_t v) {if (x <24 &&v <11) {for (uint8_t row =0; row <6; row ++) {for (uint8_t col =0; col <6; col ++) {writePhysicalDigit (fila, col + x, pgm_read_byte (&largeDigits [v] [fila] [col]), falso); }}}} // -------------------------------------------- ------------------- // Escriba una máscara de bits de segmento // x =0 a 23 // v =dígito grande para mostrar (0..10) void displaySmallDigit ( uint8_t x, uint8_t v) {if (x <24 &&v <11) {para (uint8_t fila =0; fila <5; fila ++) {para (uint8_t col =0; col <3; col ++) {writePhysicalDigit (fila, col + x, pgm_read_byte (&smallDigits [v] [fila] [col]), falso); }}}} // -------------------------------------------- ------------------- // Escriba una máscara de bits de segmento // x =0 a 23 // v =dígito grande para mostrar (0..10) void displaySquareDigit ( uint8_t col, uint8_t v) {// Orden de segmento defbca _ g uint8_t mask =ascii [v]; if (máscara ==B00000000) {// Máscara de guión =B00000001; } if (máscara &B00000100) {// seg A writePhysicalDigit (0, col + 0, 0xff, false); writePhysicalDigit (0, col + 1, 0xff, falso); writePhysicalDigit (0, col + 2, 0xff, falso); } if (máscara &B00010000) {// seg B writePhysicalDigit (0, col + 2, 0xff, false); writePhysicalDigit (1, col + 2, 0xff, falso); writePhysicalDigit (2, col + 2, 0xff, falso); } if (máscara &B00001000) {// seg C writePhysicalDigit (2, col + 2, 0xff, false); writePhysicalDigit (3, col + 2, 0xff, falso); writePhysicalDigit (4, col + 2, 0xff, falso); } if (máscara &B10000000) {// seg D writePhysicalDigit (4, col + 0, 0xff, false); writePhysicalDigit (4, col + 1, 0xff, falso); writePhysicalDigit (4, col + 2, 0xff, falso); } if (máscara &B01000000) {// seg C writePhysicalDigit (2, col, 0xff, false); writePhysicalDigit (3, col, 0xff, falso); writePhysicalDigit (4, col, 0xff, falso); } if (máscara &B00100000) {// seg E writePhysicalDigit (0, col, 0xff, false); writePhysicalDigit (1, col, 0xff, falso); writePhysicalDigit (2, col, 0xff, falso); } if (máscara &B00000001) {// seg D writePhysicalDigit (2, col + 0, 0xff, false); writePhysicalDigit (2, col + 1, 0xff, falso); writePhysicalDigit (2, col + 2, 0xff, falso); }} // ---------------------------------------------- ----------------- // Escribe una cadena de caracteres uint8_t displayString (uint8_t fila, uint8_t col, String s) {for (int i =0; i  0x5F) {c =0x3F; // Usado como carácter de espacio} c =c - 0x30; writePhysicalDigit (fila, columna, ascii [c], verdadero); col =col + 1; }} // ---------------------------------------------- ----------------- // Escribe un número uint8_t displayNumber (uint8_t fila, uint8_t col, int número, int padding, bool leadingZeros) {if (padding ==0) {padding =(número> 0)? piso (log10 (número)) + 1:1; } col =col + relleno; bool primero =verdadero; para (int i =0; i > 2) * 3 + (fila>> 1); uint16_t c =((uint16_t) dev <<3) | digitMap [dig]; si (! borrar) {v =v | mx.getColumn (c); } mx.setColumn (c, v); }} // ---------------------------------------------- ----------------- // Devuelve los días de un año y mes determinados // Feb tiene 28 a menos que sea un año bisiesto o el cambio de siglo uint8_t daysInMonth (int y, int m) {return dom [m - 1] + ((m ==2 &&(y% 4) ==0 &&(y% 100)! =0)? 1:0);} // ------- -------------------------------------------------- ------ // Escribe la estructura EepromData en EEPROMvoid writeEepromData () {// Esta función usa EEPROM.update () para realizar la escritura, por lo que no reescribe el valor si no cambió. EEPROM.put (EEPROM_ADDRESS, EepromData);} // -------------------------------------- ------------------------- // Lea la estructura EepromData de EEPROM, inicialice si es necesario void readEepromData () {// Eprom EEPROM.get (EEPROM_ADDRESS, EepromData); //Serial.println("magic:"+ String (EepromData.magic, 16) +", alarma:"+ String (EepromData.alarm) +", hora:"+ String (EepromData.hours) +":"+ Cadena (EepromData.minutes) + ", 12 horas:" + Cadena (EepromData.format12hr) + ", brillo:" + Cadena (EepromData.brightness)); if (EepromData.magic! =EEPROM_MAGIC) {Serial.println ("Inicializando EEPROM ..."); EepromData.magic =EEPROM_MAGIC; EepromData.alarm =falso; EepromData.minutes =30; EepromData.horas =5; EepromData.format12hr =falso; EepromData.brightness =8; EepromData.tune =0; EepromData.formatDmy =falso; writeEepromData (); } Serial.println ("alarma:" + String (EepromData.alarm) + ", tiempo:" + String (EepromData.hours) + ":" + String (EepromData.minutes) + ", 12hr:" + String (EepromData .format12hr) + ", brillo:" + String (EepromData.brightness));} // ----------------------------- ---------------------------------- // Toca una melodía en playSong (const uint16_t * melody) {// Toca cada nota de la melodía hasta que se encuentre la nota END_OF_TUNE musicPlaying =true; int thisNote =0; uint16_t noteRaw =pgm_read_word (&melodía [thisNote ++]); while (reproducción de música &¬eRaw! =END_OF_TUNE) {testButtons (); producir(); playNote (noteRaw); noteRaw =pgm_read_word (&melodía [thisNote ++]); } // while delay (50);} // -------------------------------------- ------------------------- // Toque una sola nota void playNote (uint16_t noteRaw) {// para calcular la duración de la nota, tome un segundo dividido por el tipo de nota. // p.ej. negra =1000/4, corchea =1000/8, etc. uint16_t frecuencia =noteRaw &0x1FFF; uint16_t duración =(noteRaw &0xE000)>> 13; si (duración ==7) duración =8; uint16_t noteDuration =1800 / duración; if (frecuencia! =DESCANSO) {tono (ALTAVOZ, frecuencia, notaDuración); } // para distinguir las notas, establezca un tiempo mínimo entre ellas. // la duración de la nota + 30% parece funcionar bien:uint16_t pauseBetweenNotes =(noteDuration * 13) / 10; delay (pauseBetweenNotes); if (frecuencia! =DESCANSO) {// detiene la reproducción del tono:noTone (ALTAVOZ); }} 
Digits.h C / C ++
 / * --------------------------------------------- ------ * Reloj de matriz de 7 segmentos * define cada dígito en una matriz de bytes de 6x6 * ----------------------------- ---------------------*/ #pragma once//---------------------- -----------------------------// Standard MAX7219 wiring// Digit order 0,1,2,3,4,5/ *// Segment order _ abcdefg#define _______ B00000000#define __cd___ B00011000#define _bcde_g B00111101#define abcdefg B01111111#define __cdefg B00011111#define __c____ B00010000#define ab__efg B01100111#define abcd_fg B01111011#define abcde_g B01111101#define ab_defg B01101111#define _bc____ B00110000#define a__defg B01001111#define ____ef_ B00000110#define ___defg B00001111#define abc__fg B01110011#define a___ef_ B01000110#define _b_____ B00100000#define ab___f_ B01100010#define _bcd___ B00111000#define a___ef_ B01000110#define ab_____ B01100000#define ____e__ B00000100#define __cde_g B00011101# define a____f_ B01000010#define a_cdefg B01011111#define ___de__ B00001100#define _____f_ B00000 010#define ab___fg B01100011#define a__def_ B01001110#define __cde__ B00011100#define a___efg B01000111#define a__d___ B01001000#define abc____ B01110000#define _bc_ef_ B00110110#define ___def_ B00001110#define abc_ef_ B01110110#define _bcdef_ B00111110#define a__def_ B01001110#define abcd___ B01111000*///Segment order d e f b c a _ g#define _______ B00000000#define __cd___ B10001000#define _bcde_g B11011001#define abcdefg B11111101#define __cdefg B11101001#define __c____ B00001000#define ab__efg B01110101#define abcd_fg B10111101#define abcde_g B11011101#define ab_defg B11110101#define _bc____ B00011000#define a__defg B11100101#define ____ef_ B01100000#define ___defg B11100001#define abc__fg B00111101#define a___ef_ B01100100#define _b_____ B00010000#define ab___f_ B00110100#define _bcd___ B10011000#define a___ef_ B01100100#define ab_____ B00010100#define ____e__ B01000000#define __cde_g B11001001#define a____f_ B00100100#define a_cdefg B11101101#define ___de__ B11000000#define _____f _ B00100000#define ab___fg B00110101#define a__def_ B11100100#define __cde__ B11001000#define a___efg B01100101#define a__d___ B10000100#define abc____ B00011100#define _bc_ef_ B01111000#define ___def_ B11100000#define abc_ef_ B01111100#define _bcdef_ B11111000#define a__def_ B11100100#define abcd___ B10011100//Square Numbers//ASCII Character Set//Numbers 0 - 9//Letters A - Z//Segment order d e f b c a _ guint8_t ascii[] ={ B11111100, B00011000, B11010101, B10011101, B00111001, B10101101, B11101101, B00011100, B11111101, B10111101, B00000000, B00000000, B00000000, B00000001, B00000000, B00000000, B00000000, B01111101, B11101001, B11100100, B11011001, B11100101, B01100101, B10111101, B01111001, B00011000, B11011000, B00000000, B11100000, B00000000, B01001001, B11001001, B01110101, B00000000, B01000001, B10101101, B11100001, B11001000, B00000000, B00000000, B00000000, B10111001, B00000000, B11001100, B01010001, B10011100, B00000000, B10000000};//Digit sequence for each device (MAX7219)u int8_t digitMap[] ={5, 2, 6, 4, 1, 7, 3, 0};//------------------------------------------------------------// Digits using logical coordinates//------------------------------------------------------------const int8_t largeDigits[11][6][6] PROGMEM ={ { //0 { _______, _______, __cd___, _bcde_g, abcdefg, __cdefg }, { _______, __c____, abcdefg, ab__efg, abcd_fg, abcdefg }, { _______, abcde_g, ab_defg, _______, _bc____, a__defg }, { _______, abcdefg, ____ef_, __c____, abcdefg, ____ef_ }, { _______, abcdefg, __cdefg, abcdefg, a___efg, _______ }, { _______, abc__fg, abcdefg, ab__efg, _______, _______ } }, { //1 { _______, _______, _______, __c____, abcdefg, __cdefg }, { _______, _______, _______, abcdefg, abcdefg, ____ef_ }, { _______, _______, _bcde_g, abcdefg, a__defg, _______ }, { _______, _bc____, abcdefg, abcdefg, ____ef_, _______ }, { _______, abcdefg, abcdefg, a___ef_, _______, _______ }, { _b_____, abcdefg, abcdefg, _______, _______, _______ } }, { //2 { _______, _______, __cd___, _b cde_g, abcdefg, __cdefg }, { _______, _bc____, abcdefg, ab___f_, abcd_fg, abcdefg }, { _______, _______, _______, _bcd___, abcdefg, a___ef_ }, { _______, _______, _bcde_g, abcdefg, a___ef_, _______ }, { __c____, abcdefg, abcdefg, a___ef_, _______, _______ }, { _b_____, abc__fg, abcdefg, abcdefg, ab__efg, _______ } }, { //3 { _______, _______, __cd___, abcdefg, abcdefg, __cdefg }, { _______, _b_____, abcdefg, ab___f_, abcd_fg, abcdefg }, { _______, _______, __cd___, _bcde_g, abcdefg, a___ef_ }, { _______, _______, ab_____, abc__fg, abcdefg, ____e__ }, { _______, __cd___, __cde_g, _bcde_g, abcdefg, ____ef_ }, { _b_____, abc__fg, abcdefg, abcdefg, a____f_, _______ } }, { //4 { _______, _______, _bcd___, abcdefg, __c____, abcdefg }, { _______, __c____, abcdefg, a___ef_, abcde_g, a__defg }, { _______, abcde_g, abcdefg, _bcd___, abcdefg, ____ef_ }, { __c____, abcdefg, abcdefg, abcdefg, abcdefg, _______ }, { _______, _______, __c____, abcdefg, ____ef_, _______ }, { _______, _______, abcdefg, ab__efg, _______, _______ } }, { //5 { _______, _______, _bcde_g, abcdefg, abcdefg, abcdefg }, { _______, _bc____, abcdefg, a_cdefg, ___de__, _______ }, { _______, _______, abc__fg, abcdefg, abcdefg, ____ef_ }, { _______, _______, _______, _bc____, abcdefg, ____ef_ }, { _______, __cde_g, __cde_g, _bcde_g, abcdefg, _____f_ }, { _b_____, abcdefg, abcdefg, ab__efg, a____f_, _______ } }, { //6 { _______, _______, _______, __cd___, abcdefg, ____ef_ }, { _______, _______, _bcde_g, abcdefg, a____f_, _______ }, { _______, _bcd___, abcdefg, abcdefg, abcdefg, ____e__ }, { __c____, abcdefg, a___ef_, ab_____, abcdefg, ____ef_ }, { _bc____, abcdefg, __cdefg, _bcde_g, abcdefg, _______ }, { _______, abc__fg, abcdefg, ab__efg, _______, _______ } }, { //7 { _______, _bc____, abcdefg, abcdefg, abcdefg, __cdefg }, { _______, _b_____, ab___fg, ab___fg, abcdefg, abcdefg }, { _______, _______, _______, _bcde_g, abcdefg, a___ef_ }, { _______, _______, _bcde_g, abcdefg, ab__efg, _______ }, { _______, _bcde_g, abcdefg, a___ef_, _______, _______ }, { _b_____, abcdefg, abcdefg, _______, _______, _______ } }, { //8 { _______, _______, __cd___, abcdefg, abcdefg, __cdefg }, { _______, _bc____, abcdefg, ab___f_, abcd_fg, abcdefg }, { _______, _b_____, abcdefg, _bcde_g, abcdefg, a___ef_ }, { _______, _bcde_g, ab__efg, abc__fg, abcdefg, ____e__ }, { _bc____, abcdefg, __cde_g, _bcde_g, abcdefg, ____ef_ }, { _______, abc__fg, abcdefg, abcdefg, a____f_, _______ } }, { //9 { _______, _______, __cde_g, abcdefg, __cdefg, ___de__ }, { _______, _bcd___, abcdefg, ab___fg, abcd_fg, abcdefg }, { _______, abcdefg, a_cdefg, __cde__, abcdefg, a__defg }, { _______, ab_____, abcd_fg, abcdefg, abcdefg, _____f_ }, { _______, __cd___, abcdefg, ab__efg, _______, _______ }, { _b_____, abcdefg, a___ef_, _______, _______, _______ } }, { //Colon { _______, _______, _______, _______, _______, _______ }, { _______, __cde_g, _______, _______, _______, _______ }, { _______, _______, _______, _______, _______, _______ }, { ___ ____, _______, _______, _______, _______, _______ }, { __cde_g, _______, _______, _______, _______, _______ }, { _______, _______, _______, _______, _______, _______ } }};const int8_t smallDigits[11][5][3] PROGMEM ={ { //0 { a___ef_, a__d___, abc____ }, { _bc_ef_, _______, _bc_ef_ }, { _bc_ef_, _______, _bc_ef_ }, { _bc_ef_, _______, _bc_ef_ }, { ___def_, a__d___, _bcd___ } }, { //1 { _______, abc_ef_, _______ }, { _______, _bc_ef_, _______ }, { _______, _bc_ef_, _______ }, { _______, _bc_ef_, _______ }, { _______, _bcdef_, _______ } }, { //2 { a__def_, a__d___, abc____ }, { _______, _______, _bc_ef_ }, { a___ef_, a__d___, _bcd___ }, { _bc_ef_, _______, _______ }, { ___def_, a__d___, abcd___ } }, { //3 { a__def_, a__d___, abc____ }, { _______, _______, _bc_ef_ }, { _______, a__def_, _bc____ }, { _______, _______, _bc_ef_ }, { a__def_, a__d___, _bcd___ } }, { //4 { abc_ef_, _______, abc_ef_ }, { _bc_ef_, _______, _bc_ef_ }, { ___def_, a__d___, _bc____ }, { _______, _______, _bc_ef_ }, { _______, _______, _bcdef_ } }, { //5 { a___ef_, a__d___, abcd___ }, { _bc_ef_, _______, _______ }, { ___def_, a__d___, abc____ }, { _______, _______, _bc_ef_ }, { a__def_, a__d___, _bcd___ } }, { //6 { a___ef_, a__d___, abcd___ }, { _bc_ef_, _______, _______ }, { ____ef_, a__d___, abc____ }, { _bc_ef_, _______, _bc_ef_ }, { ___def_, a__d___, _bcd___ } }, { //7 { a__def_, a__d___, abc____ }, { _______, _______, _bc_ef_ }, { _______, _bc_ef_, _______ }, { _______, _bc_ef_, _______ }, { _______, _bcdef_, _______ }, }, { //8 { a___ef_, a__d___, abc____ }, { _bc_ef_, _______, _bc_ef_ }, { ____ef_, a__d___, _bc____ }, { _bc_ef_, _______, _bc_ef_ }, { ___def_, a__d___, _bcd___ } }, { //9 { a___ef_, a__d___, abc____ }, { _bc_ef_, _______, _bc_ef_ }, { ___def_, a__d___, _bc____ }, { _______, _______, _bc_ef_ }, { a__def_, a__d___, _bcd___ } }, { //Hyphen { _______, _______, _______ }, { _______, _______, _______ }, { a__def_, a__d___, abcd___ }, { _______, _______, _______ }, { _______, _____ __, _______ } }};
Tunes.hC/C++
 Sin vista previa (solo descarga). 
Button.hC/C++
/*Class:ButtonAuthor:John Bradnam ([email protected])Purpose:Arduino library to handle buttons*/#pragma once#include "Arduino.h"#define DEBOUNCE_DELAY 10//Repeat speed#define REPEAT_START_SPEED 500#define REPEAT_INCREASE_SPEED 50#define REPEAT_MAX_SPEED 50class Button{ public://Simple constructor Button(int pin); Button(int name, int pin); Button(int name, int pin, int analogLow, int analogHigh, bool activeLow =true); //Background function called when in a wait or repeat loop void Background(void (*pBackgroundFunction)()); //Repeat function called when button is pressed void Repeat(void (*pRepeatFunction)()); //Test if button is pressed bool IsDown(void); //Test whether button is pressed and released //Will call repeat function if one is provided bool Pressed(); //Return button state (HIGH or LOW) - LOW =Pressed int State(); //Return button name int Name(); private:int _name; int _pin; bool _range; int _low; int _high; bool _activeLow; void (*_repeatCallback)(void); void (*_backgroundCallback)(void);};
Button.cppC/C++
/*Class:ButtonAuthor:John Bradnam ([email protected])Purpose:Arduino library to handle buttons*/#include "Button.h"Button::Button(int pin){ _name =pin; _pin =pin; _range =false; _low =0; _high =0; _backgroundCallback =NULL; _repeatCallback =NULL; pinMode(_pin, INPUT_PULLUP);}Button::Button(int name, int pin){ _name =name; _pin =pin; _range =false; _low =0; _high =0; _backgroundCallback =NULL; _repeatCallback =NULL; pinMode(_pin, INPUT_PULLUP);}Button::Button(int name, int pin, int analogLow, int analogHigh, bool activeLow){ _name =name; _pin =pin; _range =true; _low =analogLow; _high =analogHigh; _activeLow =activeLow; _backgroundCallback =NULL; _repeatCallback =NULL; pinMode(_pin, INPUT);}//Set function to invoke in a delay or repeat loopvoid Button::Background(void (*pBackgroundFunction)()){ _backgroundCallback =pBackgroundFunction;}//Set function to invoke if repeat system requiredvoid Button::Repeat(void (*pRepeatFunction)()){ _repeatCallback =pRepeatFunction;} bool Button::IsDown(){ if (_range) { int value =analogRead(_pin); return (value>=_low &&value <_high); } else { return (digitalRead(_pin) ==LOW); }}//Tests if a button is pressed and released// returns true if the button was pressed and released// if repeat callback supplied, the callback is called while the key is pressedbool Button::Pressed(){ bool pressed =false; if (IsDown()) { unsigned long wait =millis() + DEBOUNCE_DELAY; while (millis() =time) { _repeatCallback(); unsigned long faster =speed - REPEAT_INCREASE_SPEED; if (faster>=REPEAT_MAX_SPEED) { speed =faster; } time =millis() + speed; } } pressed =true; } } return pressed;}//Return current button stateint Button::State(){ if (_range) { int value =analogRead(_pin); if (_activeLow) { return (value>=_low &&value <_high) ? LOW :HIGH; } else { return (value>=_low &&value <_high) ? HIGH :LOW; } } else { return digitalRead(_pin); }}//Return current button nameint Button::Name(){ return _name;}
Hardware_Test_V1.zipC/C++
Hardware test sketch - Turns on all segments and tests speaker
No preview (download only).

Piezas y carcasas personalizadas

Esquemas

Schematic for each MAX7219 (repeated 18 times) Holds six 7 segment 4 digit displays (6 boards required) PCB files in Eagle format eagle_files_KPhUOj6Ezv.zip

Proceso de manufactura

  1. Reloj de visión pov de Arduino
  2. Reloj de palabras simple (Arduino)
  3. Reloj Arduino con tiempos de oración islámicos
  4. Reloj maestro
  5. Reloj Flip Arduino de matriz de un solo LED
  6. Controlar una matriz de LED con Arduino Uno
  7. eDOT - Reloj de precisión y estación meteorológica basados ​​en Arduino
  8. Mini radar con Arduino
  9. Pantalla de temperatura OLED de Arduino con reloj en tiempo real
  10. Arduino Shield NCS314 Reloj de tubos NIXIE IN-14
  11. Reloj despertador simple con DS1302 RTC