1 Segundo
Arduino ATMEGA328
Después de haber realizado el Generador de DCF77 con el Arduino, me dí cuenta que algunos relojes no sincronizaba bien.
El caso es que debía tener una base de tiempos muy precisa, y con la función de delay() no servía.
Pensando y mirando montajes anteriores míos, encontré entre mis montajes uno que utilizaba interrupciones internas mediante contadores.
Para este montaje se utilizan los contadores de 16bits, en modo CTC
19.9.2 -Modo de borrado del temporizador en comparación (CTC)
En los modos de borrado del temporizador en comparación (CTC) (modo 4 o 12, WGMn[3:0]=0x4 o 0xC), los registros OCRnA o ICRn se utilizan para manipular la resolución del contador: el contador se pone a CERO cuando el valor del contador (TCNTn) coincide con el OCRnA (si WGMn[3:0]=0x4) o el ICRn (WGMn[3:0]=0xC). El OCRnA o el ICRn definen el valor superior del contador, por lo tanto también su resolución. Este modo permite un mayor control de la frecuencia de salida de comparación. Simplifica la operación de conteo de eventos externos.
El valor del contador (TCNTn) aumenta hasta que se produce una comparación con OCRnA o ICRn, y luego se borra el TCNTn.
ISR(TIMER1_COMPA_vect) { if(playRun==true) rutina100(); } setup() { ............. ............. // Interrupciones cada 0,1 Segundos cli(); TCCR1A=0; TCCR1B=0; #if MODO_SEG == 0 // 0=999.762.128 nS 1=999.762.876 OCR1A=1562; TCCR1B |= (1<<WGM12); // 0 1 0 0 CTC OCR1A Immediate MAX TCCR1B |= (1<<CS10); // clk I/O /1024 (From prescaler) TCCR1B |= (1<<CS12); #endif #if MODO_SEG == 1 // 1=1.000.081.262 nS 0=1.000.0828 OCR1A=6253; //6252 DIV-256 TCCR1B |= (1<<WGM12); // 0 1 0 0 CTC OCR1A Immediate MAX TCCR1B |= (1<<CS12); // clk I/O /256 (From prescaler) #endif #if MODO_SEG == 2 // DIV-64 OCR1A=25031; // 25020 1.000.282.772 nS // 25015 1.000.082.800 nS // 25013 DIV-64 1.000.003.00 nS // 25013 DEDO 1.000.241.871 // DEDO 1.000.121.011 // 25013 otro reloj 999.289.372 nS // 25032 otro reloj 1.000.052.634 nS // 25031 otro reloj 1.000.012.119 nS TCCR1B |= (1<<WGM12); // 0 1 0 0 CTC OCR1A Immediate MAX TCCR1B |= (1<<CS10); // clk I/O /64 (From prescaler) TCCR1B |= (1<<CS11); #endif TIMSK1=(1<<OCIE1A); // Timer/Counter1, Output Compare A Match Interrupt Enable sei(); } |
En el código se crea un a interrupción cada 0.1 Segundos.
Con un contador hasta 10, se crea un incremento de 1 Segundo.
Al utilizar los prescaler de /1024, /265, /64 , podemos aumentar la resolución.
La mejor resolución la conseguimos al utilizar la división 64 , o eso debería ocurrir.
DIV 1024 | 16000000/1024=15625/10=1562 | 999.762.128 nS |
DIV 256 | 16000000/256=62500/10=6250 | 1.000.081.262 |
DIV 64 | 16000000/64=250000/10=25000 | 25020 1.000.282.772
nS 25015 1.000.082.800 nS 25013 1.000.003.000 nS 25013 1.000.241.871 ns DEDO 25013 1.000.121.011 ns DEDO2 25013 999.289.372 nS otro reloj 25032 1.000.052.634 nS otro reloj 25031 1.000.012.119 nS otro reloj |
Todos los tiempos de este montaje dependen de la precisión del cristal de cuarzo a 16 MHz.
Es claro que para el circuito del Arduino nano, no creo que empleen un cristal demasiado exacto.
Entre dos Arduinos nano existe una variación de 14 microsegundos.
Con el mismo módulo nano, si colocamos el dedo sobre el cristal de cuarzo, la variación llega alcanzar 118 microsegundos.
Esto puede ser debido al aumento de temperatura y a la variación de capacidad que induce el dedo.
Vamos a realizar unos cálculos sobre la variación de tiempo en un reloj después de 3 meses, en el caso de 1.000.003.000 nS.
1 Segundo ->3 microSegundos
1h -> 10800 uS
1 dia ->259200 uS (0.259 S.)
3 meses->23 Segundos
Conclusión:
Se puede y no se puede utilizar el ATMEGA328 como base de tiempos de un reloj.
Lo primero que debemos hacer es ajustar el temporizador para cada circuito nano, y obtener la la mejor precisión, o tener un cristal de 16MHz muy preciso.
También tenemos que tener cuidado la temperatura del entorno del Arduino nano.
Para las medidas he utilizado un analizador de señal Saleae Logic , y no estoy seguro de su precisión, creo que es alta.
Programa Arduino
Espero que os haya gustado este pequeño análisis.
Saludos.
Juan Galaz