Reloj Flip Arduino de matriz de un solo LED
Componentes y suministros
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 2 | ||||
| × | 1 |
Herramientas y máquinas necesarias
|
Aplicaciones y servicios en línea
|
Acerca de este proyecto
Construyo este RELOJ de módulo de matriz LED de 8x8 desarrollado por Adrian Jones. El tiempo se muestra desplazándose de izquierda a derecha o, bajo el control del software, de arriba a abajo. Cada dígito del tiempo se desliza sucesivamente desde el lado derecho y, cuando está centrado, se detiene momentáneamente y se ilumina ligeramente. Luego se desplaza hacia la izquierda mientras que el siguiente dígito de la pantalla se desplaza hacia la vista. El ciclo se repite con un breve retraso entre pantallas sucesivas. Para un giro vertical "de arriba a abajo", debe cambiar:
static boolean top2bottom =false;
para:
static boolean top2bottom =true;
Como puede ver en los comentarios del código, se pueden cambiar muchos parámetros, por ejemplo, scroll spreed, número de líneas en blanco entre caracteres, visualización de 12/24 horas, ms entre caracteres, brillo, etc.
El tiempo se puede configurar fácilmente mediante un codificador rotatorio. Un diodo de dos colores muestra el modo de configuración (minutos, horas o normal). Pongo el reloj en una caja formada por dos piezas básicas para que el acceso al interior de la caja sea muy conveniente y práctico.
Código
- código
código Arduino
// ******************************************* ****************************************** //// RELOJ MATRIZ // Adrian Jones, marzo de 2014 //// - permite el desplazamiento de izquierda a derecha y de arriba a abajo //// ******************** *********************************************** ****************** // # incluir// I2C-WIRE library # include // RTC-Library // definir max7219 registros y pasadores de control # define max7219_reg_noop 0x00 # define max7219_reg_digit0 0x01 # define max7219_reg_digit1 0x02 # define max7219_reg_digit2 0x03 # define max7219_reg_digit3 0x04 # define max7219_reg_digit4 0x05 # define max7219_reg_digit5 0x06 # define max7219_reg_digit6 0x07 # define max7219_reg_digit7 0x08 # define max7219_reg_decodeMode 0x09 # define max7219_reg_intensity 0x0A # define max7219_reg_scanLimit 0x0b # define max7219_reg_shutdown 0x0c # define max7219_reg_displayTest 0x0f # define dataIn 12 // DIN # define load 10 // CS #define clock 11 // CLKchar alphanum [] [8] ={{0x00,0x00,0x00,0x00,0x00,0x00 , 0x00,0x00}, // hexadecimal en blanco 20 de diciembre de 32 {0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x10}, //! 33 {0x00,0x28,0x28,0x28,0x00,0x00,0x00,0x00}, // "34 {0x00,0x28,0x7C, 0x28,0x7C, 0x28,0x00,0x00}, // # 35 {0x10,0x38, 0x50,0x38,0x14,0x54,0x38,0x10}, // $ {0x41,0xA2,0x44,0x08,0x10,0x22,0x45,0x82}, //% {0x38,0x44,0x44,0x38,0x50,0x4A, 0x44,0x3A}, // &{0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00}, // '{0x30,0x40,0x80,0x80,0x80,0x80,0x40,0x30}, // ( 40 {0xC0,0x20,0x10,0x10,0x10,0x10,0x20,0xC0}, //) {0x28,0x10,0xAA, 0x54,0xAA, 0x10,0x28,0x00}, // * {0x00,0x10,0x10, 0x10,0xFE, 0x10,0x10,0x10}, // + {0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x10}, //, {0x00,0x00,0x00,0x00,0x7E, 0x00,0x00, 0x00}, // - {0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18}, //. {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}, // / {0x7E , 0xC1,0xA1,0x91,0x89,0x85,0x83,0x7E}, // 0 {0x10,0x30,0x10,0x10,0x10,0x10,0x10,0x7C}, // 1 {0x38,0x44,0x82,0x04,0x18 , 0x20,0x40,0xFE}, // 2 50 {0x7C, 0x82,0x02,0x3C, 0x02,0x02,0x82,0x7C}, // 3 {0x08,0x18,0x28,0x48,0xFE, 0x08,0x08,0x08} , // 4 {0xFE, 0x80,0xF8,0x04,0x02,0x82,0x44,0x38}, // 5 {0x38,0x44,0x80,0xB8,0xC4 , 0x82,0x44,0x38}, // 6 {0xFE, 0x02,0x04,0x08,0x10,0x20,0x20,0x20}, // 7 {0x7C, 0x82,0x82,0x7C, 0x82,0x82,0x82,0x7C}, // 8 {0x7C, 0x82,0x82,0x7E, 0x02,0x82,0x44,0x38}, // 9 {0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x00}, //:{0x00,0x00, 0x18,0x18,0x00,0x18,0x18,0x30}, //; {0x00,0x10,0x20,0x40,0x80,0x40,0x20,0x10}, // <60 {0x00,0x00,0x00,0x7E, 0x00,0x7E, 0x00,0x00}, // ={0x00,0x80,0x40, 0x20,0x10,0x20,0x40,0x80}, //> {0x70,0x88,0x88,0x10,0x20,0x20,0x00,0x20}, //? {0x7E, 0x81,0x99,0xA1,0xA1,0x9E, 0x80,0x7E}, // @ {0x3C, 0x42,0x81,0x81,0xFF, 0x81,0x81,0x81}, // A {0xFC, 0x82,0x81,0xFE , 0x81,0x81,0x82,0xFC}, // B {0x3C, 0x42,0x81,0x80,0x80,0x81,0x42,0x3C}, // C {0xFC, 0x82,0x81,0x81,0x81,0x81,0x82,0xFC }, // D {0xFE, 0x80,0x80,0xFC, 0x80,0x80,0x80,0xFE}, // E {0xFE, 0x80,0x80,0xFC, 0x80,0x80,0x80,0x80}, // F 70 {0x3C , 0x42,0x81,0x80,0x87,0x81,0x42,0x3C}, // G {0x81,0x81,0x81,0xFF, 0x81,0x81,0x81,0x81}, // H {0xFE, 0x10,0x10,0x10,0x10 , 0x10,0x10,0xFE}, // I {0xFF, 0x08,0x08,0x08,0x08,0x88,0x88,0x70}, // J {0x88,0x90,0xA0,0xC0,0xA0,0x90,0x88,0x84}, // K {0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFE}, // L {0x81,0xC3,0xA5,0x99,0x81,0x81,0x81,0x81}, // M {0x81,0xC1, 0xA1,0x91,0x89,0x85,0x83,0x81}, // N {0x3C, 0x42,0x81,0x81,0x81,0x81,0x42,0x3C}, // O {0xFC, 0x82,0x81,0x82,0xFC, 0x80, 0x80,0x80}, // P 80 {0x3C, 0x42,0x81,0x81,0x81,0x85,0x42,0x3D}, // Q {0xFC, 0x82,0x81,0x82,0xFC, 0x84,0x82,0x81}, // R {0x3C, 0x42,0x81,0x40,0x3E, 0x81,0x42,0x3C}, // S {0xFE, 0x10,0x10,0x10,0x10,0x10,0x1 0,0x10}, // T {0x82,0x82,0x82,0x82,0x82,0x82,0x44,0x38}, // U {0x82,0x82,0x82,0x82,0x82,0x44,0x28,0x10}, // V {0x81,0x81,0x81,0x81,0x99,0xA5,0xC3,0x81}, // W {0x81,0x42,0x24,0x18,0x18,0x24,0x42,0x81}, // X {0x82,0x44,0x28,0x10 , 0x10,0x10,0x10,0x10}, // Y {0xFF, 0x02,0x04,0x08,0x10,0x20,0x40,0xFF}, // Z 90 {0xE0,0x80,0x80,0x80,0x80,0x80,0x80, 0xE0}, // [{0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}, // {0x07,0x01,0x01,0x01,0x01,0x01,0x01,0x07}, //] {0xE0, 0xA0,0xE0,0xA0,0xAA, 0x15,0x15,0x11}, // am (codificado como '^' {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E}, // _ {0x10,0x08, 0x00,0x00,0x00,0x00,0x00,0x00}, // '{0x00,0x00,0x38,0x04,0x3C, 0x44,0x48,0x34}, // a {0x00,0x40,0x40,0x40,0x78,0x44, 0x44,0x38}, // b {0x00,0x00,0x18,0x24,0x40,0x40,0x24,0x18}, // c {0x00,0x04,0x04,0x04,0x3C, 0x44,0x44,0x38}, // d 100 {0x00,0x00,0x38,0x44,0x7C, 0x40,0x44,0x38}, // e {0x00,0x18,0x20,0x20,0x78,0x20,0x20,0x20}, // f {0x00,0x38,0x44, 0x44,0x38,0x04,0x44,0x38}, // g {0x00,0x40,0x40,0x40,0x78,0x44,0x44,0x44}, // h {0x0 0,0x00,0x40,0x00,0x40,0x40,0x40,0x40}, // i {0x00,0x08,0x00,0x08,0x08,0x08,0x48,0x30}, // j {0x00,0x40,0x40,0x48, 0x50,0x60,0x50,0x48}, // k {0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x20}, // l {0x00,0x00,0x00,0x28,0x54,0x44,0x44,0x44} , // m {0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44}, // n 110 {0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x38}, // o {0x00, 0x00,0x70,0x48,0x48,0x70,0x40,0x40}, // p {0x00,0x00,0x30,0x48,0x48,0x38,0x08,0x08}, // q {0x00,0x00,0x00,0x30,0x48, 0x40,0x40,0x40}, // r {0x00,0x30,0x48,0x40,0x30,0x08,0x48,0x30}, // s {0x00,0x20,0x70,0x20,0x20,0x20,0x28,0x10}, / / t {0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x38}, // u {0x00,0x00,0x44,0x44,0x44,0x44,0x28,0x10}, // v {0x00,0x00,0x82 , 0x82,0x82,0x92,0x54,0x28}, // w {0x00,0x00,0x84,0x48,0x30,0x30,0x48,0x84}, // x 120 {0x00,0x48,0x48,0x48,0x38,0x08, 0x48,0x30}, // y {0x00,0x00,0x00,0x7C, 0x08,0x10,0x20,0x7C}, // z {0x00,0x30,0x40,0x40,0x80,0x40,0x40,0x30}, // { {0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20}, // | {0x00,0x60,0x10,0x10,0x08,0x10,0x10,0x60}, //} {0xE0,0xA0,0xE0,0x80,0x8A, 0x15,0x15,0x11} // códigos pm como '~' Hex 7E, dic 126}; // definir la operación RTC RTC_DS1307 RTC; // Módulo Tiny RTC (DS1307) (SDA - A4, SCL - A5) // Codificador rotatorio, interruptor y control LED # definir enc_PinA 2 // codificador A al pin 2 (interrupción 0) #definir enc_PinB 4 // codificador B a pin 4 # define enc_Switch 3 // conmutador del codificador al pin 3 (interrupción 1) #define mode_Pin 8 // LED de modo pin # define min_Pin 9 // minuto LED pinunsigned char enc_A, enc_B, enc_A_prev =0; static boolean rotating =false; static boolean en el sentido de las agujas del reloj =falso; static boolean updateFlag =false; static int mode =0; // 0 - nada, conjunto de 1 hora, conjunto de 2 minutos // definir cadenas de visualización # definir tamaño_array_máx 100char ac [tamaño_array_máx] ={}; byte rc [8] ={}; String display_message =""; int arraylen; // parámetros operativos # definir delay_line 75 // ms entre cambios de línea # definir delay_char 400 // ms entre caracteres # definir delay_mess 500 // ms entre mensajes # definir cblanks 1 // número de líneas en blanco entre caracteres # definir eblanks 0 // número de líneas en blanco adicionales (por encima de 8) al final del mensaje // mostrar característicasstatic boolean top2bottom =false; // dirección de visualización (de arriba a abajo o de derecha a izquierda estático booleano hour24 =falso; // visualización de 24 horas? static boolean charHI =true; // resaltar caracteres completos estático booleano doSerial =true; // salida en serie? // *** *********************************************** ************************************//// Configuración inicial//****** *********************************************** ********************************* // configuración vacía () {Wire.begin (); Serial.begin ( 57600); if (doSerial) Serial.print ("Reloj MATRIX - Adrian Jones, marzo de 2014"); // 8x8 pines de control de matriz LED pinMode (entrada de datos, SALIDA); pinMode (reloj, SALIDA); pinMode (carga, SALIDA ); initMatrix (); // inicializar la matriz de LED // Pines de LED pinMode (mode_Pin, OUTPUT); // pin de modo digitalWrite (mode_Pin, 1); pinMode (min_Pin, OUTPUT); // pin de minutos digitalWrite (min_Pin, 1); // control del codificador pinMode (enc_PinA, INPUT_PULLUP); digitalWrite (enc_PinA, HIGH); // codificador rotatorio pin A pinMode (enc_PinB, INPUT_PULLUP); digitalWrite (enc_PinB, HIGH); // rotativo codificador pin B pinMode (enc_Switch, INPUT_PULLUP); digitalWrite (enc_Switch, HIGH); // conmutador de codificador attachInterrupt (0, rotEncoder, CHANGE); // ajuste de tiempo attachInterrupt (1, swEncoder, CHANGE); // minutos / horas // RTC RTC.begin (); if (! RTC.isrunning ()) {RTC.adjust (DateTime (__ DATE__, __TIME__)); if (doSerial) Serial.println ("(reinicio de RTC)"); } else {if (doSerial) Serial.println ("(RTC en ejecución)"); }} // ******************************************** *******************************************//// Bucle principal/ / ********************************************** *************************************** // bucle vacío () {DateTime now =RTC.now (); // show_time_and_date (ahora); // mostrar el tiempo display_message =createMessage (ahora); arraylen =initDisplayString (display_message); if (updateFlag) {show_time_and_date (ahora); updateFlag =falso; } while (rotando) {retardo (1); // debounce adjTime (ahora, en el sentido de las agujas del reloj); show_time_and_date (RTC.now ()); display_message =createMessage (ahora); arraylen =initDisplayString (display_message); retraso (1); rotatorio =falso; // Restablece la bandera de interrupción a falso} delay (5); for (int i =0; i <(arraylen-7); i ++) {// recorre la matriz de mensajes, avanzando un byte a la vez para (int j =1; j <9; j ++) {maxSingle (j, ac [i + 8-j]); } // la fila 1 obtiene ac [i + 8], la fila 2 obtiene ac [i + 7] etc ... la fila 8 obtiene ac [i + 0] if (i% (8 + cblanks) ==0) {/ / cuando hay un carácter completo en la pantalla ... if (charHI) maxSingle (max7219_reg_intensity, 0x01); // ... aumenta el brillo y detiene temporalmente newDelay (delay_char); } else {// brillo normal maxSingle (max7219_reg_intensity, 0x00); newDelay (delay_line); }} if (modo ==0) newDelay (delay_mess);} // ******************************* *********************************************** / /// RUTINAS DE INTERRUPCIÓN // **************************************** ************************************** //// función rotEncoder ():ISR llamado cuando el codificador rotatedvoid rotEncoder () {delay (1); enc_A =digitalRead (enc_PinA); enc_B =digitalRead (enc_PinB); if (! enc_A &&enc_A_prev) {// cambio de estado en el sentido de las agujas del reloj =(! enc_A &&enc_B)? verdadero Falso; if (modo! =0) rotating =true; } enc_A_prev =enc_A; // Almacenar el valor de A para la próxima vez} // función swEncoder ():ISR llamado cuando se presiona el botón del codificador para evitar swEncoder () {delay (1); if (digitalRead (enc_Switch)! =LOW) return; // si se oprime el interruptor delay (1); // debounce if (digitalRead (enc_Switch)! =LOW) return; // si el conmutador aún está presionado en modo ++; modo =modo% 3; // modo de incremento digitalWrite (mode_Pin,! (mode ==1)); // hora ajusta LED digitalWrite (min_Pin,! (modo ==2)); // minuto ajustar LED updateFlag =true;} // ************************************ ****************************************** //// RUTINAS DE OPERACIÓN // ********************************************* ********************************* //// función newDelayvoid newDelay (int dly) {for (int z =1; z =25) adj_hrs =1; } else {// disminuir if (adj_hrs ==0) adj_hrs =24; si (- adj_hrs <=0) adj_hrs =24; } RTC.adjust (DateTime (now.year (), now.month (), now.day (), adj_hrs, now.minute (), now.second ())); } if (modo ==2) {// ajustar los minutos int adj_mins =ahora.minuto (); if (dir) {if (++ adj_mins> =60) adj_mins =0; } else {if (- adj_mins <0) adj_mins =59; } RTC.adjust (DateTime (now.year (), now.month (), now.day (), now.hour (), adj_mins, now.second ())); }} // función rotChar (char):para el carácter char, transpone bits 90 grados. (arriba - abajo ==> izquierda - derecha) // y almacena los resultados en rc [0] - rc [7] .byte rotChar (char inLetter) {int ind =int (inLetter) - 0x20; for (int col =0; col <8; col ++) {máscara de byte =0x01 <<(7-col); for (int fila =0; fila <8; fila ++) {bitWrite (rc [col], 7-row, (alfanum [ind] [fila] y máscara)); }}} // función show_time_and_date:imprime la cadena de tiempo &bytesvoid show_time_and_date (DateTime datetime) {if (doSerial) {int minutes =datetime.minute (); int hours =datetime.hour (); si (horas ==0) horas =24; int segundos =fecha y hora.segundo (); char delim ='/'; char dend =''; String te ="Fecha / hora actual:"; te =te + datetime.year () + delim + datetime.month () + delim + datetime.day () + dend; Serial.print (te); if (horas <10) Serial.print (0); Serial.print (horas, DEC); Serial.print (":"); if (minutos <10) Serial.print (0); Serial.print (minutos, DEC); Serial.print (":"); if (segundos <10) Serial.print (0); Serial.print (segundos, DEC); Serial.println (""); }} String createMessage (DateTime datetime) {String new_mess =""; int hr =datetime.hour ()% 24; si (hr ==0) hr =24; int mn =datetime.minute (); if (mode ==0) {// Modo normal if (hour24) {new_mess + =hr; } más {new_mess + =(hr> 12)? hr - 12:hr; } new_mess + =':'; if (mn <10) new_mess + ='0'; new_mess + =mn; if (! hour24) new_mess + =(hr> 12)? "~":"^"; } if (mode ==1) {// Ajustando horas new_mess + =hr; } if (mode ==2) {// Ajustando los minutos if (mn <10) new_mess + ='0'; new_mess + =mn; } return new_mess;} // función initDisplayString ():crea una matriz de cadena de mensaje con espacios en blanco entre los caracteres y al final initDisplayString (String message) {int x =0; for (int y =0; y > 1); // poner datos digitalWrite (cargar, ALTO);} // función putByte ():carga datos a la matriz, MSB a LSB void putByte (datos de bytes) {byte i =8; máscara de bytes; while (i> 0) {// MSB a LSB máscara =0x01 <<(i - 1); // crea una máscara de bits digitalWrite (reloj, BAJO); // marque if (datos y máscara) {// elija bit digitalWrite (dataIn, HIGH); // envíe 1} else {digitalWrite (dataIn, LOW); // enviar 0} digitalWrite (reloj, ALTO); // tac --i; // mover a un bit menor}}
Esquemas
Proceso de manufactura
- Reloj de visión pov de Arduino
- El reloj IV9 Numitron más simple de bricolaje con Arduino
- Reloj maestro
- Arduino Nano Tetris Game en una matriz casera de 16x8
- MotionSense
- Matriz LED + Pantalla de puerta con sensor de movimiento [Arduino Holiday]
- Arduino Cuadrúpedo
- Control del brillo del LED usando Bolt y Arduino
- Medidor de IoT con Arduino, Yaler e IFTTT
- Levitación electromagnética repulsiva Arduino
- Registrador de datos de globos meteorológicos con tecnología Arduino