ESP32: Reloj / Cronómetro

Construcción de un Reloj/Cronómeto de precisión, controlado con un módulo ESP32. Este cronómetro dispone de un pulsador, permitiendo su manejo en modo local y también a distancia. Para el control remoto se puede utilizar cualquier teléfono móvil o PC, que esté conectado a la misma red local que el módulo ESP32.

Hasta ahora, todos los relojes que he construido con el ESP32 necesitaban un acceso a Internet vía Wi-Fi para funcionar. En este caso, cuando el reloj funcione en modo cronómetro no será imprescindible disponer del acceso Wi-Fi. A través de su pulsador se pueden controlar todas las funciones del cronómetro,  y lo único que se perdería sin el acceso a Wi-Fi es el control remoto.

Reloj Pac-Man con ESP32 & UTF-8

Crono_ESP32.ino

Al principio del fichero Crono_ESP32.ino están los comentarios, indicando algunos link de compra de los módulos y descarga de librerías

hw_timer_t >>> Es la variable del ‘timer’ que se utiliza para crear las interrupciones de 100 mSeg del cronómetro

has_expired >>> Es la variable booleana que gestionará el ‘void loop’ para incrementar con precisión los 100mSeg. del cronómetro cuando esté en marcha.

Mode_CRONO >>> Es la variable booleana necesaria para gestionar si está funcionando como reloj o cronómetro.

pinPulsa >>> Define el pin GPIO donde está conectado el pulsador del cronómetro.

WifiManager.h >>> Es la librería necesaria para configurar le red WiFi a la que irá conectado el módulo ESP32.

Void IRAM_ATTR >>> Es la rutina de la interrupción, que se ejecutará siguiendo con precisión un intervalo de tiempo. Cada 100mSeg. se pondrá en alto la variable booleana: has_expired

void setup()

Se inicializa el puerto serie y se carga la configuración del reloj, almacenada en la memoria EEPROM del módulo ESP32.

Se configura el LED azul del módulo ESP32 como salida, para indicar de forma visual los incrementos y estado del cronómetro. También se configura el pin al que va conectado el pulsador como entrada en modo Pull-Up.

timer = timerBegin(0, 80, true) >>> Como el cristal de cuarzo del ESP32 es de 80 MHz, dividimos entre 80 para tener como referencia 1MHz, para que el Timer 0 se desborde cada microsegundo.

timerAttachInterrupt(timer, &timerInterrupcion, true) >>> Aquí activamos la interrupción del timer, y hacemos la llamada a la rutina: void IRAM_ATTR timerInterrupcion() 

timerAlarmWrite(timer, 100000, true) >>> Aquí activamos el disparo del timer cada 100.000 uSeg. = cada décima de segundo se producirá la ejecución de la rutina: void IRAM_ATTR timerInterrupcion() 

timerAlarmEnable(timer) >>> Se habilita la alarma del timer.

Librerías personalizadas

En la misma carpeta del proyecto se incluyen dos librerías, personalizadas para este Reloj/Cronómetro:

fonts_es.h >>> Contiene las dos fuentes de caracteres que utiliza el reloj, incluyendo los caracteres especiales que se utilizan en español, como son las letras acentuadas, Ç y Ñ; tanto en minúsculas como en mayúsculas .

max7219.h >>> Contiene las rutinas necesarias para mostrar y animar los caracteres en las 4 matrices LED, gestionadas en serie con sus respectivos circuitos integrados MAX7219.  Es importante indicar en esta librería la posición en las que van montadas las matrices LED sobre el circuito impreso… en este caso van rotadas 90º.

https://github.com/J-RPM/ESP32_Crono/

ESQUEMA

En el esquema se muestran con las conexiones que tenemos que hacer entre el módulo ESP32 y el PCB que contiene las 4 matrices LED. Son las mismas conexiones que tenía el anterior firmware del reloj, lo único nuevo son los dos hilos de conexión del pulsador con el módulo ESP32.

Caja 3D

Para hacer la carcasa del Reloj/Cronómetro utilicé el mismo diseño 3D que hice para el reloj, sin diseñar el tamaño y posición del agujero del pulsador. Así es posible mecanizar la caja a gusto de cada uno, para utilizar cualquier modelo de pulsador, eligiendo su posición… o mecanizar un paso de cable en la caja para colocar un pulsador en el exterior.

Caja 3D, para el PCB de 8 dígitos LED de 7 segmentos

https://www.thingiverse.com/thing:4655690

¿Necesitas fabricar un circuito impreso?

Actualmente hay muchas empresas que se dedican a fabricar circuitos impresos (PCB), pero no en todas podemos conseguir pequeñas tiradas a buen precio. Por suerte, ahora disponemos de Internet y es mucho más fácil que antes. Podemos buscar empresas en cualquier parte del mundo, y es más fácil encontrar un fabricante que haga nuestros prototipos (PCB) a buen precio. Una de las empresas más grandes del sector es PCBWay.

 https://www.pcbway.es/

Logo: PCBWay

¿Programar con interrupciones?

Elegir el modo de programar un microprocesador: consultando de forma cíclica el estado de cada periférico (Polling), o creando una interrupción por cada periférico a controlar. Métodos a seguir para programar el microprocesador AT89S52 con 2 interrupciones y una consulta cíclica. Posibles efectos indeseados cuando se programa con interrupciones.

Interrupciones AT89S52

Cuando se programa un microprocesador con la finalidad de tomar decisiones, dependiendo del estado de alguno o varios dispositivos periféricos, como podrían ser: pulsadores, un reloj en tiempo real (RTC), termómetros, alarmas, etc… existen dos formas posibles de hacerlo:

-> La forma más sencilla y clásica sería consultar de forma cíclica el estado de cada periférico.

-> Lo ideal sería habilitar una interrupción en el procesador por cada periférico a controlar.

Consulta secuencial y periódica

En este proceso de consulta, también conocido como polling en inglés, es el propio procesador el que determina el momento en el que realiza la consulta.

Consulta secuencial

Este método tiene el inconveniente de ser poco eficiente, porque el procesador consume muchos recursos realizando las instrucciones de sondeo… y además en algunas aplicaciones, una pequeña demora de tiempo afecta a la precisión de la medida o produce efectos indeseados. Por ejemplo, un error en la precisión cuando se utiliza un temporizador del procesador como patrón de tiempo de un reloj o cronómetro. Efectos indeseados, como podrían ser parpadeos, cuando se genera una señal PWM para el control de brillo de un display… o inestabilidad  si se utiliza esta misma señal PWM para  regular la velocidad de un motor.

Programar con interrupciones

Una interrupción sirve para detectar en tiempo real el momento en el que se debe realizar la consulta a cada periférico. Con la interrupción, es el periférico quien se encarga de avisar al procesador, y mientras tanto el procesador puede realizar otras tareas.

Habilitación de las interrupciones

El orden de prioridad de todas las interrupciones se pueden programar en el procesador. Así el procesador decidirá si un proceso se debe interrumpir o no, en caso de que se produzca una interrupción mientras se está atendiendo a otra, o cuando se produzcan dos o más interrupciones de forma simultánea. Un mal uso de la prioridad en las interrupciones, también podría provocar efectos indeseados.

Prioridad de las interrupciones

En la imagen anterior, al no tener la prioridad de interrupción el Timer que genera la señal PWM, se producen fluctuaciones en el ancho de impulso generado.