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 de matriz LED

Componentes y suministros

Arduino Nano R3
× 1
Maxim Integrated DS3231M - ± 5ppm, I2C Real-Time Clock
× 1
Interruptor de botón, momentáneo
× 2
Módulo de matriz LED 32x8
× 1

Herramientas y máquinas necesarias

Soldador (genérico)

Aplicaciones y servicios en línea

Arduino IDE

Acerca de este proyecto

En la página "Proyectos LED de Nick" encontré un proyecto de reloj que muestra la hora en 4 matrices con leds de 8x8. Construyó el reloj con matrices de la tienda "ICStation" que vende kits de bricolaje de paneles de módulos de matriz.

Con un cambio mínimo en el código, hice mi reloj con el módulo de matriz de puntos MAX7219 icrocontroller Pantalla cuatro en uno que está completamente plegada y es mucho más barata. Lo compré en AliExpress.

El reloj tiene muchas características:

- Modo básico con dígitos grandes

- Modo de diapositiva donde los dígitos aparecen y desaparecen de la pantalla

- Dígitos pequeños con modo de segundos

- Tiempo escrito en palabras, p. Ej. "Doce y diez"

- Visualización de la fecha

- Opción de 12/24 horas

- Opción de brillo

- Opción de modo de reloj aleatorio que cambia el modo de visualización cada pocas horas.

- Menús controlados por botones para configuración y selección de pantalla.

Como puede ver en el circuito, excepto las matrices, necesitamos una placa arduino, un módulo de reloj en tiempo real y dos botones para la configuración. Puede descargar bibliotecas y código modificado en los enlaces a continuación.

Código

  • código
  • Bibliotecas
código Arduino
 / ******************************************** ************************ Mini Clock v1.0, julio de 2014 por Nick Hall Distribuido bajo los términos de la GPL. reloj ver mi blog:http://123led.wordpress.com/Tested en IDE v1.6.5 *************************** ***************************************** /// incluir bibliotecas:#include "LedControl.h" #include  // Biblioteca de fuentes # incluye  // DS1307 reloj # incluye "RTClib.h" // DS1307 reloj # incluye  // Biblioteca de botones por Alexander Brevig // Setup LED Matrix // pin 12 está conectado a DataIn en la pantalla // pin 11 está conectado a CLK en la pantalla // pin 10 está conectado a LOAD en la pantallaLedControl lc =LedControl (12, 11, 10, 4); // establece los 3 pines como 12, 11 y 10 y luego configura 4 pantallas (el máximo es 8 pantallas) // variables globales intensidad de bytes =7; // Intensidad / brillo por defecto (0-15) byte clock_mode =0; // Modo de reloj predeterminado. Predeterminado =0 (modo_básico) bool modo_aleatorio =0; // Definir modo aleatorio:cambia el tipo de visualización cada pocas horas. Predeterminado =0 (desactivado) byte old_mode =clock_mode; // Almacena el modo de reloj anterior, así que si vamos a la fecha o lo que sea, sabemos a qué modo volver después.bool ampm =0; // Defina el tiempo de 12 o 24 horas. 0 =24 horas. 1 =12 horasbyte change_mode_time =0; // Mantiene la hora cuando el modo de reloj cambiará a continuación si está en modo aleatorio. Tiempo de retardo largo sin firmar =500; // Siempre esperamos un poco entre actualizaciones de displayint rtc [7]; // Mantiene el reloj en tiempo real outputchar days [7] [4] ={"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; // matriz de día:se utiliza en los modos slide, basic_mode y jumble (el DS1307 genera de 1 a 7 valores para el día de la semana) char daysfull [7] [9] ={"Sunday", "Monday", "Tuesday", "Wed "," Jueves "," viernes "," sábado "}; sufijo char [4] [3] ={" st "," nd "," rd "," th "}; // matriz de sufijo de fecha, utilizada en los modos slide, basic_mode y jumble. e, g, 1st 2nd ... // definir constantes # definir NUM_DISPLAY_MODES 3 // modos de visualización de números (con cero como primer modo) #define NUM_SETTINGS_MODES 4 // modos de configuración de números =6 (con cero como primer modo) # define SLIDE_DELAY 20 // El tiempo en milisegundos para el efecto de diapositiva por carácter en el modo de diapositiva. Haga esto más alto para un efecto más lento # define cls clear_display // Clear displayRTC_DS1307 ds1307; // Crear RTC objectButton buttonA =Button (2, BUTTON_PULLUP); // Configurar el botón A (usando la biblioteca de botones) Button buttonB =Button (3, BUTTON_PULLUP); // Botón de configuración B (usando la biblioteca de botones) void setup () {digitalWrite (2, HIGH); // enciende la resistencia pullup para el botón en el pin 2 digitalWrite (3, HIGH); // enciende la resistencia pullup para el botón en el pin 3 digitalWrite (4, HIGH); // enciende la resistencia pullup para el botón en el pin 4 Serial.begin (9600); // iniciar serial // inicializar los 4 paneles de matriz // ya hemos establecido el número de dispositivos cuando creamos el LedControl int devices =lc.getDeviceCount (); // tenemos que iniciar todos los dispositivos en un bucle for (int address =0; address  =0 &&x <=7) {dirección =3; } si (x> =8 &&x <=15) {dirección =2; x =x - 8; } si (x> =16 &&x <=23) {dirección =1; x =x - 16; } si (x> =24 &&x <=31) {dirección =0; x =x - 24; } if (val ==1) {lc.setLed (dirección, y, x, verdadero); } else {lc.setLed (dirección, y, x, falso); }} // borrar screenvoid clear_display () {for (byte address =0; address <4; address ++) {lc.clearDisplay (address); }} // desvanecimiento de la pantalla downvoid fade_down () {// desvanecimiento de la intensidad global a 1 para (byte i =intensidad; i> 0; i--) {para (byte dirección =0; dirección <4; dirección ++) {lc .setIntensity (dirección, i); } retraso (30); // cambia esto para cambiar la velocidad de atenuación} clear_display (); // borrar la pantalla completamente (apagado) // restablecer la intensidad a valor global para (dirección de byte =0; dirección <4; dirección ++) {lc.setIntensity (dirección, intensidad); }} // encender el LED de prueba y mostrar el número de versión del software void printver () {byte i =0; char ver_a [9] ="Vers 1.0"; char ver_b [9] ="¡Hola!"; // prueba todos los leds. para (byte x =0; x <=31; x ++) {para (byte y =0; y <=7; y ++) {plot (x, y, 1); }} retraso (500); fade_down (); while (ver_a [i]) {puttinychar ((i * 4), 1, ver_a [i]); retraso (35); i ++; } retraso (700); fade_down (); i =0; while (ver_b [i]) {puttinychar ((i * 4), 1, ver_b [i]); retraso (35); i ++; } retraso (700); fade_down ();} // puttinychar // Copia un glifo de 3x5 caracteres de la estructura de datos myfont para mostrar la memoria, con su parte superior izquierda en la coordenada dada // Esto no está optimizado y simplemente usa plot () para dibujar cada punto. (byte x, byte y, char c) {byte puntos; if (c> ='A' &&c <='Z' || (c> ='a' &&c <='z')) {c &=0x1F; // A-Z se asigna a 1-26} else if (c> ='0' &&c <='9') {c =(c - '0') + 32; } más si (c =='') {c =0; // espacio} else if (c =='.') {c =27; // punto final} else if (c ==':') {c =28; // dos puntos} else if (c =='\' ') {c =29; // comilla simple} else if (c =='!') {c =30; // comilla simple} else if (c =='?') {c =31; // comilla simple} para (byte col =0; col <3; col ++) {puntos =pgm_read_byte_near (&mytinyfont [c] [col]); for (char fila =0; fila <5; fila ++) {if (puntos &(16>> fila)) plot (x + col, y + fila, 1); de lo contrario trazar (x + col, y + fila, 0); }}} void putnormalchar (byte x, byte y, char c) {byte puntos; // si (c> ='A' &&c <='Z' || (c> ='a' &&c <='z')) {// c &=0x1F; // A-Z se asigna a 1-26 //} if (c> ='A' &&c <='Z') {c &=0x1F; // A-Z se asigna a 1-26} else if (c> ='a' &&c <='z') {c =(c - 'a') + 41; // A-Z se asigna a 41-67} else if (c> ='0' &&c <='9') {c =(c - '0') + 31; } más si (c =='') {c =0; // espacio} else if (c =='.') {c =27; // punto final} else if (c =='\' ') {c =28; // comilla simple} else if (c ==':') {c =29; // flecha del selector de modo_de_reloj} else if (c =='>') {c =30; // flecha del selector de modo_de_reloj} else if (c> =-80 &&c <=-67) {c * =-1; } para (char col =0; col <5; col ++) {puntos =pgm_read_byte_near (&myfont [c] [col]); for (char row =0; row <7; row ++) {// verifique que las coordenadas estén en la pantalla antes de intentar trazar // if ((x> =0) &&(x <=31) &&(y> =0) &&(y <=7)) {if (puntos &(64>> fila)) {// solo 7 filas. plot (x + col, y + fila, 1); } else {plot (x + col, y + row, 0); } //}}}} // small_mode // muestra la hora en pequeños caracteres de 3x5 con segundos displayvoid small_mode () {char textchar [8]; // los 16 caracteres en el byte de la pantalla min =100; // min byte secs =rtc [0]; // segundos byte old_secs =segundos; // mantiene el valor de los segundos antiguos - desde la última vez que se actualizaron los segundos o display - se usa para verificar si los segundos han cambiado cls (); // ejecutar el ciclo principal del reloj siempre que run_mode devuelva verdadero while (run_mode ()) {get_time (); // comprobar si se ha pulsado el botón if (buttonA.uniquePress ()) {switch_mode (); regreso; } if (buttonB.uniquePress ()) {display_date (); regreso; } // si los segundos cambiaron, actualícelos en la pantalla secs =rtc [0]; if (segs! =old_secs) {// segs char buffer [3]; itoa (segundos, búfer, 10); // arreglar - de lo contrario si num tiene un cero a la izquierda, p. ej. "03" segundos, itoa convierte esto en caracteres con espacio "3". si (segundos <10) {búfer [1] =búfer [0]; búfer [0] ='0'; } puttinychar (20, 1, ':'); // segundos colon puttinychar (24, 1, buffer [0]); // segundos puttinychar (28, 1, buffer [1]); // segundos old_secs =segundos; } // si los minutos cambian, cambie la hora if (min! =rtc [1]) {// restablecerlos para compararlos la próxima vez min =rtc [1]; byte horas =rtc [2]; if (horas> 12) {horas =horas - ampm * 12; } if (horas <1) {horas =horas + ampm * 12; } // byte dow =rtc [3]; // el DS1307 genera 0 - 6 donde 0 =domingo 0 - 6 donde 0 =domingo. // byte fecha =rtc [4]; // establece los caracteres char buffer [3]; itoa (horas, búfer, 10); // arreglar - de lo contrario si num tiene un cero a la izquierda, p. ej. "03" horas, itoa convierte esto en caracteres con espacio "3". if (horas <10) {buffer [1] =buffer [0]; // si estamos en el modo de 12 horas en blanco el cero inicial. if (ampm) {buffer [0] =''; } más {búfer [0] ='0'; }} // establecer horas chars textchar [0] =buffer [0]; textchar [1] =búfer [1]; textchar [2] =':'; itoa (minutos, tampón, 10); si (minutos <10) {búfer [1] =búfer [0]; búfer [0] ='0'; } // establece minutos caracteres textchar [3] =buffer [0]; textchar [4] =búfer [1]; // hacer segundos textchar [5] =':'; tampón [3]; segundos =rtc [0]; itoa (segundos, búfer, 10); // arreglar - de lo contrario si num tiene un cero a la izquierda, p. ej. "03" segundos, itoa convierte esto en caracteres con espacio "3". si (segundos <10) {búfer [1] =búfer [0]; búfer [0] ='0'; } // establecer segundos textchar [6] =buffer [0]; textchar [7] =búfer [1]; byte x =0; byte y =0; // imprime cada carácter para (byte x =0; x <6; x ++) {puttinychar (x * 4, 1, textchar [x]); }} retraso (50); } fade_down ();} // modo_básico () // muestra la hora en caracteres de 5x7 void modo_básico () {cls (); tampón de carbón [3]; // para que la conversión de int a char convierta los valores rtc en caracteres podemos imprimir en la pantalla byte offset =0; // se usa para compensar la posición x de los dígitos y centrar la pantalla cuando estamos en el modo de 12 horas y el reloj muestra solo 3 dígitos. p.ej. 3:21 bytes x, y; // se usa para dibujar un cuadro transparente sobre el "1" de la izquierda de la pantalla cuando pasamos de 12:59 a 1:00 am en el modo de 12 horas. // realiza una conversión de 12/24 horas si ampm se establece en 1 byte horas =rtc [2]; if (horas> 12) {horas =horas - ampm * 12; } if (horas <1) {horas =horas + ampm * 12; } // realizar conversión de compensación if (ampm &&hours <10) {offset =2; } // establecemos el siguiente minuto mostramos la fecha en // set_next_date (); // inicialmente establece minutos en el valor 100, por lo que nunca será igual a rtc [1] en el primer ciclo del reloj, lo que significa que dibujamos la pantalla del reloj cuando ingresamos la función byte secs =100; minutos de bytes =100; int count =0; // ejecutar el ciclo principal del reloj siempre que run_mode devuelva verdadero while (run_mode ()) {// obtener la hora del chip del reloj get_time (); // comprobar si se ha pulsado el botón if (buttonA.uniquePress ()) {switch_mode (); regreso; } if (buttonB.uniquePress ()) {display_date (); regreso; } // verifica si es hora de mostrar automáticamente la fecha // check_show_date (); // dibuja el parpadeo:como si los segundos hubieran cambiado. if (secs! =rtc [0]) {// actualiza los segundos con un nuevo valor secs =rtc [0]; // dibujar:trazar (15 - desplazamiento, 2, 1); // trama del punto superior (15 - desplazamiento, 5, 1); // recuento de puntos inferiores =400; } // si el recuento se ha agotado, apague:if (count ==0) {plot (15 - offset, 2, 0); // gráfico del punto superior (15 - desplazamiento, 5, 0); // punto inferior} else {cuenta--; } // volver a dibujar la pantalla si se presiona el botón o si minutos! =rtc [1] es decir, si el tiempo ha cambiado de lo que habíamos almacenado en minutos, (también se activa en la primera función de ingreso cuando los minutos son 100) si (minutos! =rtc [1]) {// actualiza los minutos y las horas con los nuevos valores mins =rtc [1]; horas =rtc [2]; // ajusta las horas de ampm en modo de 12 horas if (hours> 12) {hours =hours - ampm * 12; } if (horas <1) {horas =horas + ampm * 12; } itoa (horas, búfer, 10); // si horas <10 el num p. ej. "3" horas, itoa convierte esto en caracteres con espacio "3" que no queremos si (horas <10) {buffer [1] =buffer [0]; búfer [0] ='0'; } // imprimimos las horas // si estamos en el modo de 12 horas y las horas <10, entonces no imprimamos el cero inicial y establezcamos el desplazamiento para que centremos la pantalla con 3 dígitos. if (ampm &&hours <10) {offset =2; // si la hora es 1:00 am, borre toda la pantalla ya que el desplazamiento cambia a esta hora y necesitamos borrar el antiguo 12:59 if ((hours ==1 &&mins ==0)) {cls (); }} else {// else no hay compensación e imprime las horas decenas de dígitos offset =0; // si la hora es 10:00 am, borre toda la pantalla ya que el desplazamiento cambia en esta hora y necesitamos borrar el antiguo 9:59 if (hours ==10 &&mins ==0) {cls (); } putnormalchar (1, 0, buffer [0]); } // imprime el dígito de las horas en unidades putnormalchar (7 - offset, 0, buffer [1]); // imprime minutos // agrega un cero a la izquierda si minutos <10 itoa (minutos, búfer, 10); si (minutos <10) {búfer [1] =búfer [0]; búfer [0] ='0'; } // imprime los dígitos de las decenas y las unidades de los minutos putnormalchar (19 - offset, 0, buffer [0]); putnormalchar (25 - desplazamiento, 0, búfer [1]); }} fade_down ();} // como modo_básico pero con efecto de diapositiva void slide () {byte digits_old [4] ={99, 99, 99, 99}; // valores antiguos en los que almacenamos la hora. Establezca algo que nunca coincida con la hora inicialmente para que todos los dígitos se dibujen cuando el modo comience byte digits_new [4]; // el tiempo de los nuevos dígitos se deslizará para revelar el byte digits_x_pos [4] ={25, 19, 7, 1}; // x pos para la cual dibujar cada dígito en char old_char [2]; // se usa cuando usamos itoa para transponer el dígito actual (tipo byte) a un carácter para pasar a la función de animación char new_char [2]; // se usa cuando usamos itoa para transponer el nuevo dígito (tipo byte) a un carácter para pasar a la función de animación // caracteres_antiguos:almacena los caracteres del sufijo de 5 días y fechas en la pantalla. p.ej. "mon" y "st". Los introducimos en la animación de la diapositiva como el carácter actual cuando se actualizan estos caracteres. // Los enviamos como A inicialmente, que se usan cuando el reloj entra en modo y no se almacenan los últimos caracteres. // char caracteres_antiguos [6] ="AAAAA"; // traza los dos puntos del reloj en la pantalla cls (); putnormalchar (13, 0, ':'); byte old_secs =rtc [0]; // almacena segundos en old_secs. Comparamos segundos y segundos antiguos. Cuando son diferentes, redibujamos la pantalla // ejecutamos el ciclo principal del reloj siempre que run_mode devuelva verdadero while (run_mode ()) {get_time (); // comprobar si se ha pulsado el botón if (buttonA.uniquePress ()) {switch_mode (); regreso; } if (buttonB.uniquePress ()) {display_date (); regreso; } // si los segundos han cambiado, actualice la pantalla if (rtc [0]! =old_secs) {old_secs =rtc [0]; // realiza una conversión de 12/24 horas si ampm se establece en 1 byte horas =rtc [2]; if (horas> 12) {horas =horas - ampm * 12; } if (horas <1) {horas =horas + ampm * 12; } // dividir toda la fecha y la hora en dígitos individuales - pegar en digits_new array // rtc [0] =segs // array pos y digit almacenados // digits_new [0] =(rtc [0]% 10); // 0 - segundos unos // digits_new [1] =((rtc [0] / 10)% 10); // 1 - decenas de segundos // rtc [1] =minutos digits_new [0] =(rtc [1]% 10); // 2 - minutos unidades digits_new [1] =((rtc [1] / 10)% 10); // 3 - min decenas // rtc [2] =horas digits_new [2] =(horas% 10); // Unidades de 4 horas digits_new [3] =((horas / 10)% 10); // decenas de 5 horas // rtc [4] =fecha // dígitos_nuevos [6] =(rtc [4]% 10); // 6 - fecha unos // digits_new [7] =((rtc [4] / 10)% 10); // 7 - date decenas // dibuja la pantalla inicial de todos los caracteres. Después de esto, simplemente dibujamos los cambios. // comparar los dígitos 0 a 3 (minutos y horas) para (byte i =0; i <=3; i ++) {// ver si el dígito ha cambiado ... if (digits_old [i]! =digits_new [i]) {// ejecutar secuencia de animación de 9 pasos para cada uno por turno para (byte seq =0; seq <=8; seq ++) {// convertir el dígito a la cadena itoa (digits_old [i], old_char, 10); itoa (dígitos_nuevo [i], nuevo_car, 10); // si está configurado en el modo de 12 horas y estamos en el dígito 2 (modo de las decenas de las horas), verifique si es un cero. Si es así, déjelo en blanco en su lugar para obtener 2.00pm no 02.00pm if (ampm &&i ==3) {if (digits_new [3] ==0) {new_char [0] =''; } if (dígitos_antiguo [3] ==0) {antiguo_char [0] =''; }} // dibuja el cuadro de animación para cada dígito slideanim (digits_x_pos [i], 0, seq, old_char [0], new_char [0]); retraso (SLIDE_DELAY); }}} / * // comparar el dígito de fecha 6 (unidades) y (7) decenas - si alguno de estos cambia, necesitamos actualizar la línea de fecha. Comparamos la fecha de las decenas como, por ejemplo, del 31 de enero -> 01 de febrero, entonces el dígito de las unidades no cambia si ((digits_old [6]! =Digits_new [6]) || (digits_old [7]! =Digits_new [7])) { // cambia el día mostrado. El bucle de abajo recorre cada uno de los 3 caracteres uno por uno, p. Ej. "MON" for (byte day_char =0; day_char <=2; day_char ++) {// ejecuta la secuencia de animación para cada carácter para (byte seq =0; seq <=8; seq ++) {// el día (0 - 6 ) Lea este número en la matriz de caracteres de días. el número de segundos en la matriz 0-2 obtiene los 3 caracteres del nombre del día, p. ej. m o n slideanim (6 * day_char, 8, seq, old_chars [day_char], days [rtc [3]] [day_char]); // 6 x day_char nos da la posición x para el retardo de caracteres (SLIDE_DELAY); } // guarda los caracteres antiguos en la matriz old_chars en la matriz pos 0-2. Lo usaremos la próxima vez que cambiemos el día y lo incluyamos en la animación como el carácter actual. El carácter actualizado se alimenta como el nuevo carácter. old_chars [day_char] =days [rtc [3]] [day_char]; } // cambia el dígito de las decenas de la fecha (si es necesario) y el dígito de las unidades. (El dígito de la fecha en unidades siempre cambiará, pero poner esto en el bucle 'if' hace que el código sea un poco más ordenado.) for (byte i =7; i> =6; i -) {if (digits_old [i] ! =digits_new [i]) {for (byte seq =0; seq <=8; seq ++) {itoa (digits_old [i], old_char, 10); itoa (dígitos_nuevo [i], nuevo_car, 10); slideanim (digits_x_pos [i], 8, seq, old_char [0], new_char [0]); retraso (SLIDE_DELAY); }}} // imprime el sufijo del día "nd" "rd" "th" etc. Primera fecha de trabajo Sufijo de 2 letras - p. ej. st, nd, rd, th byte s =3; // la pos para leer nuestra matriz de sufijos. byte fecha =rtc [4]; if (fecha ==1 || fecha ==21 || fecha ==31) {s =0; } más si (fecha ==2 || fecha ==22) {s =1; } más si (fecha ==3 || fecha ==23) {s =2; } for (byte suffix_char =0; suffix_char <=1; suffix_char ++) {for (byte seq =0; seq <=8; seq ++) {slideanim ((suffix_char * 6) + 36,8, seq, old_chars [suffix_char + 3 ], sufijo [s] [suffix_char]); // pasamos el carácter de la matriz old_char como el carácter actual y la matriz de sufijos como el nuevo retardo de caracteres (SLIDE_DELAY); } // guarda el carácter suficiente en la matriz de caracteres anterior en la matriz pos 3 y 5. Usamos estos caracteres la próxima vez que cambiemos el sufijo y lo alimentemos a la animación como el carácter actual. El carácter actualizado se alimenta como el nuevo carácter. old_chars [suffix_char + 3] =suffix [s] [suffix_char]; }} // finaliza la línea de fecha * / // guarda la matriz de dígitos tol vieja para comparar el siguiente ciclo para (byte i =0; i <=3; i ++) {digits_old [i] =digits_new [i]; }} // secs / oldsecs} // while loop fade_down ();} // llamado por diapositiva // esto dibuja la animación de un carácter deslizándose y el otro deslizándose. Hay 8 pasos en la animación, llamamos a la función para dibujar uno de los pasos de 0-7 // las entradas son char xey, secuencia de cuadros de animación (0-7) y los caracteres actuales y nuevos que se dibujan. slideanim (byte x, byte y, secuencia de bytes, char current_c, char new_c) {// Para deslizar un carácter y otro, necesitamos 9 pasos o cuadros en secuencia ... // seq # 0123456 <-fileras de la pantalla // | ||||||| // seq0 0123456 START:todas las filas de la pantalla 0-6 muestran las filas de caracteres actuales 0-6 // seq1 012345 el carácter actual se mueve hacia abajo una fila en la pantalla. Solo vemos sus filas 0-5. Hay en las posiciones de visualización 1-6 Hay una fila en blanco insertada en la parte superior // seq2 6 01234 el carácter actual se mueve hacia abajo 2 filas. ahora solo vemos las filas 0-4 en las filas 2-6 de la pantalla. La fila 1 de la pantalla está en blanco. La fila 0 muestra la fila 6 del nuevo carácter // seq3 56 0123 // seq4 456012 mitad antiguo / mitad nuevo carácter // seq5 3456 01 // seq6 23456 0 // seq7 123456 // seq8 0123456 END - todas las filas muestran el nuevo char // desde arriba podemos ver ... // currentchar corre 0-6 luego 0-5 luego 0-4 hasta 0. La posición inicial de Y aumenta en 1 fila cada vez. // el nuevo carácter corre 6, luego 5-6, luego 4-6 y luego 3-6. La posición inicial de Y aumenta en 1 fila cada vez. // si el número de secuencia está por debajo de 7, necesitamos dibujar el carácter actual if (secuencia <7) {byte puntos; // if (current_c> ='A' &&|| (current_c> ='a' &¤t_c <='z')) {// current_c &=0x1F; // A-Z se asigna a 1-26 //} if (current_c> ='A' &¤t_c <='Z') {current_c &=0x1F; // A-Z se asigna a 1-26} else if (current_c> ='a' &¤t_c <='z') {current_c =(current_c - 'a') + 41; // A-Z se asigna a 41-67} else if (current_c> ='0' &¤t_c <='9') {current_c =(current_c - '0') + 31; } más si (current_c =='') {current_c =0; // espacio} else if (current_c =='.') {current_c =27; // punto final} else if (current_c =='\' ') {current_c =28; // comilla simple} else if (current_c ==':') {current_c =29; // dos puntos} else if (current_c =='>') {current_c =30; // flecha del selector de modo de reloj} byte curr_char_row_max =7 - secuencia; // el número máximo de filas para dibujar es 6 - número de secuencia byte start_y =secuencia; // La posición y para comenzar - es la misma que el número de secuencia. Incrementamos cada ciclo // trazamos cada fila hasta el máximo de fila (calculado a partir del número de secuencia) para (byte curr_char_row =0; curr_char_row <=curr_char_row_max; curr_char_row ++) {for (byte col =0; col <5; col ++) {puntos =pgm_read_byte_near (&myfont [current_c] [col]); if (puntos &(64>> curr_char_row)) plot (x + col, y + start_y, 1); // trazar guiado en else trama (x + col, y + start_y, 0); // si no, la trama se inició} start_y ++; // agregamos uno ay para que dibujemos la siguiente fila uno hacia abajo}} // dibujamos una línea en blanco entre los caracteres si la secuencia está entre 1 y 7. Si no hacemos esto, obtenemos los restos de la última posición de los caracteres actuales que quedan en la pantalla if (secuencia> =1 &&secuencia <=8) {for (byte col =0; col <5; col ++) {plot (x + col, y + (secuencia - 1), 0); // la posición y para dibujar la línea es equivalente al número de secuencia - 1}} // si la secuencia está por encima de 2, también debemos comenzar a dibujar el nuevo carácter if (secuencia> =2) {// calcular el byte de caracteres puntos // if (nuevo_c> ='A' &&nuevo_c <='Z' || (nuevo_c> ='a' &&nuevo_c <='z')) {// nuevo_c &=0x1F; // A-Z se asigna a 1-26 //} if (new_c> ='A' &&new_c <='Z') {new_c &=0x1F; // A-Z se asigna a 1-26} else if (new_c> ='a' &&new_c <='z') {new_c =(new_c - 'a') + 41; // A-Z se asigna a 41-67} else if (new_c> ='0' &&new_c <='9') {new_c =(new_c - '0') + 31; } más si (nuevo_c =='') {nuevo_c =0; // espacio} else if (new_c =='.') {new_c =27; // punto final} else if (new_c =='\' ') {new_c =28; // comilla simple} else if (new_c ==':') {new_c =29; // flecha del selector de modo_de_reloj} else if (new_c =='>') {new_c =30; // flecha del selector de modo_de_reloj} byte newcharrowmin =6 - (secuencia - 2); // número de fila mínimo para dibujar para un nuevo carácter:esto genera una salida de 6 a 0 cuando se alimentan los números de secuencia 2-8. Esta es la fila mínima que se debe dibujar para el nuevo byte de caracteres start_y =0; // La posición y para comenzar - es la misma que el número de secuencia. incidimos cada fila // trazamos cada fila desde el mínimo de fila (calculado por número de secuencia) hasta 6 para (byte newcharrow =newcharrowmin; newcharrow <=6; newcharrow ++) {for (byte col =0; col <5; col ++ ) {puntos =pgm_read_byte_near (&myfont [new_c] [col]); if (puntos &(64>> newcharrow)) plot (x + col, y + start_y, 1); // trazar guiado en else trama (x + col, y + start_y, 0); // de lo contrario, el diagrama se apagó} start_y ++; // agregamos uno ay para que dibujemos la siguiente fila uno hacia abajo}}} // imprimimos un reloj usando palabras en lugar de números void word_clock () {cls (); números de caracteres [19] [10] ={"uno", "dos", "tres", "cuatro", "cinco", "seis", "siete", "ocho", "nueve", "diez", "once", "doce", "trece", "catorce", "quince", "dieciséis", "diecisiete", "dieciocho", "diecinueve"}; char numberstens [5] [7] ={"diez", "veinte", "treinta", "cuarenta", "cincuenta"}; // potencialmente 3 líneas para mostrar char str_a [8]; char str_b [8]; char str_c [8]; // byte horas_y, minutos_y; // horas y minutos y posiciones para las líneas de horas y minutos byte hours =rtc [2]; if (horas> 12) {horas =horas - ampm * 12; } if (horas <1) {horas =horas + ampm * 12; } consigue tiempo(); // obtiene la hora del byte del chip de reloj old_mins =100; // almacena minutos en old_mins. Comparamos los minutos y los viejos y, cuando son diferentes, redibujamos la pantalla. Ajústelo a 100 inicialmente para que la pantalla se dibuje cuando se inicie el modo. minutos de bytes; // ejecutar el bucle principal del reloj siempre que run_mode devuelva verdadero while (run_mode ()) {// comprobar si se presiona el botón if (buttonA.uniquePress ()) {switch_mode (); regreso; } if (buttonB.uniquePress ()) {display_date (); } consigue tiempo(); // obtiene la hora del chip de reloj mins =rtc [1]; // obtener minutos // si los minutos son diferentes de old_mins - volver a dibujar la pantalla if (mins! =old_mins) {// actualizar old_mins con el valor actual de minutos old_mins =mins; // restablecerlos para compararlos la próxima vez min =rtc [1]; horas =rtc [2]; // convierte las horas en formato de 12 horas if (horas> 12) {horas =horas - 12; } if (horas ==0) {horas =12; } // divide el valor en minutos en dos dígitos separados int mindigit =rtc [1]% 10; byte mindigitten =(rtc [1] / 10)% 10; // si min <=10, entonces la línea superior debe leer "minsdigti past" y la línea inferior dice hours if (mins <10) {strcpy (str_a, numbers [mindigti - 1]); strcpy (str_b, "PASADO"); strcpy (str_c, números [horas - 1]); } // si min =10, no se puede usar mindigit como arriba, por lo que el caso social imprime 10 últimas / n hora. if (minutos ==10) {strcpy (str_a, números [9]); strcpy (str_b, "PASADO"); strcpy (str_c, números [horas - 1]); } // si la hora no es la hora, es decir, ambos dígitos de los minutos no son cero, // luego haga que la primera línea diga "horas" y la 2 y la tercera líneas digan "minstens" "minutos", p. ej. "tres / n veinte / n uno" else if (mindigitten! =0 &&mindigit! =0) {strcpy (str_a, numeros [horas - 1]); // si los minutos están en los adolescentes, use los adolescentes de la matriz de números para la segunda línea, p. ej. "quince" // if (minutos> =11 &&minutos <=19) {if (minutos <=19) {strcpy (str_b, números [minutos - 1]); } else {strcpy (str_b, numberstens [mindigitten - 1]); strcpy (str_c, números [mindigit - 1]); }} // si el dígito de los minutos es cero, no lo imprima. leer leer "horas" "minutos" p. ej. "tres / n veinte" else if (mindigitten! =0 &&mindigit ==0) {strcpy (str_a, numeros [horas - 1]); strcpy (str_b, numberstens [mindigitten - 1]); strcpy (str_c, ""); } // si ambos minutos son cero, es decir, está en la hora, la línea superior dice "horas" y la línea inferior dice "en punto" else if (minsdigitten ==0 &&minsdigit ==0) {strcpy (str_a, números [horas - 1]); strcpy (str_b, "O'CLOCK"); strcpy (str_c, ""); }} // finaliza el tiempo de finalización del trabajo // se ejecuta en un bucle // imprime una línea de "doce" bytes len =0; while (str_a [len]) {len ++; }; // obtiene la longitud del byte del mensaje offset_top =(31 - ((len - 1) * 4)) / 2; // // trazar horas byte de línea i =0; while (str_a [i]) {puttinychar ((i * 4) + offset_top, 1, str_a [i]); i ++; } // mantener la pantalla pero comprobar si hay botones presionados int contador =1000; while (contador> 0) {// comprobar si se ha pulsado el botón if (buttonA.uniquePress ()) {switch_mode (); regreso; } if (buttonB.uniquePress ()) {display_date (); } retraso (1); encimera--; } fade_down (); // imprime la línea b len =0; while (str_b [len]) {len ++; }; // obtener la longitud del mensaje offset_top =(31 - ((len - 1) * 4)) / 2; i =0; while (str_b [i]) {puttinychar ((i * 4) + offset_top, 1, str_b [i]); i ++; } // mantener la pantalla pero comprobar si hay pulsaciones de botones contador =1000; while (contador> 0) {if (buttonA.uniquePress ()) {switch_mode (); regreso; } if (buttonB.uniquePress ()) {display_date (); } retraso (1); encimera--; } fade_down (); // imprime la línea c si la hay. len =0; while (str_c [len]) {len ++; }; // obtener la longitud del mensaje offset_top =(31 - ((len - 1) * 4)) / 2; i =0; while (str_c [i]) {puttinychar ((i * 4) + offset_top, 1, str_c [i]); i ++; } contador =1000; while (contador> 0) {// comprobar si se ha pulsado el botón if (buttonA.uniquePress ()) {switch_mode (); regreso; } if (buttonB.uniquePress ()) {display_date (); } retraso (1); encimera--; } fade_down (); // Mantén la pantalla en blanco pero comprueba que no haya presiones de botones antes de empezar de nuevo. contador =1000; while (contador> 0) {// comprobar si se ha pulsado el botón if (buttonA.uniquePress ()) {switch_mode (); regreso; } if (buttonB.uniquePress ()) {display_date (); } retraso (1); encimera--; }} fade_down ();} /// mensaje de desplazamiento - no se usa en este momento - demasiado lento.void scroll () {char message [] ={"Hola"}; cls (); byte p =6; // posición actual en el byte de cadena chara [] ={0, 1, 2, 3, 4, 5}; // caracteres de la cadena int x [] ={0, 6, 12, 18, 24, 30}; // xpos para cada byte de carácter y =0; // y pos // clear_buffer (); while (mensaje [p]! ='\ 0') {// dibuja los 6 caracteres para (byte c =0; c <6; c ++) {putnormalchar (x [c], y, mensaje [chara [c]] ); // dibuja una línea de píxeles apagados después de cada carácter; de lo contrario, los espacios entre los caracteres tienen píxeles del carácter anterior para (byte yy =0; yy <8; yy ++) {plot (x [c] + 5, aa, 0); } // quitar uno de cada posición de caracteres x [c] =x [c] - 1; } // restablece un carácter si ha desaparecido de la pantalla durante (byte i =0; i <=5; i ++) {if (x [i] <-5) {x [i] =31; chara [i] =p; p ++; }}}} // display_date - imprime el día de la semana, la fecha y el mes con un cursor parpadeante. Effectvoid display_date () {cls (); // lee la fecha del byte DS1307 dow =rtc [3]; // día de la semana 0 =domingo byte date =rtc [4]; byte mes =rtc [5] - 1; // matriz de nombres de meses para imprimir en la pantalla. Algunos están abreviados ya que solo tenemos 8 caracteres de ancho para jugar con los nombres de mes de caracteres [12] [9] ={"enero", "febrero", "marzo", "abril", "mayo", "junio", "julio" , "Agosto", "septiembre", "octubre", "noviembre", "diciembre"}; // imprime el nombre del día // obtiene la longitud del texto en píxeles, de esa manera podemos centrarlo en la pantalla divindin en los píxeles restantes b2 y usándolo como un byte de compensación len =0; while (daysfull [dow] [len]) {len ++; }; desplazamiento de bytes =(31 - ((len-1) * 4)) / 2; // nuestro desplazamiento para centrar el texto // imprime el nombre int i =0; while(daysfull[dow][i]) { puttinychar((i*4) + offset , 1, daysfull[dow][i]); i ++; } retraso (1000); fade_down(); cls(); // print date numerals char buffer[3]; itoa(date,buffer,10); offset =10; //offset to centre text if 3 chars - e.g. 3rd // first work out date 2 letter suffix - eg st, nd, rd, th etc // char suffix[4][3]={"st", "nd", "rd", "th" }; is defined at top of code 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; } //print the 1st date number puttinychar(0+offset, 1, buffer[0]); //if date is under 10 - then we only have 1 digit so set positions of sufix etc one character nearer byte suffixposx =4; //if date over 9 then print second number and set xpos of suffix to be 1 char further away if (date> 9){ suffixposx =8; puttinychar(4+offset, 1, buffer[1]); offset =8; //offset to centre text if 4 chars } //print the 2 suffix characters puttinychar(suffixposx+offset, 1, suffix[s][0]); puttinychar(suffixposx+4+offset, 1, suffix[s][1]); retraso (1000); fade_down(); //print the month name //get length of text in pixels, that way we can centre it on the display by divindin the remaining pixels b2 and using that as an offset len =0; while(monthnames[month][len]) { len++; }; offset =(31 - ((len-1)*4)) / 2; //our offset to centre up the text i =0; while(monthnames[month][i]) { puttinychar((i*4) +offset, 1, monthnames[month][i]); i ++; } retraso (1000); fade_down();}//dislpay menu to change the clock modevoid switch_mode() { //remember mode we are in. We use this value if we go into settings mode, so we can change back from settings mode (6) to whatever mode we were in. old_mode =clock_mode; char* modes[] ={ "Basic", "Small", "Slide", "Words", "Setup" }; byte next_clock_mode; byte firstrun =1; //loop waiting for button (timeout after 35 loops to return to mode X) for (int count =0; count <35; count++) { //if user hits button, change the clock_mode if (buttonA.uniquePress() || firstrun ==1) { count =0; cls(); if (firstrun ==0) { clock_mode++; } if (clock_mode> NUM_DISPLAY_MODES + 1 ) { clock_mode =0; } //print arrown and current clock_mode name on line one and print next clock_mode name on line two char str_top[9]; //strcpy (str_top, "-"); 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; } retraso (50); }}//run clock main loop as long as run_mode returns truebyte run_mode() { //if random mode is on... check the hour when we change mode. if (random_mode) { //if hour value in change mode time =hours. then reurn false =i.e. exit mode. if (change_mode_time ==rtc[2]) { //set the next random clock mode and time to change it set_next_random(); //exit the current mode. return 0; } } //else return 1 - keep running in this mode return 1;}//set the next hour the clock will change mode when random mode is onvoid set_next_random() { //set the next hour the clock mode will change - current time plus 1 - 4 hours get_time(); change_mode_time =rtc[2] + random (1, 5); //if change_mode_time now happens to be over 23, then set it to between 1 and 3am if (change_mode_time> 23) { change_mode_time =random (1, 4); } //set the new clock mode clock_mode =random(0, NUM_DISPLAY_MODES + 1); //pick new random clock mode}//dislpay menu to change the clock settingsvoid setup_menu() { char* set_modes[] ={ "Rndom", "24 Hr","Set", "Brght", "Exit"}; if (ampm ==0) { set_modes[1] =("12 Hr"); } byte setting_mode =0; byte next_setting_mode; byte firstrun =1; //loop waiting for button (timeout after 35 loops to return to mode X) for(int count=0; count <35; count++) { //if user hits button, change the clock_mode if(buttonA.uniquePress() || firstrun ==1){ count =0; cls(); if (firstrun ==0) { setting_mode++; } if (setting_mode> NUM_SETTINGS_MODES) { setting_mode =0; } //print arrown and current clock_mode name on line one and print next clock_mode name on line two 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; } retraso (50); } //pick the mode switch(setting_mode){ case 0:set_random(); descanso; case 1:set_ampm(); descanso; case 2:set_time(); descanso; case 3:set_intensity(); descanso; case 4://exit menu break; } //change the clock from mode 6 (settings) back to the one it was in before clock_mode=old_mode;}//toggle random mode - pick a different clock mode every few hoursvoid set_random(){ cls(); char text_a[9] ="Off"; char text_b[9] ="On"; byte i =0; //if random mode is on, turn it off if (random_mode){ //turn random mode off random_mode =0; //print a message on the display while(text_a[i]) { putnormalchar((i*6), 0, text_a[i]); i ++; } } else { //turn randome mode on. random_mode =1; //set hour mode will change set_next_random(); //print a message on the display while(text_b[i]) { putnormalchar((i*6), 0, text_b[i]); i ++; } } delay(1500); //leave the message up for a second or so}//set 12 or 24 hour clockvoid set_ampm() { // AM/PM or 24 hour clock mode - flip the bit (makes 0 into 1, or 1 into 0 for ampm mode) ampm =(ampm ^ 1); cls();}//change screen intensityintensityvoid set_intensity() { cls(); byte i =0; char text[7] ="Bright"; while(text[i]) { puttinychar((i*4)+4, 0, text[i]); i ++; } //wait for button input while (!buttonA.uniquePress()) { levelbar (0,6,(intensity*2)+2,2); //display the intensity level as a bar while (buttonB.isPressed()) { if(intensity ==15) { intensity =0; cls (); } else { intensity++; } //print the new value i =0; while(text[i]) { puttinychar((i*4)+4, 0, text[i]); i ++; } //display the intensity level as a bar levelbar (0,6,(intensity*2)+2,2); //change the brightness setting on the displays for (byte address =0; address <4; address++) { lc.setIntensity(address, intensity); } delay(150); } }}// display a horizontal bar on the screen at offset xposr by ypos with height and width of xbar, ybarvoid levelbar (byte xpos, byte ypos, byte xbar, byte ybar) { for (byte x =0; x  
LibrariesArduino
 Sin vista previa (solo descarga). 

Esquemas


Proceso de manufactura

  1. Secuenciador LED
  2. Reloj de cuco
  3. MATLAB - Matriz
  4. Mini batalla contra jefes
  5. Reloj maestro
  6. Reloj de Berlín
  7. Reloj POV LED de estilo analógico
  8. Matriz LED + Pantalla de puerta con sensor de movimiento [Arduino Holiday]
  9. Iluminación LED de 8x por sonido
  10. Arduino Cuadrúpedo
  11. Lámpara de matriz LED Hot Glue