He hecho un reloj usando un Arduino, pero el tiempo parece ir a la deriva. Soy consciente del problema de reinversión ; el reloj parece moverse unos 15 minutos en el transcurso de una semana.
Estoy usando una PCB personalizada con este resonador de Digi-key. El código lee la función millis () al comienzo de cada ciclo y funciona a partir de ese valor.
Mi pregunta es: ¿cómo puedo medir el tiempo con un Arduino, con la precisión suficiente para hacer un reloj de escritorio aceptable?
millis()
.Respuestas:
Nota: aunque mi respuesta fue aceptada y tiene una puntuación de voto más alta, asegúrese de leer la excelente respuesta de Edgar Bonet sobre cómo hacer que su Arduino mantenga el tiempo sin un RTC.
He tenido bastante éxito en el uso del reloj de tiempo real DS1307. Aquí hay un enlace a su hoja de datos .
A continuación se presentan algunas de sus características:
Utiliza la interfaz IC para la comunicación con Arduino, lo que facilita la programación utilizando las bibliotecas correctas (disponibles en la red).
Está conectado a Arduino a través de los pines SCL y SDA (analógico A4 y A5 respectivamente), por lo que solo usa 2 pines.
Requiere muy pocos componentes externos para funcionar.
Se puede conectar a una batería de celda de moneda para que mantenga el tiempo incluso cuando el Arduino está apagado. En su modo de bajo consumo, la batería de celda de moneda dura años.
Se desplaza muy poco (en mi caso solo se desplaza unos segundos por semana).
No es muy costoso.
Si no tiene la intención de usar un RTC, puede reemplazar el cristal que se usa comúnmente para proporcionar reloj a arduino para un módulo oscilador de cristal como este de Farnel o este otro . Vienen en paquetes de 4 pines como en las imágenes a continuación. Generarán un reloj mucho más preciso para tu arduino.
Ambos módulos mencionados tienen tolerancias de 50 ppm y funcionan a 5V.
Nuevamente, para ser claros, estos módulos osciladores de cristal no deben confundirse con el cristal normal de 2 pines como se muestra a continuación. Esos son parte de los circuitos de relojes externos para MCU, por ejemplo.
fuente
No necesita un RTC para construir un reloj: el chip ATmega tiene todo el hardware necesario para realizar las tareas del RTC. Aquí es cómo:
Obtenga un reloj de cristal de 32768 Hz: cómprelo o desarme un reloj antiguo. Estos cristales, diseñados específicamente para mantener el tiempo, tienen una deriva de temperatura extremadamente pequeña. También necesitarías uno de esos si quisieras usar un chip RTC.
Configure los fusibles de su ATmega para funcionar con el oscilador RC de 8 MHz. Esto hará que su
millis()
función sea terriblemente inexacta, y también liberará los pines XTAL1 y XTAL2.Conecte el cristal de reloj a los pines TOSC1 y TOSC2. Estos son los mismos pines que XTAL1 y XTAL2 (9 y 10 en el 328P). Los diferentes nombres se usan para significar diferentes funciones.
Configure el Temporizador / Contador 2 para operación asíncrona, modo de conteo normal, preescalador configurado en 128 y habilite la interrupción de desbordamiento del temporizador.
Ahora obtendrá una interrupción TIMER2_OVF a una velocidad muy constante de una vez por segundo. Solo necesita avanzar la pantalla del reloj un segundo en el ISR. Entre las interrupciones, puede poner el MCU en modo de suspensión muy profundo (modo de suspensión de ahorro de energía: nada funciona más que Temporizador / Contador 2) y funcionar durante años en un par de celdas AA. A menos que la pantalla tenga mucha energía, obviamente.
Hice exactamente esto para construir mi reloj de pared con una mano las 24 horas . Este enlace apunta ahora a la traducción al inglés de la documentación original en francés.
Calibración de cuarzo
Si no calibra su cuarzo, puede esperar una deriva significativa, generalmente unos segundos por semana . La tasa de deriva depende de la capacitancia parásita de las trazas que conectan el cristal a la MCU. En principio, podría eliminarse agregando un poco de capacitancia extra finamente ajustada. Vale la pena señalar que tendría el mismo problema de deriva con un RTC.
Si está satisfecho con este tipo de precisión, viva con ella y sea feliz. Sin embargo, si desea medir la deriva, notará que es muy estable. Luego puede compensarlo fácilmente en el software y lograr una precisión de unos segundos por año .
El algoritmo para corregir la deriva es muy simple. A partir de la deriva medida, calcula el retraso preciso entre las interrupciones, que debería estar muy cerca de 10 9 nanosegundos, luego:
En el ejemplo anterior, el cuarzo es un poco demasiado rápido, y el software lo compensa con un "tic" cada pocos días. Si el cuarzo fuera demasiado lento, el mismo código haría doble clic una vez cada pocos días.
Este tipo de calibración también podría realizarse para un RTC, pero sería significativamente más complejo porque el RTC informa el tiempo en una forma desglosada que no se presta naturalmente a operaciones aritméticas.
fuente
El resonador que especificó tiene una estabilidad del 0.3%, donde el cristal o el oscilador de cristal (como lo menciona Ricardo) es de 50 ppm. Muchas veces más estable. Sin mencionar que la deriva de la temperatura del resonador es horrible. El calentamiento por la luz solar lo cambiará. Por lo tanto, no debe usarse un resonador para mantener el tiempo durante largos períodos.
Por lo tanto, usar un cristal o un oscilador de cristal obtendrá lo que desea. Ya sea usándolo en el ATmega y configurando los fusibles respectivamente o usándonos uno conectado a un RTC.
fuente
Si no desea utilizar hardware adicional, como un reloj de tiempo real (por ejemplo, DSDS1307), puede mejorar significativamente la precisión de la sincronización desactivando todas las interrupciones no utilizadas. Por defecto, los bocetos de Arduino vienen con varias rutinas de interrupción habilitadas y, a menudo, no se usan para su boceto. La forma más rápida de averiguar si puede prescindir de él para intentar deshabilitarlos emitiendo
noInterrupts();
fuente
millis()
menos que se las arregle para gastar más de un milisegundo a la vez en darles servicio, en cuyo caso tiene otros problemas ... 4. ¡Desactivar las interrupcionesnoInterrupts()
evitarámillis()
perder tiempo!Entiendo que gran parte del espíritu con Arduino es ser frugal y ocasionalmente pasar por un problema. Utilizo Arduino (y ahora chipKIT, ya que tiene 10 veces la RAM y 10 veces la velocidad del reloj) para mi lugar de trabajo y necesito "funciones periféricas" para estar al día y trabajar lo más rápido posible.
Utilizo el reloj de tiempo real sparkfun en uno de mis proyectos y estoy muy contento con él. También tienen una variante "Dead on" .
fuente