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 despertador LCD con muchas caras

Componentes y suministros

Arduino UNO
Si usa la PCB incluida, use un microprocesador ATmega328 DIL, cristal de 16MHz, condensadores de 2x22pf, regulador 7805, Condensador de 100 uF 16 V, 3 condensadores de 0,1 uF y condensador de 1 uF.
× 1
Resistencia de 10k ohmios
× 4
Resistencia de orificio pasante, 470 ohmios
× 1
LCD estándar Adafruit - 16x2 blanco sobre azul
× 1
Buzzer
× 1
Condensador 10 µF
× 1
Reloj en tiempo real (RTC)
DS1302 RTC
× 1
Cristal de 32,768 kHz
× 1
Batería tipo botón CR2032
+ titular. Si usa una PCB, use la batería CR1220 y el soporte
× 1
Interruptor de inclinación, encapsulado
Interruptor de mercurio
× 1
Potenciómetro de ajuste, 10 kohm
× 1

Herramientas y máquinas necesarias

Impresora 3D (genérica)

Aplicaciones y servicios en línea

Arduino IDE

Acerca de este proyecto

Se puede encontrar una nueva versión con 10 esferas de reloj aquí .


Buscando algo para construir, me decidí por un reloj LCD 1602. Después de examinar la Web y encontrar muchas implementaciones diferentes, decidí por qué no hacer un reloj que las incorpore todas.

Funciones del reloj

  • Ocho estilos de visualización diferentes
  • Establecer hora, fecha actual, fecha de nacimiento y alarma
  • Interruptor de mercurio para apagar la alarma
  • Control de luz de fondo
  • Sensor de temperatura y humedad DHT21

Versión protoboard

La electrónica real es bastante simple.

Una vez conectado, cargue el boceto en su Arduino IDE y cárguelo en Arduino UNO. (No se muestra si el DHT21 está conectado a D9)

Usando el reloj

El reloj tiene tres botones:SETUP, INCREMENT, DECREMENT y un interruptor TILT.

Cuando la luz de fondo está apagada, al presionar cualquier botón se encenderá la luz de fondo. Si no se presiona ningún botón mientras la luz de fondo está encendida, se apagará automáticamente después de 5 segundos. Mientras la luz de fondo está encendida, los botones realizarán las siguientes tareas:

CONFIGURACIÓN - Esto abre las pantallas de CONFIGURACIÓN. El carácter de corchete de ángulo recto es el cursor. Al presionar los botones INCREMENTO o DECREMENTO aumentará o disminuirá el valor en el que se encuentra el cursor respectivamente. Al presionar el botón SETUP nuevamente, el cursor cambiará entre Horas, Minutos, Día, Mes, Año, Día de nacimiento, Mes de nacimiento, Año de nacimiento, Horas de alarma, Minutos de alarma y volverá al modo RELOJ.

INCREMENTO - Cuando no está en las pantallas de CONFIGURACIÓN, este botón cambia entre los distintos estilos de reloj.

DECRETO - Cuando no está en las pantallas de CONFIGURACIÓN, este botón activa o desactiva la alarma.

INTERRUPTOR DE INCLINACIÓN - Cuando la alarma está sonando, inclinar el reloj o presionar cualquier botón apagará la alarma.

Construyendo un reloj completamente terminado

Llevar su construcción de la placa a un reloj completamente terminado requerirá una placa de circuito impreso y algunos componentes adicionales. Los archivos Eagle se adjuntan en caso de que desee que el PCB se fabrique comercialmente o haga lo que yo hice y lo haga usted mismo. Usé el método Toner.

NOTA:Debido a que la pantalla LCD 1602 está conectada a la PCB principal mediante un cabezal de clavija en ángulo recto, puede resultar muy difícil insertar la placa y la pantalla en la carcasa cuando ya están soldados. Tener una placa de doble cara con revestimiento de orificios pasantes le permitirá soldar la pantalla a la placa en su lugar.

Usando piezas que tenía en el taller, el Arduino UNO fue reemplazado por un chip DIL ATMega328, cristal de 16MHz y dos capacitores cerámicos de 22pf. El regulador de 5V es del tipo 7805 TO-220 y un capacitor de 100uF 16V para suavizar. El RTC es un DS1302 con un cristal de reloj de 32,768 KHz. El altavoz es un zumbador pasivo que está aislado en CC con un condensador de 10uF 16V. Los condensadores de 0,1 uF y 1 uF son condensadores cerámicos monolíticos (espaciado de orificios de 5 mm). Las resistencias son 5% 1/8 vatios o puede usar 1/4 vatios si lo desea. El interruptor de mercurio puede ser de cualquier tamaño. El mío era de 5 mm de diámetro, pero uno más pequeño será suficiente. Los tres botones táctiles montados en la parte posterior del tablero son de 6 mm x 6 mm con un eje de 13 mm.

La carcasa está impresa en 3D con una altura de capa de 0,2 mm y sin soportes. Taladre los orificios de montaje de la placa de circuito impreso con un taladro de 2,5 mm y cree una rosca con un grifo de 3 mm. Utilice tornillos M3 de 6 mm para asegurar la placa en su lugar. También perforé los cuatro orificios de montaje en la PCB a 4 mm para permitir cualquier ajuste necesario para evitar que los botones se peguen a la carcasa al asegurar la placa.

Créditos

Este reloj es una combinación de varios relojes que varios fabricantes han fabricado a lo largo de los años.

La base de este reloj es el reloj digital Arduino con función de alarma (PCB personalizado). Modifiqué la carcasa para que se imprimiera en dos piezas y no en cuatro.

  • Diseño de pantalla estándar de Michalis Vasilakis
  • Fuente Dual Thick de Arduino World
  • Fuente Dual Beveled de Arduino Forum
  • Fuente Dual Trek de Carrie Sundra
  • Fuente Dual Thin de Arduino World
  • Concepto de Word de LAGSILVA
  • Reloj de biorritmo de John Bradnam
  • Reloj meteorológico de ARDUinoautoMOTIVE

Actualizaciones

29/06/20

  - Se corrigieron errores de ortografía en el reloj WORD 
- Se agregaron #defines para controlar la luz de fondo
- Se aumentó el tiempo de espera de la luz de fondo de 5 a 10 segundos

23/11/20

  - Se agregó la configuración de la fecha de nacimiento y el almacenamiento EEPROM 
- Se agregó la esfera del reloj de biorritmo
- Se limpió la codificación de la pantalla de configuración

Se plantea la hipótesis de que, según nuestra fecha de nacimiento, los biorritmos podrían determinar los altibajos de nuestra vida. Los biorritmos constan de tres ciclos:un ciclo físico de 23 días, un ciclo emocional de 28 días y un ciclo intelectual de 33 días. El reloj de biorritmo muestra cada estado como una barra.

La barra muestra que el biorritmo está en un ciclo positivo (barra superior) o un ciclo negativo (barra inferior). La longitud de la barra muestra qué tan positivo o negativo es en el ciclo.

12/06/20

  - Se agregó compatibilidad con DHT21 
- Se agregó el termómetro y la esfera del reloj de humedad

Se ha agregado una nueva esfera de reloj meteorológico. Lee un sensor de temperatura y humedad DHT21 agregado a la parte posterior de la caja. La PCB se ha actualizado para incluir un conector de 3 pines al sensor DHT21.


Código

  • DigitalClockAlarmV7.ino
DigitalClockAlarmV7.ino C / C ++
 / * 1602 LCD despertador * de John Bradnam ([email protected]) * * Pantalla 16x2:Configuración:Configurar alarma * + ---------------- + + - --------------- + + ---------------- + * | HH:MM:SS | HH:MM | |> HH:> MM | | Establecer alarma | * | DD / MM / AA | ALARMA | |> DD /> MM /> AAAA | |> HH:> MM | * + ---------------- + + ---------------- + + ------------ ---- + * * 25/06/2020 * - Tomó el reloj de Michalis Vasilakis como base de código (https://www.instructables.com/id/Arduino-Digital-Clock-With-Alarm-Function-custom-P/ ) * - Modificado para adaptarse al hardware - DS1302 RTC y retroiluminación LCD * - Soporte agregado para diferentes estilos de pantalla * - Diseño de pantalla estándar de Michalis Vasilakis * - Fuente Dual Thick de Arduino World (https://www.hackster.io/thearduinoworld/ arduino-digital-clock-version-1-b1a328) * - Fuente Dual Bevelled de Arduino Forum (https://forum.arduino.cc/index.php/topic,8882.0.html) * - Fuente Dual Trek de Carrie Sundra ( https://www.alpenglowindustries.com/blog/the-big-numbers-go-marching-2x2) * - Fuente Dual Thin de Arduino World (https://www.hackster.io/thearduinoworld/arduino-digital-clock -version-2-5bab65) * - Concepto de Word por LAGSILVA (https://www.hackster.io/lagsilva/text-clock-bilingual-en-pt-with-arduino-881a6e) * 29/06/20 * - Se corrigieron errores de ortografía en el reloj WORD * - Se agregaron #defines a cont retroiluminación de rol * - Se aumentó el tiempo de espera de la retroiluminación de 5 a 10 segundos * 22/11/20 * - Se agregó la configuración de la fecha de nacimiento y el almacenamiento EEPROM * - Se agregó la esfera del reloj Biorhythm * - Se mejoró la codificación de la pantalla de configuración * xx / xx / 21 * - Se agregó DHT21 Soporte * - Termómetro y reloj de humedad agregados * /// Bibliotecas # incluyen  #include  #include  #include  #include  # include  // descomente si desea que la variante de pantalla doble gruesa o delgada muestre el formato de 12 horas // # defina DUAL_THICK_12HR // # defina DUAL_THIN_12HR // descomente para controlar la retroiluminación // # defina NO_BACKLIGHT // # defina BACKLIGHT_ALWAYS_ON # define BACKLIGHT_TIMEOUT 10000 // descomenta para probar los gráficos de biorritmo // # define TEST_BIO_GRAPHS # define LIGHT 2 // PD2 # define LCD_D7 3 // PD3 # define LCD_D6 4 // PD4 # define LCD_D5 5 // PD5 # define LCD_D4 6 // PD6 # definir LCD_E 7 // PD7 # definir LCD_RS 8 // PB0 # definir BTN_SET A0 // PC0 # definir BTN_ADJUST A1 // PC1 # definir BTN_ALARM A2 // PC2 # definir BTN_TILT A3 // PC3 # definir ALTAVOZ 11 // PB3 # definir DHT 21 9 // PB1 # define RTC_CE 10 // PB2 # define RTC_IO 12 // PB4 # define RTC_SCLK 13 // PB5 // Conexiones y constantes LiquidCrystal lcd (LCD_RS, LCD_E, LCD_D4, LCD_D5, LCD_D6, LCD_D7); DS1302RTC rtc ( RTC_CE, RTC_IO, RTC_SCLK); dht DHT; char daysOfTheWeek [7] [12] ={"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; const int monthDays [12] ={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; intervalo largo =300; int melody [] ={600, 800, 1000,1200}; // Variablesint DD, MM, YY, H, M, S, temp, hum, set_state, adjust_state, alarm_state, AH, AM, shake_state, BY, BM, BD; int shakeTimes =0; int i =0; String sDD; String sMM; String sYY; String sH; String sM; String sS; String sBD; String sBM; String sBY; String aH ="12"; String aM =" 00 "; String sTMP; String sHUM; // String alarm =" "; long prevAlarmMillis =0; long prevDhtMillis =0; // Boolean flagsboolean setupScreen =false; boolean alarmON =false; boolean turnItOn =false; enumeración ESTILO {ESTÁNDAR, DUAL_THICK, DUAL_BEVEL, DUAL_TREK, DUAL_THIN, WORD, BIO, THERMO}; STYLE currentStyle =STANDARD; enum SETUP {CLOCK, TIME_HOUR, TIME_MIN, TIME_DAY, TIME_MONTH, TIME_YEAR, CUMPLE_DAY_ESTABLECIMIENTO, CUMPLEAÑOS, CUMPLEAÑOS;; bool backlightOn =false; long backlightTimeout =0; byte customChar [8]; // --------------------- EEPROM --------- --------------------------------- # define EEPROM_AH 0 // Horas de alarma # define EEPROM_AM 1 // Minutos de alarma # definir EEPROM_AO 2 // Alarma encendida / apagada # definir EEPROM_CS 3 // Estilo actual # definir EEPROM_BY 4 // Año de nacimiento # definir EEPROM_BM 6 // Mes de nacimiento # definir EEPROM_BD 7 // Día de nacimiento // --------- ------------ Word clock ------------------------------------ --Unidades de cadena [] ={"CIENTOS", "UNO", "DOS", "TRES", "CUATRO", "CINCO", "SEIS", "SIETE", "OCHO", "NUEVE"}; Cadena adolescentes [] ={"DIEZ", "ELEVEN", "DOCE", "TRECE", "CATORCE", "QUINCE", "SIXTEEN", "DIECISIETE", "DIECIOCHO", "NINETEEN"}; Cadena decenas [] ={"", "", "VEINTE", "TREINTA", "CUARENTA", "CINCUENTA"}; // ---------------------- Reloj de arena animación ---------------------------- # define HOURGLASS_FRAMES 8 # define HOURGLASS_CHAR 0 # define FRAME_TIMEOUT 200; int nextFrame =0; long frameTimeout =0; reloj de arena de byte constante [HOURGLASS_FRAMES] [8] PROGMEM ={{B11111, B11111, B01010, B01010, B01010, B01010, B10001, B11111}, {B11111, B11011, B01110, B01010, B1011, B1, B1 {B11111, B10001, B01110, B01110, B01010, B01010, B10001, B11111}, {B11111, B10001, B01010, B01110, B01110 , B01010, B10001, B11111}, {B11111, B10001, B01010, B01010, B01110, B01110, B10001, B11111}, {B11111, B10001, B01010, B01010, B01010, B01110, B10101, B11111, B11111, , B01010, B01010, B01110, B11011, B11111}, {B11111, B10001, B01010, B01010, B01010, B01010, B11111, B11111}, // {B11111, B10001, B01010, B01010, B01011, B1; // ---------------------- Caracteres personalizados de alarma, reloj y DHT ------------------ ---------- # define BELL_CHAR 1 # define CLOCK_CHAR 2 # define THERMOMETER_CHAR 3 # define DROPLET_CHAR 4const byte bell [8] PROGMEM ={0x4, 0xe, 0xe, 0xe, 0x1f, 0x0, 0x4}; const reloj de bytes [8] PROGMEM ={0x0, 0xe, 0x15, 0x17, 0x11, 0xe, 0x0}; termómetro de byte constante [8] PROGMEM ={0x4, 0xa, 0xa, 0xe, 0xe, 0x1f, 0x1f, 0xe}; const gota de byte [8] PROGMEM ={0x4, 0x4, 0xa, 0xa, 0x11, 0x11, 0x11, 0xe}; # define DHT_UPDATE_INTERVAL 6000 // ------------------- --- BioRhythm Clock ---------------------------- // Constantes de caracteres personalizados (M es MSB o carácter de barra superior r, L es LSB o carácter de barra inferior # define PHYSICAL_M 3 # define PHYSICAL_L 4 # define EMOTIONAL_M 5 # define EMOTIONAL_L 6 # define INTELLECTUAL_M 7 # define INTELLECTUAL_L 8 // --------------- ------- Fuente cuadrada gruesa ---------------------------- # define C0 3 # define C1 4 # define C2 5 #define C3 6const byte C_0 [8] PROGMEM ={0x1F, 0x1F, 0x1F, 0x00,0x00,0x00,0x00,0x00}; const byte C_1 [8] PROGMEM ={0x1F, 0x1F, 0x1F, 0x00,0x00,0x1F, 0x1F, 0x1F}; byte constante C_2 [8] PROGMEM ={0x00,0x00,0x00,0x00,0x00,0x1F, 0x1F, 0x1F}; byte constante C_3 [8] PROGMEM ={0x00,0x00,0x0E, 0x0A, 0x0A, 0x0E, 0x00,0x00}; const byte blockChar [11] [2] [3] ={{{255, C0, 255}, {255, C2, 255}}, // 0 {{C0, 255, 32} , {C2, 255, C2}}, // 1 {{C0, C0, 255}, {255, C1, C2}}, // 2 {{C1, C1, 255}, {C1, C1, 255} }, // 3 {{255, C2, 255}, {32, 32, 255}}, // 4 {{255, C1, C1}, {C2, C2, 255}}, // 5 {{255 , C0, C0}, {255, C1, 255}}, // 6 {{C0, C1, 255}, {32, C0, 255}}, // 7 {{255, C1, 255}, {255 , C1, 255}}, // 8 {{255, C1, 255}, {C2, C2, 255}}, // 9 {{32, 32, 32}, {32, 32, 32}}, // En blanco}; // ---------------------- Fuente de bisel grueso -------------- -------------- # definir LT 0 # definir UB 1 # definir RT 2 # definir LL 3 # definir LB 4 # definir LR 5 # definir UMB 6 # definir LMB 7const byte _LT [8 ] PROGMEM ={B00111, B01111, B11111, B11111, B11111, B11111, B11111, B11111}; byte constante _UB [8] PROGMEM ={B11111, B11111, B11111, B00000, B00000, B00000, B00000, B00000 byte [8] PROGMEM ={B11100, B11110, B11111, B11111, B11111, B11111, B11111, B11111}; byte constante _LL [8] PROGMEM ={B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111, const byte _LB [8] PROGMEM ={B00000, B00000, B00000, B00000, B00000, B11111, B11111, B11111}; byte constante _LR [8] PROGMEM ={B11111, B11111, B11111, B11111, B11111, B110111, B11; byte constante _UMB [8] PROGMEM ={B11111, B11111, B11111, B00000, B00000, B00000, B11111, B11111}; byte constante _LMB [8] PROGMEM ={B11111, B11111, B11111, B11111, B111, B111, B11111}; byte constante bevelChar [11] [2] [3] ={{{LT, UB, RT}, {LL, LB, LR} }, // 0 {{UB, RT, 32}, {LB, LMB, LB}}, // 1 {{UMB, UMB, RT}, {LL, LB, LB}}, // 2 {{UMB , UMB, RT}, {LB, LB, LR}}, // 3 {{LL, LB, LMB}, {32, 32, LMB}}, // 4 {{LT, UMB, UMB}, {LB , LB, LR}}, // 5 {{LT, UMB, UMB}, {LL, LB, LR}}, // 6 {{UB, UB, RT}, {32, 32, LT}}, / / 7 {{LT, UMB, RT}, {LL, LB, LR}}, // 8 {{LT, UMB, RT}, {32, 32, LR}}, // 9 {{32, 32, 32}, {32, 32, 32}} // En blanco}; // ---------------------- Trek Font -------- -------------------- # definir K0 0 # definir K1 1 # definir K2 2 # definir K3 3 # definir K4 4 # definir K5 5 # definir K6 6 # definir K7 7 byte constante K_0 [8] PROGMEM ={0x1F, 0x1F, 0x00,0x00,0x00,0x00,0x00,0x00}; byte constante K_1 [8] PROGMEM ={0x18,0x18,0x18,0x18,0x18,0x18,0x18, 0x18}; byte constante K_2 [8] PROGMEM ={0x00,0x00,0x00,0x00,0x00,0x00,0x1F, 0x1F}; byte constante K_3 [8] PROGMEM ={0x1F, 0x1F, 0x03,0x03,0x03,0x03, 0x1F, 0x1F}; byte constante K_4 [8] PROGMEM ={0x1F, 0x1F, 0x18,0x18,0x18,0x18,0x1F, 0x1F}; byte constante K_5 [8] PROGMEM ={0x1F, 0x1F, 0x18,0x18,0x18, 0x18,0x18,0x18}; byte constante K_6 [8] PROGMEM ={0x03,0x03,0x03,0x03, 0x03,0x03,0x1F, 0x1F}; byte constante K_7 [8] PROGMEM ={0x1F, 0x1F, 0x03,0x03,0x03,0x03,0x03,0x03}; byte constante trekChar [11] [2] [2] ={{ {K5, K7}, {255, K6}}, // 0 {{K0, K1}, {K2, 255}}, // 1 {{K0, K3}, {255, K2}}, // 2 {{K0, K3}, {K2, 255}}, // 3 {{K1, 255}, {K0, K1}}, // 4 {{K4, K0}, {K2, 255}}, // 5 {{K5, K0}, {K4, 255}}, // 6 {{K0, 255}, {32, K1}}, // 7 {{255, K3}, {K4, 255}}, / / 8 {{255, K3}, {K2, K6}}, // 9 {{32, 32}, {32, 32}}, // En blanco}; // ---------- ------------ Thin Font ---------------------------- # define T0 0 # define T1 1 # definir T2 2 # definir T3 3 # definir T4 4 # definir T5 5 # definir T6 6 # definir T7 7const byte T_0 [8] PROGMEM ={0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02}; const byte T_1 [8] PROGMEM ={0x0E, 0x02,0x02,0x02,0x02,0x02,0x02,0x0E}; byte constante T_2 [8] PROGMEM ={0x0E, 0x08,0x08,0x08,0x08,0x08,0x08,0x0E}; byte constante T_3 [8] PROGMEM ={0x0E, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0E}; byte constante T_5 [8] PROGMEM ={0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A 0x0E}; byte constante T_4 [8] PROGMEM ={0x0E, 0x0A, 0x0A, 0x0A, 0x0 A, 0x0A, 0x0A, 0x0A}; byte constante T_6 [8] PROGMEM ={0x0E, 0x02,0x02,0x02,0x02,0x02,0x02,0x02}; byte constante T_7 [8] PROGMEM ={0x18,0x18,0x18, 0x18,0x18,0x1E, 0x1F, 0x1F}; // lcd dibujar funciones de caracteresconst byte thinChar [11] [2] ={{T4, T5}, // 0 {T0, T0}, // 1 {T1, T2} , // 2 {T1, T1}, // 3 {T5, T6}, // 4 {T2, T1}, // 5 {T2, T3}, // 6 {T6, T0}, // 7 { T3, T3}, // 8 {T3, T1}, // 9 {32, 32} // en blanco}; // ---------------------- Inicialización general ------------------------ ---- configuración vacía () {Serial.begin (115200); // Establecer salidas / entradas pinMode (BTN_SET, INPUT); pinMode (BTN_ADJUST, ENTRADA); pinMode (BTN_ALARM, ENTRADA); pinMode (BTN_TILT, ENTRADA); pinMode (ALTAVOZ, SALIDA); pinMode (LUZ, SALIDA); // Compruebe si el RTC tiene una fecha / hora válida, si no lo configura en 00:00:00 01/01/2018. // Esto solo se ejecutará la primera vez o si la batería de moneda está baja. // setSyncProvider () hace que la biblioteca Time se sincronice con el // RTC externo llamando a RTC.get () cada cinco minutos de forma predeterminada. setSyncProvider (rtc.get); if (timeStatus ()! =timeSet) {Serial.println ("Configuración de la hora predeterminada"); // Establecer RTC tmElements_t tm; tm.Year =CalendarYrToTm (2020); tm.Month =06; tm.Día =26; tm.Hora =7; tm.Minute =52; tm.Second =0; time_t t =makeTime (tm); // use el valor time_t para asegurarse de que se establece el día de la semana correcto if (rtc.set (t) ==0) {// Success setTime (t); } else {Serial.println ("¡Falló el conjunto de RTC!"); }} retraso (100); // Leer la hora de la alarma de la memoria EEPROM AH =EEPROM.read (EEPROM_AH); AM =EEPROM.read (EEPROM_AM); byte ao =EEPROM.read (EEPROM_AO); alarmON =(ao! =0); byte cs =EEPROM.read (EEPROM_CS); // Comprueba si los números que lees son válidos. (Horas:0-23 y Minutos:0-59) si (AH> 23) {AH =0; } si (AM> 59) {AM =0; } // Leer fecha de nacimiento de EEPROM BY =(EEPROM.read (EEPROM_BY + 0) <<8) | EEPROM.read (EEPROM_BY + 1); si (POR <1900 || POR> 2099) {POR =2000; } BM =EEPROM.read (EEPROM_BM); si (BM <0 || BM> 12) {BM =1; } BD =EEPROM.read (EEPROM_BD); si (BD <0 || BD> 31) {BD =1; } // Configurar el estilo actual lcd.begin (16,2); currentStyle =(cs> (uint8_t) THERMO)? ESTÁNDAR:(ESTILO) cs; switch (currentStyle) {case ESTÁNDAR:lcdStandardSetup (); descanso; case DUAL_THICK:lcdDualThickSetup (); descanso; case DUAL_BEVEL:lcdDualBevelSetup (); descanso; case DUAL_TREK:lcdDualTrekSetup (); descanso; case DUAL_THIN:lcdDualThinSetup (); descanso; CASO PALABRA:lcdWordSetup (); descanso; caso BIO:lcdBioRhythmSetup (); descanso; case THERMO:lcdThermometerSetup (); descanso; } #ifdef BACKLIGHT_ALWAYS_ON switchBacklight (true); # endif} // ---------------------- Bucle del programa principal ----------- ----------------- bucle vacío () {readBtns (); // Leer botones getTimeDate (); // Leer la hora y la fecha de RTC getTempHum (); // Leer temperatura y humedad if (! SetupScreen) {lcdPrint (); // Imprime normalmente la hora / fecha / alarma actual en la pantalla LCD if (alarmON) {callAlarm (); // y verifique la alarma si está activada if (turnItOn) {switchBacklight (true); }} //Serial.println("backlightTimeout="+ String (backlightTimeout) +", millis () ="+ String (millis ()) +", backlightOn ="+ String (backlightOn)); # ifdef BACKLIGHT_TIMEOUT if ( backlightOn &&(millis ()> backlightTimeout)) {switchBacklight (falso); } #endif} else {timeSetup (); // Si se presiona el conjunto de botones, llame a la función de configuración de la hora switchBacklight (true); }} // ---------------------------------------------- ---- // Leer botones statevoid readBtns () {set_state =digitalRead (BTN_SET); ajuste_estado =digitalRead (BTN_ADJUST); estado_de_alarma =lectura digital (BTN_ALARM); if (! backlightOn &&! setupScreen) {if (set_state ==LOW || ajuste_state ==LOW || alarm_state ==LOW) {// Enciende el interruptor de luz de fondoBacklight (true); // es necesario mantener pulsado el botón durante al menos 1/2 segundo de retraso (500); }} else {if (! setupScreen) {if (alarm_state ==LOW) {alarmON =! alarmON; EEPROM.write (EEPROM_AO, (alarma ON)? 1:0); retraso (500); switchBacklight (verdadero); } si no (ajuste_estado ==BAJO) {estilo actual =(estilo actual ==TERMO)? ESTÁNDAR:(ESTILO) ((int) currentStyle + 1); EEPROM.write (EEPROM_CS, (byte) currentStyle); switch (currentStyle) {case ESTÁNDAR:lcdStandardSetup (); descanso; case DUAL_THICK:lcdDualThickSetup (); descanso; case DUAL_BEVEL:lcdDualBevelSetup (); descanso; case DUAL_TREK:lcdDualTrekSetup (); descanso; case DUAL_THIN:lcdDualThinSetup (); descanso; CASO PALABRA:lcdWordSetup (); descanso; caso BIO:lcdBioRhythmSetup (); descanso; case THERMO:lcdThermometerSetup (); descanso; } lcd.clear (); lcdPrint (); retraso (500); switchBacklight (verdadero); }} if (set_state ==LOW) {setupMode =(setupMode ==ALARM_MIN)? RELOJ:(CONFIGURAR) ((int) setupMode + 1); if (setupMode! =CLOCK) {setupScreen =true; if (setupMode ==HORA_HORA) {lcd.clear (); lcd.setCursor (0,0); lcd.print ("------ SET ------"); lcd.setCursor (0,1); lcd.print ("- HORA y FECHA-"); retraso (2000); lcd.clear (); }} else {lcd.clear (); // Establecer RTC tmElements_t tm; tm.Year =CalendarYrToTm (YY); tm.Month =MM; tm.Day =DD; tm.Hour =H; tm.Minuto =M; tm.Second =0; time_t t =makeTime (tm); // use el valor time_t para asegurarse de que se establece el día de la semana correcto if (rtc.set (t) ==0) {// Success setTime (t); } else {Serial.println ("¡Falló el conjunto de RTC!"); } //rtc.adjust(DateTime(YY, MM, DD, H, M, 0)); // Guarde la fecha y la hora en RTC IC EEPROM.write (EEPROM_AH, AH); // Guarde las horas de alarma en EEPROM EEPROM.write (EEPROM_AM, AM); // Guarde la alarma registrada en EEPROM EEPROM.write (EEPROM_BY + 0, BY>> 8); // Guarde el año de nacimiento en EEPROM EEPROM.write (EEPROM_BY + 1, BY &0xFF); // Guarde el año de nacimiento en EEPROM EEPROM.write (EEPROM_BM, BM); // Guarde el mes de nacimiento en EEPROM EEPROM.write (EEPROM_BD, BD); // Guarde el día de nacimiento en EEPROM lcd.print ("Guardando ...."); retraso (2000); lcd.clear (); setupScreen =falso; setupMode =CLOCK; switchBacklight (verdadero); } retraso (500); }}} // --------------------------------------------- ----- // Leer la hora y la fecha de rtc icvoid getTimeDate () {if (! SetupScreen) {// DateTime now =rtc.now (); time_t t =ahora (); DD =día (t); MM =mes (t); YY =año (t); H =hora (t); M =minuto (t); S =segundo (t); } // Haga algunas correcciones ... sDD =((DD <10)? "0":"") + String (DD); sMM =((MM <10)? "0":"") + Cadena (MM); sYY =Cadena (YY-2000); sH =((H <10)? "0":"") + Cadena (H); sM =((M <10)? "0":"") + Cadena (M); sS =((S <10)? "0":"") + Cadena (S); sBD =((BD <10)? "0":"") + Cadena (BD); sBM =((BM <10)? "0":"") + Cadena (BM); sBY =Cadena (POR); aH =((AH <10)? "0":"") + Cadena (AH); aM =((AM <10)? "0":"") + String (AM);} // ------------------------- ------------------------- // Lea la temperatura y la humedad cada 6 segundos desde el sensor DHTvoid getTempHum () {unsigned long currentMillis =millis (); if (currentMillis - prevDhtMillis> =DHT_UPDATE_INTERVAL) {int chk =DHT.read21 (DHT21); prevDhtMillis =currentMillis; hum =min (redondo (DHT.humedad), 99); temp =min (redondo (temperatura DHT), 99); sTMP =((temp>
 9)? "":"") + String (temp); sHUM =((zumbido> 9)? "":"") + Cadena (zumbido); }} // ---------------------------------------------- ---- // Enciende o apaga backlightvoid switchBacklight (bool on) {#ifdef NO_BACKLIGHT digitalWrite (LIGHT, LOW); backlightOn =verdadero; // Engañar al software para que piense que está encendido aunque no lo esté #else #ifdef BACKLIGHT_ALWAYS_ON digitalWrite (LIGHT, HIGH); backlightOn =verdadero; #else digitalWrite (LIGHT, (on)? HIGH:LOW); backlightOn =encendido; backlightTimeout =milis () + BACKLIGHT_TIMEOUT; #endif #endif} // ------------------------------------------- ------- // Imprimir valores en displayvoid lcdPrint () {switch (currentStyle) {case ESTÁNDAR:lcdStandardLayout (); descanso; case DUAL_THICK:lcdDualThickLayout (); descanso; case DUAL_BEVEL:lcdDualBevelLayout (); descanso; case DUAL_TREK:lcdDualTrekLayout (); descanso; case DUAL_THIN:lcdDualThinLayout (); descanso; CASO PALABRA:lcdWordLayout (); descanso; caso BIO:lcdBioRhythmLayout (); descanso; caso THERMO:lcdThermometerLayout (); descanso; }} // ---------------------------------------------- -- Diseño estándar ---------------------------------------------- ----------------------- void lcdStandardSetup () {} void lcdStandardLayout () {String line1 =sH + ":" + sM + ":" + sS + "| "+ aH +":"+ aM; Cadena line2 =sDD + "/" + sMM + "/" + sYY + "|" + ((alarmON &&(S &0x01))? "ALARM":""); lcd.setCursor (0,0); // Primera fila lcd.print (line1); lcd.setCursor (0,1); // Segunda fila lcd.print (line2); } // Crea un carácter personalizado desde el programa memoryvoid createCharP (ranura de bytes, byte * p) {for (int i =0; i <8; i ++) {customChar [i] =pgm_read_byte (p ++); } lcd.createChar (ranura, customChar);} // ------------------------------------- ----------- Diseño de doble espesor ------------------------------------ --------------------------------- void lcdDualThickSetup () {createCharP (C0, C_0); createCharP (C1, C_1); createCharP (C2, C_2); createCharP (C3, C_3); createCharP (BELL_CHAR, bell);} void lcdDualThickLayout () {# ifdef DUAL_THICK_12HR int h =(H> =12)? H - 12:H; si (h ==0) {h =12; } lcdDualThickPrintNumber (8, M, verdadero); lcdDualThickPrintNumber (0, h, falso); lcd.setCursor (15,0); lcd.print ((H> =12)? "p":"a"); lcd.setCursor (15,1); lcd.print ("m"); #else lcdDualThickPrintNumber (8, M, verdadero); lcdDualThickPrintNumber (0, H, verdadero); alarma bool =(S &0x01); lcdWordShowBell (15, 0, alarma, BELL_CHAR); // bottonm esquina derecha lcdWordShowBell (15, 1,! alarma, BELL_CHAR); // bottonm esquina derecha #endif byte c =(S &1)? C3:32; lcd.setCursor (7,0); lcd.write (c); lcd.setCursor (7,1); lcd.write (c);} // Dibuja un número de 2 líneas // pos - posición x para dibujar el número // número - valor para dibujar // leadZero - si los ceros iniciales deben mostrarse void lcdDualThickPrintNumber (int pos, int number, int leadZero) {int t =número / 10; int u =número% 10; if (t ==0 &&! LeadZero) {t =11; } lcdDualThickPrintDigit (pos, t); lcdDualThickPrintDigit (pos + 4, u);} // Dibuja un dígito de 2 líneas // pos - posición x para dibujar el número // número - valor para dibujar el vacío lcdDualThickPrintDigit (int pos, int número) {for (int y =0; y <2; y ++) {lcd.setCursor (pos, y); para (int x =0; x <3; x ++) {lcd.write (blockChar [número] [y] [x]); }}} // --------------------------------------------- --- Diseño de bisel doble -------------------------------------------- ------------------------- void lcdDualBevelSetup () {createCharP (LT, _LT); createCharP (UB, _UB); createCharP (RT, _RT); createCharP (LL, _LL); createCharP (LB, _LB); createCharP (LR, _LR); createCharP (UMB, _UMB); createCharP (LMB, _LMB);} void lcdDualBevelLayout () {# ifdef DUAL_THICK_12HR int h =(H> =12)? H - 12:H; si (h ==0) {h =12; } lcdDualBevelPrintNumber (8, M, verdadero); lcdDualBevelPrintNumber (0, h, falso); lcd.setCursor (15,0); lcd.print ((H> =12)? "p":"a"); lcd.setCursor (15,1); lcd.print ("m"); #else lcdDualBevelPrintNumber (8, M, verdadero); lcdDualBevelPrintNumber (0, H, verdadero); alarma bool =(S &0x01); lcdWordShowBell (15, 0, alarma, 65); // bottonm esquina derecha lcdWordShowBell (15, 1,! alarma, 65); // bottonm esquina derecha #endif byte c =(S &1)? 58:32; lcd.setCursor (7,0); lcd.write (c); lcd.setCursor (7,1); lcd.write (c);} // Dibuja un número de 2 líneas // pos - posición x para dibujar el número // número - valor para dibujar // leadZero - si los ceros iniciales deben mostrarse void lcdDualBevelPrintNumber (int pos, int number, int leadZero) {int t =número / 10; int u =número% 10; if (t ==0 &&! LeadZero) {t =11; } lcdDualBevelPrintDigit (pos, t); lcdDualBevelPrintDigit (pos + 4, u);} // Dibuja un dígito de 2 líneas // pos - x posición para dibujar el número // número - valor para drawvoid lcdDualBevelPrintDigit (int pos, int número) {for (int y =0; y <2; y ++) {lcd.setCursor (pos, y); para (int x =0; x <3; x ++) {lcd.write (bevelChar [número] [y] [x]); }}} // --------------------------------------------- --- Diseño de Dual Trek -------------------------------------------- ------------------------- void lcdDualTrekSetup () {createCharP (K0, K_0); createCharP (K1, K_1); createCharP(K2, K_2); createCharP(K3, K_3); createCharP(K4, K_4); createCharP(K5, K_5); createCharP(K6, K_6); createCharP(K7, K_7);}void lcdDualTrekLayout(){ lcdDualTrekPrintNumber(10, S, true); lcdDualTrekPrintNumber(5, M, true); lcdDualTrekPrintNumber(0, H, true); byte c =(S &1) ? 165 :32; lcd.setCursor(4,0); lcd.write(c); lcd.setCursor(4,1); lcd.write(c); lcd.setCursor(9,0); lcd.write(c); lcd.setCursor(9,1); lcd.write(c); bool alarm =(S &0x01); lcdWordShowBell(15, 0, alarm, 65); //bottonm right corner lcdWordShowBell(15, 1, !alarm, 65); //bottonm right corner}//Draw a 2 line number// pos - x position to draw number// number - value to draw// leadingZero - whether leading zeros should be displayedvoid lcdDualTrekPrintNumber(int pos, int number, int leadingZero){ int t =number / 10; int u =number % 10; if (t ==0 &&!leadingZero) { t =11; } lcdDualTrekPrintDigit(pos, t); lcdDualTrekPrintDigit(pos + 2, u);}//Draw a 2 line digit// pos - x position to draw number// number - value to drawvoid lcdDualTrekPrintDigit(int pos, int number){ for (int y =0; y <2; y++) { lcd.setCursor(pos, y); for (int x =0; x <2; x++) { lcd.write(trekChar[number][y][x]); } }}//------------------------------------------------ Dual Thin layout ---------------------------------------------------------------------void lcdDualThinSetup(){ createCharP(T0, T_0); createCharP(T1, T_1); createCharP(T2, T_2); createCharP(T3, T_3); createCharP(T4, T_4); createCharP(T5, T_5); createCharP(T6, T_6); createCharP(T7, T_7);}void lcdDualThinLayout(){ #ifdef DUAL_THIN_12HR int h =(H>=12) ? H - 12 :H; if (h ==0) { h =12; } lcdDualThinPrintNumber(6, S, true); lcdDualThinPrintNumber(3, M, true); lcdDualThinPrintNumber(0, h, false); lcd.setCursor(9,0); lcd.print((H>=12) ? "p" :"a"); lcd.setCursor(9,1); lcd.print("m"); #else lcdDualThinPrintNumber(6, S, true); lcdDualThinPrintNumber(3, M, true); lcdDualThinPrintNumber(0, H, true);#endif byte c =(S &1) ? 165 :32; lcd.setCursor(2,0); lcd.write(c); lcd.setCursor(2,1); lcd.write(c); lcd.setCursor(5,0); lcd.write(c); lcd.setCursor(5,1); lcd.write(c); String line1 =aH+":"+aM; String line2 =(alarmON &&(S &0x01)) ? "ALARM" :" "; lcd.setCursor(11,0); //First row lcd.print(line1); lcd.setCursor(11,1); //Second row lcd.print(line2); }//Draw a 2 line number// pos - x position to draw number// number - value to draw// leadingZero - whether leading zeros should be displayedvoid lcdDualThinPrintNumber(int pos, int number, int leadingZero){ int t =number / 10; int u =number % 10; if (t ==0 &&!leadingZero) { t =11; } lcdDualThinPrintDigit(pos, t); lcdDualThinPrintDigit(pos + 1, u);}//Draw a 2 line digit// pos - x position to draw number// number - value to drawvoid lcdDualThinPrintDigit(int pos, int number){ for (int y =0; y <2; y++) { lcd.setCursor(pos, y); lcd.write(thinChar[number][y]); }}//------------------------------------------------ Word layout ---------------------------------------------------------------------void lcdWordSetup(){ createCharP(BELL_CHAR, &bell[0]);}void lcdWordLayout(){ String line1 =numberToWord(H, false); String line2 =numberToWord(M, true); lcd.setCursor (0,0); //First row printClear(line1, 13); lcd.setCursor (0,1); //Second row printClear(line2, 14); if (millis()> frameTimeout) { frameTimeout =millis() + FRAME_TIMEOUT; //lcd.createChar(HOURGLASS_CHAR, &hourglass[nextFrame][0]); createCharP(HOURGLASS_CHAR, &hourglass[nextFrame][0]); nextFrame =(nextFrame + 1) % HOURGLASS_FRAMES; lcd.setCursor(13,0); //First row lcd.write((int)HOURGLASS_CHAR); lcd.print(sS); } bool alarm =(S &0x01); lcdWordShowBell(14, 1, alarm, BELL_CHAR); //Second row lcdWordShowBell(15, 1, !alarm, BELL_CHAR); //Second row}//Display the bell symbol if alarm is on// x - x position (0..15)// y - y position (0..1)// show - true to showvoid lcdWordShowBell(int x, int y, bool show, byte chr) { lcd.setCursor(x,y); lcd.print(" "); if (alarmON &&show) { lcd.setCursor(x,y); lcd.write(chr); }}//Print character string and clear to right// s - String to print...This file has been truncated, please download it to see its full contents.

Piezas y carcasas personalizadas

stl_files_ZuDXHCHZCl.zip

Esquemas

Schematic and PCB in Eagle files eagle_files_ZN59zdeNf5.zip

Proceso de manufactura

  1. Alarma de agua frambuesa pi 2 con t cobbler plus
  2. Panel LCD con Arduino para Flight Simulator
  3. Despertador que realmente te saca de la cama por la mañana
  4. El reloj IV9 Numitron más simple de bricolaje con Arduino
  5. Reloj Arduino con tiempos de oración islámicos
  6. Word Clock con resolución de tiempo mínima en palabras
  7. Arduino Temp. Monitor y reloj en tiempo real con pantalla 3.2
  8. TM1637 Reloj digital con configuración de hora y funcionalidad de alarma
  9. ¡Visualización de una imagen en una pantalla LCD TFT con Arduino UNO!
  10. Pantalla de temperatura OLED de Arduino con reloj en tiempo real
  11. Reloj despertador simple con DS1302 RTC