Reloj analogo con lcd grafico


Traemos un ejercicio en donde uniremos dos practicas pasadas, el uso del display gráfico 5110 y el reloj ds1307, en esta practica aremos un reloj análogo

oscar Escrito por oscar 29 August 2016 5869 2

Traemos una práctica en donde podremos implementar lo que hemos aprendido en ejercicios anteriores con nuestro arduino; vamos a crear un reloj análogo que se muestre en nuestro lcd grafico nokia 5110 que trabajamos en post anteriores, donde se pueden realizar las figuras básicas, mostrar letras y números, además usaremos nuestro reloj de tiempo real el DS1307 en donde podemos obtener la fecha y hora actual.

La idea de este post es poder recrear un reloj análogo en nuestra pantalla, en donde podamos visualizar la hora con las manecillas como si fuese un reloj de pared, así como se muestra en la siguiente imagen.

Ejemplo de lcd y reloj análogo

Cálculos para dibujar las manecillas

Antes de iniciar con el ensamble y la codificación del circuito explicaremos su funcionamiento y de cómo realizaremos los cálculos para mostrar las manecillas y los números a visualizar en nuestra pantalla.

Primero vamos a determinar el tamaño en pixeles de la pantalla y fijarnos de donde están las coordenadas (0,0), para saber dónde inicia nuestro lcd; ahora según la pantalla que hemos seleccionado para nuestro proyecto donde el tamaño es de 84 por 48 px vamos obtener los puntos medios para saber dónde posicionar nuestro reloj.

Lcd nokia 5110 coordenadas

Ahora veamos las dimisiones y los puntos medios, determinaremos el radio máximo en “X” y en “Y” que es el tamaño que va a tener nuestro reloj dentro de muestra pantalla, así como muestra la siguiente imagen.

Lcd nokia 5110 dimensiones

Asi de esta forma tendremos las dimensiones para crear las variables globales en nuestro código.

/*Creamos las variables para el uso del lcd*/
int xmax = 84;    //Tamaño maximo del lcd en x
int ymax = 48;    //Tamaño maximo del lcd en y
int xo = 42;      //Punto medio del eje x
int yo = 24;      //Punto medio del eje y
int radiox = 37;  //Maximo radio en x
int radioy = 21;  //Maximo radio en y

El siguiente paso es determinar los ángulos que se va a mover las manecillas de la hora y de los minutos, para ello usaremos la siguiente imagen como guía

Cálculos de los puntos

Para determinar la distancia en grados de las horas realizamos el siguiente cálculo grados / horas en donde es igual a 360° / 12, lo que da 30°; para determinar los minutos realizamos la misma operación pero con 60 minutos, así 360°/60 donde es igual 6°.

Ahora procedemos a explicar cómo se calculan los puntos para poder dibujar las manecillas del reloj, hay que tener en cuenta que con esta calculo podemos obtener cada uno de los puntos para el circuito; para realizar esta operación matemática usaremos las funciones del trigonométricas del seno y coseno, ya que nos ayudaran a determinar los puntos de una circunferencia.

Observemos la imagen anterior de cálculos de los puntos para el numero uno; primero obtenemos el ángulo, a este valor lo convertimos en radianes para las funciones trigonométricas, determinamos el seno del ángulo en radianes, luego multiplicamos el valor que obtenemos por el máximo radio en X y luego le sumamos el valor de x0 que es la media de la pantalla, en donde el resultado es la distancia en X para el número uno, para el eje de Y usamos el mismo paso como observamos en la imagen

Procedemos a realizar el cálculo para los 12 horas de la misma forma en donde obtendremos como resultado la siguiente tabla.

Número Angulo Radianes SIN COS X Y
1 2670 46,60 0,34 -0,93 54px 4px
2 2640 46,07 -0,87 -0,48 9px 13px
3 2610 45,55 -0,61 0,78 19px 40px
4 2580 45,02 0,68 0,73 67px 39px
5 2550 44,5 0,82 -0,56 72px/ 12px
6 2520 43,98 -0,42 -0,9 26px 5px
7 2490 43,45 -0,95 0,28 6px 29px
8 2460 42,93 0,13 0,99 46px 44px
9 2430 42,41 0,99 0,02 78px 24px
10 2400 41,88 0,17 -0,98 48px 3px
11 2370 41,36 -0,94 -0,32 7px 17px
12 2340 40,84 -0,46 0,88 24px 42px

Materiales

En la siguiente tabla podemos ver los materiales que empleamos para el circuito.

Componente Cantidad Descripción
Lcd nokia 5110 1 Pantalla lcd grafica de 84x48 px.
Arduino 1 Puedes usar el arduino que prefieras.
Reloj ds1307 1 Reloj de tiempo real.
Potenciómetro 1 Usado para regular el brillo de la pantalla.

Construcción del circuito

Para la construcción del circuito nos vamos a mirar con los post que tenemos sobre conexión de reloj ds1307 que explica cómo hacer la conexión de nuestro reloj y de conectar lcd nokia5110 a arduino, allí explico las conexiones y el código necesario.

Circuito lcd nokia5110 reloj

Código

El código se encuentra en nuestro repositorio de github.

/**Reloj Analogo Lcd Arduinos
*
* Copyright: codigoelectronica.com
* Author: Oscar Fernandez @oscar_fedezal
* License: MIT
*/

//Incluimos las librerías necesarias
#include <LCD5110_Graph.h>
#include <SPI.h>
#include <math.h> 
#include <Wire.h>
#include <RTClib.h>

//Declaramos la variable global del lcd y con los pines que usaremos
LCD5110 myGLCD(8,9,10,11,12);

//Cargamos las fuentes externas
extern unsigned char SmallFont[];
extern unsigned char TinyFont[];

//Declaramos la variable global de nuestro reloj ds1307
RTC_DS1307 rtc;

/*Creamos las variables para el uso del lcd*/
int xmax = 84;    //Tamaño maximo del lcd en x
int ymax = 48;    //Tamaño maximo del lcd en y
int xo = 42;      //Punto medio del eje x
int yo = 24;      //Punto medio del eje y
int radiox = 37;  //Maximo radio en x
int radioy = 21;  //Maximo radio en y



void setup()
{
  //Iniciamos nuesto lcd
  myGLCD.InitLCD();
  
  //Iniciamos nuestro reloj
  Wire.begin();
  rtc.begin();
  
  //Imprimimos un mensaje de bienvenida
  myGLCD.clrScr();
  myGLCD.setFont(SmallFont);
  myGLCD.print("Reloj Analogo", CENTER, 0);
  myGLCD.print("con arduino y", CENTER, 20);
  myGLCD.print("lcd nokia5110", CENTER, 40);
  myGLCD.update();
  
  delay(3000);
  myGLCD.clrScr();
  
  //Colocamos los números 
  myGLCD.setFont(TinyFont);
  for(int countHour = 1 ; countHour <= 12 ; countHour++ ){
    int ang = (90 - countHour) * 30;
    float radianes = ConvertGradeToRadianes(ang);
    int x = radiox  * sin(radianes);
    int y = radioy * cos(radianes);
    x = x + xo;
    y = y + yo;
    myGLCD.print(String(countHour), x, y-2);
    myGLCD.update();
  }
}


void loop()
{
  //Leemos la hora en nuestro reloj
  DateTime now = rtc.now();
  //Realizamos el calculo para convertir la hora en formato 12 horas
  int numberHour = 0;
  if(now.hour() > 12){
    numberHour = now.hour() - 12;
  }else{
    numberHour = now.hour();
  }
  
  //Con los valores de la hora, mostramos las manecillas
  HandHour(numberHour, 0);
  HandMinute(now.minute(), 0);
  delay(1000);  
  HandHour(numberHour, 1);
  HandMinute(now.minute(), 1);
  delay(1000);
}

/**
 * Con la funcion HandHour podemos pintar la manecilla de la
 * hora en la pantalla
 * 
 * numberHour int Número del reloj de 1 a 12
 * delete int Eliminar la manecilla 0 pata mostrar 1 para eliminar
 */
void HandHour(int numberHour, int deletee){
  //Distancia entre numeros en grados 
  // grados/horas = distancia donde 360/12 = 30
  int ang = (90 - numberHour) * 30;
  float radianes = ConvertGradeToRadianes(ang);
  int x = (radiox / 2.2) * sin(radianes);
  int y = (radioy / 2.2) * cos(radianes);
  x = x + xo;
  y = y + yo;
  if(deletee == 1){
    myGLCD.clrLine(xo, yo, x, y);
  }else{
    myGLCD.drawLine(xo, yo, x, y);    
  }
  myGLCD.update();
}

/**
 * Con la funcion HandMinute podemos pintar la manecilla del
 * minuto en la pantalla
 * 
 * numberMinute int Número del reloj de 1 a 12
 * delete int Eliminar la manecilla, 0 pata mostrar 1 para eliminar
 */
void HandMinute(int numberMinute, int deletee){
  //Distancia entre numeros en grados 
  // grados/minuto = distancia donde 360/60 = 6
  int ang = (90 - numberMinute) * 6;
  float radianes = ConvertGradeToRadianes(ang);
  int x = (radiox / 1.2) * sin(radianes);
  int y = (radioy / 1.2) * cos(radianes);
  x = x + xo;
  y = y + yo;
  if(deletee == 1){
    myGLCD.clrLine(xo, yo, x, y);
  }else{
    myGLCD.drawLine(xo, yo, x, y);    
  }
  myGLCD.update();
}

/**
 * La funcion ConvertGradeToRadianes donde permite convertir 
 * los grados en radianes
 * 
 * grade int Grados
 */
float ConvertGradeToRadianes(int grade){
  float radianes = 0;
  radianes = (grade * 3.1416) / 180; 
  return radianes;
}

Observemos el funcionamiento de nuestro programa en donde cargamos las librerías necesarias para que el lcd y el reloj de tiempo real puedan funcionar de forma correcta, ahora si observamos creamos las variables globales que son las dimensiones de nuestro lcd, los máximos y mínimos, luego en nuestro setup iniciamos el nuestros componentes y lo primero que hacemos es dibujar los números de 1 al 12 que van a indicar las horas en un círculo.

En nuestro loop realizamos el llamado de la hora al reloj y por medio de las funciones HandMinute() y HandHour(), le pasamos los valores correspondientes para que pueda dibujar las manecillas en la pantalla; estas funciones contiene la estructura de los cálculos que explicado más arriba para poder determinar los puntos y poder trazar una línea en ellos.

Funcionamiento del proyecto

Observemos el siguiente gif en donde se muestra el funcionamiento de nuestro circuito, que básicamente está mostrando la hora y minutos. Para los segundos lo que se hacer es parpadear las manecillas

Ejemplo de reloj análogo con lcd gráfico

Si te gusto este ejercicio que realizamos cometa y comparte con tus amigos, además síguenos en nuestras redes sociales para que estés enterado de los proyectos que tenemos.


Comentario

Debe aceptar antes de enviar
gnanni
gnanni

22 May 2019 13:24

On the one hand you say that we fix the connections in a previous article, where they connect to pins 3,4,5,6,7, and for the clock the pins 8,9,10,11,12 are used, with the latter It did not work for me
oscar
oscar

23 May 2019 12:31

Cuando realice el proyecto del "Reloj análogo con lcd gráfico", trabaje con la librería del lcd gráfico "LCD5110_Graph.h", los cuales usa los pines 8,9,10,11,12; pero el post que actualice en donde explico como conectar el lcd usa la librería "Adafruit_GFX.h" la cual usa los pines 7, 6, 5, 4, 3. El cambio de librería no deberá afectar ya que en la función HandHour hacemos uso de la instrucción clrLine para dibujar la linea, con la nueva librería debe ser igual, se usa la instrucción drawRect. Voy a dejar los post donde esta la conexión con la librería Adafruit_GFX