huborarduino.com

La web de Hubor para la simulación de Arduino con Proteus

Banner Guia Programacion Arduino Con Proteus

[Proteus versión 8.1]

En la lección 16 montamos como práctica un reloj digital. En aquel momento nuestro objetivo era aprender a utilizar un display LCD de texto monocromo y, por esa razón, no nos preocupó realizar una serie de simplificaciones que, en la práctica, hacían que nuestro reloj fuera inservible. De hecho, nuestro reloj era un prodigio de inexactitud y de ineficacia. Inexacto, porque contábamos los segundos mediante la utilización de lapsos de tiempo de inactividad (lo que significa que cada segundo se produce un desfase igual al tiempo que tarda el micro en ejecutar el resto del código de programa). Ineficaz porque teníamos a nuestro microprocesador ocupado la mayor parte del tiempo en un bucle de espera inoperativo.

Lec18 001

En la lección 17 vimos como podíamos utilizar una serie de funciones de tiempo que nos permitían evitar el uso de la función delay() con los problemas que nos acarreaba. En esta lección vamos a construir un reloj un poco más profesional. Utilizaremos un display LCD de dos filas y 40 caracteres. Aprovecharemos para aprender a utilizar un integrado RTC (reloj de tiempo real) que proporcionará a nuestro reloj una adecuada precisión. Incluiremos el uso de las funciones temporales para que los pulsadores de mando estén activos en todo momento. Y veremos la utilización de un función que nos permita detectar el flanco de subida de una señal. Además utilizaremos el bus i2c que vimos en las lecciones 910 y 11. Por supuesto todo ello simulado desde nuestro entorno Proteus.

Nuestro montaje se muestra en las imagénes siguientes. Como es un poco mayor de lo habitual, presentamos una versión global y varios detalles:

Lec18 002

 El detalle del integrado RTC se muestra a continuación:

Lec18 003

El conexionado del display LCD es el siguiente:

Lec18 004

Y, por último, el conjunto de pulsadores de mando, se muestra a continuación:

Lec18 005

El DS3232 es un integrado de la firma Maxim (http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3232.html) que nos proporciona un reloj de gran precisión con corrección de las derivas que se producen por los cambios de temperatura. Se conecta con nuestro ARDUINO utilizando el puerto i2c. Proteus incluye un modelo que nos permite llevar a cabo su simulación. Para ello sólo tenemos que unirlo a nuestro ARDUINO utilizando dos pines (los del puerto i2c). Además, aprovecharemos una ventaja que nos proporciona Proteus. Si modificamos las propiedades del DS3232 podemos indicarle que tome de forma automática la hora de nuestro PC al arrancar la simulación. Así tendremos un reloj en hora sin esfuerzo.

Lec18 006

Una vez que tenemos listo nuestro hardware, podemos pasar a ocuparnos del programa que se ejecutará en nuestro Arduino. Esta vez es un poco más largo de los que habitualmente utilizamos en el curso. Pero es que, a medida que el curso avanza, los programas se hacen más interesantes, más sofisticados y, por lo tanto, más largos. Por ese motivo, lo vamos a analizar por trozos.

En la primera parte (líneas 1 a 25) vamos a enlazar con las dos librerías que vamos a utilizar. Wire.h nos posibilita la utilización del bus i2c y LiquidCrystal.h el uso del display LCD (ya vimos el uso de las dos en lecciones anteriores). Luego definimos unas constantes que utilizaremos a lo largo del programa (la dirección de nuestro integrado DS3232 y los operadores lógicos AND, OR y NOT). A continuación, dos constantes para indicar el tamaño de nuestro display LCD (dos filas y cuarenta columnas). Por último una serie de variables de trabajo, de las cuales sólo destaca la variable del objeto que usamos para controlar nuestro display LCD donde definimos los pines con los que se conecta a nuestro ARDUINO y que vimos con detalle en lecciones anteriores.

Lec18 007

El segundo trozo de nuestro código contiene la función setup() que sirve para inicializar nuestro equipo Arduino. La utilizamos para escribir la primera línea de nuestro display LCD, definir como entradas los pines a los que conectamos los pulsadores de mando e inicializar el puerto serie que utilizamos para el bus i2c. Observe que hemos dejado comentadas una serie de líneas al final en las que se incluye un pequeño trozo de código que sirve para escribir la hora actual en el dispositivo DS3232. Como explicamos antes, Proteus nos facilita esta tarea e inicializa por defecto el dispositivo DS3232 con la hora actual del reloj de nuestro PC por lo que en simulación no es necesaria utilizarla.

Lec18 008

La tercera parte del programa contiene la función loop() que es el código que se ejecuta de forma cíclica en nuestro equipo Arduino.

En la primera parte utilizamos las funciones chkTemp e iniTemp para ejecutar una serie de instrucciones sólamente una vez cada 100ms. De esa forma no tenemos que utilizar el poco práctico delay() y descargamos a nuestro Arduino de la tarea de estar refrescando de forma infructuosa cada ciclo de programa el display. Por otro lado 100ms es tiempo suficiente para que si se usan los pulsadores de mando, la información se refresque en el display cuando el usuario los utilice.

La tarea que se ejecuta cada 100ms es la encargada de refrescar la hora actual en el display LCD utilizando la función auxiliar llamada MostrarHoraEnDisplay() cuyo código veremos más adelante.

El resto de la función es una serie de trozos de código iguales, cada uno de los cuales controla un pulsador y responde aumentando la parte del reloj correspondiente (segundo, minuto, hora, etc) una unidad y controlando los desbordes. Destacamos el uso de la nueva función FlancoSub() cuyo código veremos más adelante. Con ella posibilitamos que cuando el usuario pulse el botón, sólo se incremente una unidad con el flanco de subida. Si no lo hiciéramos así, cada vez que el usuario actúa sobre el pulsador se incrementarían muchas unidades de un golpe. La función flanco de subida puede resultar muy útil en muchos otros proyectos en los que necesitemos utilizar pulsadores.

Lec18 009

Lec18 010

El siguiente trozo de código contiene la función MostrarHoraEnDisplay() que ya dijimos que se ocupa de escribir en el display LCD la hora actual. Recibe como parámetros las unidades que componen nuestro reloj: segundo, minuto, hora, día de la semana, día, mes y año. Formatea de forma adecuada el mensaje para presentarlo en nuestro display.

Lec18 011

Lec18 012

La función LeerHoraDS3232() se encarga de recibir de la información de la hora actual desde el dispositivo DS3232. Puesto que es un dispositivo con el que nos conectamos a través del bus i2c, el flujo de control es muy similar al que ya vimos en lecciones anteriores para leer información procedente de un dispositivo que cumple el estandar de comunicación i2c. Primero hacemos una llamada a su dirección dentro de la red, luego escribimos el comando adecuado para indicarle que queremos que nos devuelva los datos de la hora actual y, por último, leemos los diferentes bytes que nos trasmite. Guardamos cada trozo de informacióin en la variable destinada a tal fin y utilizamos la función bcdToDec(), que veremos con detalle más adelante, para transformarla al formato decimal.

Lec18 013

FijarHoraDS3232() es una función que utilizamos para cambiar la hora guardada en este momento en el dispositivo DS3232. Su funcionamiento es muy similar a la que acabamos de ver, pero en este caso escribimos en lugar de leer los datos.

Lec18 014

Las funciones iniTemp() y chkTemp() ya las vimos en lecciones anteriores. Sirven para arrancar un temporizador de un determinado tiempo de duración y para comprobar si ese tiempo ya se ha cumplido o cuanto queda todavía para hacerlo. Es una técnica muy útil para poder manejar varios temporizadores diferentes en nuestro Arduino basándose en un único reloj maestro (en este caso el que usa la función millis().

Lec18 015

decToBcd() es una función que convierte un número en formato decimal a un número en formato BCD. La función bcdToDec() hace la función inversa. El código BCD ( Binary Coded Decimal) es un código estándar de 6 bits usado por algunos ordenadores para almacenar caracteres alfanuméricos y signos de puntuación. Cada carácter está compuesto por 6 bits (2 carácteres en formato octal). Con estos 6 bits se pueden definir un total de 64 caracteres (2^6). Como el dispositivo DS3232 almacena su información utilizando este formato, estas funciones son útiles para hacer las transformaciones adecuadas al formato decimal que utilizamos en nuestro Arduino.

Lec18 016

En una señal digital, se denomina flanco a la transición del nivel bajo al alto (flanco de subida) o del nivel alto al bajo (flanco de bajada). En este caso, incorporamos la función FlancoSub() que detecta el flanco de subida. De esta forma, nos resulta sencillo determinar el momento en que se actúa sobre el pulsador ignorando el resto del tiempo que dicho botón permanece actuado. Así, permitimos que se incremente una unidad cada vez que se produce una actuación sobre el pulsador. 

Esta función es muy utilizada en dispositivos de mando de máquinas móviles para reducir el riesgo de que una botonera caída en el suelo (con tal mala suerte de que el pulsador de marcha quede pulsado de forma constante) o humedades producidas por condensación en el interior de la botonera, puedan provocar de forma extemporánea arranques no intencionados con riesgo para las personas.

Lec18 017

Una vez desentrañado todo el código, ya sólo resta arrancar la simulación y disfrutar de nuestro reloj.

Lec18 018

Esperamos que les haya resultado interesante la lección de hoy y como siempre terminamos proponiendo una práctica. ¿Se anima el lector a completar el proyecto logrando que nuestro reloj se convierta en un despertador? Para ello es necesario poder fijar una hora con ayuda de los pulsadores y hacer sonar una alarma cuando se cumpla dicha hora.

 

 

Comparte este artículo en redes sociales

Submit to FacebookSubmit to Google PlusSubmit to TwitterSubmit to LinkedIn


Esta página es propiedad de Hubor.

2014.

¡Atención! Este sitio usa cookies y tecnologías similares. Si no cambia la configuración de su navegador, usted acepta su uso. Ampliar información