Nota: esta publicación se publicó originalmente en el repositorio Github del autor para este proyecto. Como se describe en el artículo práctico adjunto, este proyecto es un reloj digital que utiliza un oscilador de 10 megahercios de alta estabilidad como referencia de sincronización. El oscilador es un oscilador de cristal controlador de horno, u OCXO, una tecnología que ha experimentado mejoras significativas en los últimos años, consumiendo mucha menos energía a un precio mucho más bajo. La plataforma básica aquí es un OCXO combinado con un Arduino Nano. El Nano ofrece mucha más potencia de procesamiento de la necesaria para realizar un reloj simple de horas, minutos y segundos, pero es barato y fácil de usar. Sin embargo, la señal de reloj sin procesar de 10 MHz del OCXO no se puede utilizar para controlar el Nano directamente. El Nano utiliza un resonador cerámico de 16 MHz para el reloj de su sistema y no es fácil cambiar la frecuencia de este, digamos 10 MHz, sin modificaciones significativas en el firmware del Nano porque la señal del reloj de 16 MHZ se utiliza para derivar la señal de sincronización para la conexión USB necesaria para cargar programas en el microcontrolador. Un interruptor físico para cambiar entre 16 MHz y 10 MHz después de cargar el programa era una opción, pero no muy práctica. En cambio, el enfoque fue utilizar interrupciones. Como ocurre con todos los microprocesadores, el Nano admite interrupciones que, cuando se activan, pueden pausar el código del programa que se está ejecutando actualmente, mover los registros de la CPU a una ubicación de memoria, llevar a cabo una rutina de servicio de interrupción y luego devolver el controlador a su funcionamiento normal restaurando el registros. Las interrupciones generalmente pueden activarse mediante un temporizador controlado por un reloj o una entrada en un pin externo dedicado. El Nano incluye tres temporizadores de interrupción, y Timer0 y Timer1 también pueden ser controlados por una fuente de reloj externa a través de los pines T0 y T1. Los temporizadores funcionan cargándose con un número binario, que luego disminuye cada vez que se detecta un pulso en su pin correspondiente. Cuando el temporizador llega a cero, se activa una interrupción. Cambiar el número cargado en el temporizador altera el intervalo entre interrupciones. Timer0 es de 8 bits, mientras que Timer1 es de 16 bits. Sin embargo, todavía no era posible controlar los temporizadores directamente con la señal de 10 MHz del OCXO. Cuando se usa con un reloj externo en T0 o T1, la señal en el pin se muestrea en relación con el reloj del sistema de 16 MHz. Utilizando un factor de muestreo de Nyquist máximo de 2,5, se obtiene una frecuencia de entrada externa máxima realista de 6,4 MHz: se perderán los pulsos entrantes y superiores en el pin. Agregar un contador binario de 4 bits después de la salida del OCXO da como resultado que el contador emita un pulso por cada 16 pulsos que recibe, mientras el contador cuenta de 0000 a 1111. Con el OCXO funcionando a 10 MHZ, la frecuencia de la señal de salida del contador es luego 625 kHz. En consecuencia, hacer que el temporizador cuente regresivamente desde 62500 resultará en una interrupción cada décima de segundo. Luego, los segundos, minutos y horas se actualizan adecuadamente. Componentes Elegí un Arduino Nano como microcontrolador del reloj porque ofrece las mismas capacidades que los controladores Arduino más grandes, pero tiene un factor de forma más compacto y es muy económico. En particular, incluye las interfaces SPI e I2C habituales que facilitan la interfaz con pantallas modernas con sus controladores integrados. El OCXO es un Raltron Electronics OX4120A-D3-5-10.000-3.3. Se podría utilizar cualquier OCXO adecuado, incluso uno con una frecuencia diferente cambiando la relación del divisor. También viene en una configuración de paquete dual en paquete (DIP) estándar de 14 pines, aunque en realidad solo se utilizan 4 pines. El OCXO es una pieza de 3,3 voltios, por lo que un regulador lineal de voltaje de caída baja (LDO) LD1117V33C deriva este voltaje del voltaje del sistema de 5 voltios que proporciona la conexión USB-C utilizada para alimentar el reloj. Un segundo regulador idéntico proporciona 3,3 V a la pantalla. El tipo de regulador no es crítico; se podrían utilizar LDO alternativos o tipos de conmutación. El contador de 4 bits es 74HC191. Aunque el contador se alimenta con el voltaje del sistema de 5 V, su entrada es compatible con el nivel lógico de 3,3 V del OCXO, por lo que no es necesario un cambiador de voltaje. La pantalla se compone de seis Adafruit CharliePlex FeatherWings. Cada CharliePlex consta de una matriz de LED de 7×15 píxeles que se pueden controlar individualmente en modo gráfico o utilizando fuentes integradas en la biblioteca Adafruit_IS31FL3731. Se comunican con ellos a través de una conexión I2C. La dirección de cada CharliePlex se puede configurar en uno de dos valores: de forma predeterminada, 0x74, pero se puede cambiar a 0x77 conectando un enlace con soldadura. Para controlar varias pantallas utilicé una placa de conexión con el chip expansor I2C TCA9548A, que me permite conectar varios CharliePlex y abordar cada uno en un bus I2C separado, evitando colisiones de direcciones. Como interfaz de usuario se utiliza un único codificador rotatorio con un interruptor de presión momentáneo. Esto le da al reloj una sensación minimalista moderna. Por supuesto, se podrían usar interruptores de presión separados con solo cambios mínimos en el hardware y/o software. Todos los componentes utilizados en este proyecto tienen empaques con orificios pasantes para una fácil construcción. Una lista de materiales con números de referencia de productos Digikey está disponible en mi repositorio de Github. Placa de circuito impreso La placa de circuito impreso fue diseñada en KiCad. El diseño de PCB está disponible en el repositorio como archivos KiCad y en formato Gerber para que otros lo fabriquen o modifiquen bajo la licencia creative commons. La placa final no es compleja y está diseñada como una placa de doble cara fácil de soldar. Se puede dividir fácilmente en dos secciones a lo largo de dos cortes, ya sea con una sierra o rayando y rompiendo. Si se dividen en secciones, se proporcionan almohadillas para que los cabezales se puedan soldar para conectar una placa detrás de la otra, creando una forma más compacta adecuada para un reloj de escritorio. De esta forma, la placa “superior” contiene la pantalla y el codificador giratorio, y todo lo demás se encuentra en la placa posterior. El codificador giratorio encaja en el centro del tablero, pero, por supuesto, podría trasladarse a otro lugar y conectarse mediante cables voladores. El prototipo de PCB se encargó a través de JCL en China, pero cualquier fabricante de PCB serviría. La parte inferior de la placa contiene el Arduino, el expansor I2C, el OCXO, la cadena divisoria y los reguladores de voltaje. Los reguladores de voltaje se montan con las pestañas hacia afuera para poder instalar disipadores de calor si es necesario. Esto no se consideró necesario en el prototipo, pero si, por ejemplo, las pantallas funcionan con un brillo general alto, puede ser necesario. Si las placas se montan una detrás de otra, deben colocarse espalda con espalda, de modo que todos los componentes sean accesibles desde la parte posterior del reloj. Esto hará que el reloj sea más fácil de piratear más adelante si es necesario. Hay orificios M3 en el tablero para facilitar el montaje y estos se alinean para las partes superior e inferior del tablero si se montan espalda con espalda. Se pueden instalar espaciadores metálicos para proporcionar el espacio libre y la estabilidad mecánica correctos. También hay dos orificios de montaje encima y debajo del OCXO. Esto es para proporcionar estabilidad mecánica. El OCXO es un componente relativamente pesado y se sujeta a la placa simplemente mediante cuatro pines en un conector DIP. Este también está montado verticalmente, por lo que no es especialmente estable. Se puede pasar un trozo de alambre a través de los dos orificios con los extremos entrelazados para mantener el OCXO en su lugar. También se pueden utilizar bridas para cables o una abrazadera, si está disponible. Hay dos conjuntos de esquemas, PCB y archivos Gerbers. Esto se debe a que los módulos TCA9548A vienen en dos versiones. El de Adafruit tiene un espacio de 0,6 pulgadas entre las filas (la versión “N”) mientras que algunos módulos disponibles en eBay tienen un espacio de 0,7 pulgadas. Verifique cuál está utilizando antes de fabricar los PCB. Software El software también está disponible en mi repositorio de Github. El código fuente se basa solo en dos bibliotecas adicionales, la mencionada Adafruit_IS31FL3731 y la biblioteca Wire común que permite la comunicación en serie, esencial para la conexión I2C a la pantalla. Para controlar las pantallas es necesario programar individualmente cada uno de los 105 LED de cada CharliePlex. Esto se hace utilizando un conjunto de tablas de búsqueda (LUT) que se definen inmediatamente después de que la biblioteca se incluye en el código fuente. Hay una LUT por número. Al observarlos, es obvio qué número está almacenado en cada LUT, y es sencillo reemplazar los LUT con un nuevo conjunto, que represente una fuente diferente. A continuación, el código de configuración verifica que todos los CharliePlex estén funcionando correctamente y, de lo contrario, enviará un mensaje de depuración a cualquier computadora conectada a través de la interfaz serie USB. Next Timer1 está configurado para aceptar pulsos de un reloj externo y realizar una cuenta regresiva desde 62499. Este es 62499 y no 62500 para tener en cuenta el tiempo necesario para restablecer el contador cada vez que llega a cero y desencadena una interrupción del bucle principal del programa. La función principal del bucle principal es llamar a la subrutina que lee el codificador rotatorio. La subrutina del codificador intenta eliminar el rebote del interruptor y también es fácilmente modificable. El bucle principal también actualiza la pantalla, pero sólo cuando el temporizador de interrupción ha establecido un bit de bandera. También hay aquí una variable de brillo que el usuario puede configurar, al igual que la variable para aumentar temporalmente el brillo de un dígito cuando se está configurando. El código para la rutina de servicio de interrupción del Timer1 sigue el bucle principal. Esto se llama diez veces por segundo y se encarga de incrementar los segundos, minutos y horas según sea necesario. Aquí también parpadean un par de LED entre los segundos y los minutos, y otro par de LED entre los minutos y las horas, encendiéndose y apagándose cada medio segundo. Su función podría cambiarse fácilmente si se desea. La subrutina final se encarga de transmitir la actualización a la pantalla a través del chip expansor I2C TCA9548A. Precisión El OX4120A-D3-5-10.000-3.3 utilizado en este proyecto es un OCXO fijo; su frecuencia no se puede ajustar. Otros OCXO permiten realizar ajustes aplicando un voltaje de control a uno de los pines, pero yo opté por el oscilador más simple; se creía que su estabilidad era lo suficientemente alta como para que este proyecto no requiriera ajuste. Para comprobar la precisión del reloj se requiere un reloj de referencia de precisión aún mayor. Lo mejor que tenía el autor en su laboratorio era un contador de frecuencia HP 53150A con su propia referencia OCXO. Fue calibrado por última vez en 2013. Al medir la referencia OCXO, la frecuencia en el contador fluctuó entre 10.000.000 y 9.999.999. Esto sugiere una concordancia, y por tanto una precisión, superior a 1 parte en 10.000.000. Al ser más nuevo, es probable que el OCXO de este reloj sea mejor que el contador HP.

Source link