Vamos a programar #76 - Neo Clock View.

Hola de nuevo a todos, el día de hoy vamos a ver un poco de algo a lo que decidí llamar "Neo Clock View". Para fabricarlo vamos a hacer uso de los displays de siete segmentos que vimos en el post anterior.

En la versiones anteriores de Clock View, usamos el módulo DS1302. En esta ocasión haremos uso del modulo DS1307 y haremos una versión solo para probar si los "displays" funcionan cómo esperamos.

Antes de comenzar, deberás de instalar la librería para poder usar el modulo de reloj de forma sencilla. La puedes descargar del GitHub del dueño.

Una vez instalada, vamos a realizar las conexiones. Para esto simplemente conectamos de la siguiente manera.

  • SDA - Al pin A4 del arduino.
  • SCL - Al pin A5 del arduino.
  • VCC - A 5v del arduino.
  • GND - A GND del arduino.
Con las conexiones hechas ahora revisemos el código.

//Reloj
// A4 - SDA
// A5 - SCL
#include <FastLED.h>
#define NUM_LEDS 126
#define DATA_PIN 9
#include <Wire.h>
#include <TimeLib.h>
#include <DS1307RTC.h>

CRGB leds[NUM_LEDS];
int XC = 0;

void setup() {
	// Serial.begin(9600);
	// while (!Serial) ;
	// delay(200);
	LEDS.addLeds<WS2812,DATA_PIN,RGB>(leds,NUM_LEDS);
	LEDS.setBrightness(10);
}

void PrintNumber(int Value, int Digit, int Green, int Red, int Blue){
	for(int i = 0; i < 7; i++) {
		switch (Value)
		{
			case 0:
				if (i == 6){
					leds[(i * 3) + 2 + (Digit * 21)].setRGB(0, 0, 0);
					leds[(i * 3) + 1 + (Digit * 21)].setRGB(0, 0, 0);
					leds[i * 3 + (Digit * 21)].setRGB(0, 0, 0);
				}else{
					leds[(i * 3) + 2 + (Digit * 21)].setRGB(Green, Red,Blue);
					leds[(i*3) + 1 + (Digit * 21)].setRGB(Green, Red,Blue);
					leds[i*3+ (Digit * 21)].setRGB(Green, Red,Blue);		
				}
				FastLED.show(); 
				break;
			case 1:
				if (i == 0 || i == 1){
					leds[(i * 3) + 2 + (Digit * 21)].setRGB(Green, Red,Blue);
					leds[(i * 3) + 1 + (Digit * 21)].setRGB(Green, Red,Blue);
					leds[i * 3 + (Digit * 21)].setRGB(Green, Red,Blue);			
				}else{
					leds[(i * 3) + 2 + (Digit * 21)].setRGB(0,0,0);
					leds[(i*3) + 1 + (Digit * 21)].setRGB(0,0,0);
					leds[i * 3 + (Digit * 21)].setRGB(0,0,0);
				}
			FastLED.show();
			break;
			case 2:
				if (i == 0 || i == 3){
					leds[(i * 3) + 2 + (Digit * 21)].setRGB(0,0,0);
					leds[(i * 3) + 1 + (Digit * 21)].setRGB(0,0,0);
					leds[i * 3 + (Digit * 21)].setRGB(0,0,0);
				}else{
					leds[(i * 3) + 2 + (Digit * 21)].setRGB(Green, Red,Blue);
					leds[(i * 3) + 1 + (Digit * 21)].setRGB(Green, Red,Blue);
					leds[i * 3 + (Digit * 21)].setRGB(Green, Red,Blue);
				}
			FastLED.show();
			break;
			case 3:
				if (i == 3 || i == 4){
					leds[(i * 3) + 2 + (Digit * 21)].setRGB(0,0,0);
					leds[(i * 3) + 1 + (Digit * 21)].setRGB(0,0,0);
					leds[i * 3 + (Digit * 21)].setRGB(0,0,0);
				}else{
					leds[(i * 3) + 2 + (Digit * 21)].setRGB(Green, Red,Blue);
					leds[(i * 3) + 1 + (Digit * 21)].setRGB(Green, Red,Blue);
					leds[i * 3 + (Digit * 21)].setRGB(Green, Red,Blue);
				}
			FastLED.show();
			break;
			case 4:		
				if (i == 2 || i == 4 || i == 5){
					leds[(i * 3) + 2 + (Digit * 21)].setRGB(0,0,0);
					leds[(i * 3) + 1 + (Digit * 21)].setRGB(0,0,0);
					leds[i * 3 + (Digit * 21)].setRGB(0,0,0);
				}else{
					leds[(i * 3) + 2 + (Digit * 21)].setRGB(Green, Red,Blue);
					leds[(i * 3) + 1 + (Digit * 21)].setRGB(Green, Red,Blue);
					leds[i * 3 + (Digit * 21)].setRGB(Green, Red,Blue);
				}
			FastLED.show();
			break;
			case 5:
				if (i == 1 || i == 4){
					leds[(i * 3) + 2 + (Digit * 21)].setRGB(0,0,0);
					leds[(i * 3) + 1 + (Digit * 21)].setRGB(0,0,0);
					leds[i * 3 + (Digit * 21)].setRGB(0,0,0);
				}else{
					leds[(i * 3) + 2 + (Digit * 21)].setRGB(Green, Red,Blue);
					leds[(i * 3) + 1 + (Digit * 21)].setRGB(Green, Red,Blue);
					leds[i * 3 + (Digit * 21)].setRGB(Green, Red,Blue);
				}
			FastLED.show();
			break;
			case 6:
				if (i == 1){
					leds[(i * 3) + 2 + (Digit * 21)].setRGB(0,0,0);
					leds[(i * 3) + 1 + (Digit * 21)].setRGB(0,0,0);
					leds[i * 3 + (Digit * 21)].setRGB(0,0,0);
				}else{
					leds[(i * 3) + 2 + (Digit * 21)].setRGB(Green, Red,Blue);
					leds[(i * 3) + 1 + (Digit * 21)].setRGB(Green, Red,Blue);
					leds[i * 3 + (Digit * 21)].setRGB(Green, Red,Blue);
				}
			FastLED.show();
			break;
			case 7:
				if (i == 3 || i == 6 || i == 4 || i == 5){
					leds[(i * 3) + 2 + (Digit * 21)].setRGB(0,0,0);
					leds[(i * 3) + 1 + (Digit * 21)].setRGB(0,0,0);
					leds[i * 3 + (Digit * 21)].setRGB(0,0,0);
				}else{
					leds[(i * 3)+ 2 + (Digit * 21)].setRGB(Green, Red,Blue);
					leds[(i * 3)+ 1 + (Digit * 21)].setRGB(Green, Red,Blue);
					leds[i * 3 + (Digit * 21)].setRGB(Green, Red,Blue);
				}
			FastLED.show();
			break;
			case 8:
				leds[(i * 3) + 2 + (Digit * 21)].setRGB(Green, Red,Blue);
				leds[(i * 3) + 1 + (Digit * 21)].setRGB(Green, Red,Blue);
				leds[i * 3 + (Digit * 21)].setRGB(Green, Red,Blue);
			FastLED.show();
			break;
			case 9:
				if (i == 4){
					leds[(i * 3) + 2 + (Digit * 21)].setRGB(0,0,0);
					leds[(i * 3) + 1 + (Digit * 21)].setRGB(0,0,0);
					leds[i * 3 + (Digit * 21)].setRGB(0,0,0);
				}else{
					leds[(i * 3) + 2 + (Digit * 21)].setRGB(Green, Red,Blue);
					leds[(i * 3) + 1 + (Digit * 21)].setRGB(Green, Red,Blue);
					leds[i * 3 + (Digit * 21)].setRGB(Green, Red,Blue);
				}
			FastLED.show();
			break;
			default:		
				if (i == 0 || i == 1){
					leds[(i * 3) + 2 + (Digit * 21)].setRGB(0,0,0);
					leds[(i * 3) + 1 + (Digit * 21)].setRGB(0,0,0);
					leds[i * 3 + (Digit * 21)].setRGB(0,0,0);
				}else{
					leds[(i * 3) + 2 + (Digit * 21)].setRGB(Green, Red,Blue);
					leds[(i * 3) + 1 + (Digit * 21)].setRGB(Green, Red,Blue);
					leds[i * 3 + (Digit * 21)].setRGB(Green, Red,Blue);
				}
			FastLED.show();
			break;
		}
	}
}

void ShowIntro(){
	for(int i = 0; i < NUM_LEDS; i++) {
		leds[i] = CHSV(255, 255, 255);
		FastLED.show(); 
		delay(5);
	}
	Intro = false;
}

void PrintTime(int Hour, int Minutes, int Seconds){
	if(Seconds < 10){
		PrintNumber(Seconds,0,255,0,0);
		PrintNumber(0,1,255,0,0);
	}else{
		PrintNumber(Seconds % 10, 0, 255, 0, 0);
		PrintNumber(Seconds / 10, 1, 255, 0, 0);
	}
	
	if(Minutes < 10){
		PrintNumber(Minutes,2,0,255,0);
		PrintNumber(0,3,0,255,0);
	}else{
		PrintNumber(Minutes % 10, 2, 0, 255, 0);
		PrintNumber(Minutes / 10, 3,0 , 255, 0);
	}
	
	if(Hour < 10){
		PrintNumber(Hour,4,0,0,255);
		PrintNumber(0,5,255,0,0);
	}else{
		PrintNumber(Hour % 10, 4, 0, 0,255);
		PrintNumber(Hour / 10, 5, 0, 0,255);
	}
}

tmElements_t tm;
bool Intro = true;

void loop() {
	
	if (Intro == true) ShowIntro();

	if (RTC.read(tm)) {
		PrintTime(tm.Hour,tm.Minute,tm.Second);
	} else {
		if (RTC.chipPresent()) {
			PrintTime(1025,1024,1023);
			// Serial.println("The DS1307 is stopped.  Please run the SetTime");
			// Serial.println("example to initialize the time and begin running.");
			// Serial.println();
		} else {
			// Serial.println("DS1307 read error!  Please check the circuitry.");
			// Serial.println();
		}
		delay(9000);
	}
	delay(100);
}

El código consta de tres funciones. La primera de ellas en orden de aparicion es "PrintNumber", hay que recordar que diseñamos los segmentos de forma tal; que cada tres LED's representan un segmento. La función recibe cinco parámetros. El primero es el valor que el digito tendrá y técnicamente puede ser cualquier valor (dentro del tipo "integer"), pero debido a que solo podemos mostrar valores dentro del rango 0 ~ 9, deberíamos pasar valores que no excedan nueve. El siguiente parámetro debe de ser un valor que nos indicara que digito es el que queremos usar, dado que empezamos de derecha a izquierda, si decimos que queremos usar el digito uno, estaríamos usando el del lado derecho.
Los ultimos tres parametrosn, son los valores que se usaran para cada color empezando por el rojo, luego el verde y finalmente el azul. El valor para cada uno de estos deberá de estar entre los valores 0 ~ 255, y mezclandolos, podemos crear cualquier color.

la siguiente función es "ShowIntro()", esta función sirve para hacer una animación que recorrerá cada un de los LED de inicio a fin, solo se hará una vez y sirve para demostrar de que otra forma se pueden controlar los LED's.

La siguiente función es "PrintTime()". Recibe tres parámetros del tipo "int", el primero es el valor que representan las horas, el segundo es un valor que representa a los minutos y finalmente el tercero es un valor que representa a los segundos. dentro de la función se usan tres condiciones; la primera para los segundos; cuando se le hace la consulta del tiempo al modulo de reloj, si el tiempo es menor a diez segundos, este devolverá un solo dígito; es decir, si el tiempo tiene solo siete segundos en lugar de devolver "07" que seria el valor que esperamos, solo nos regresaría "7". La comprobación sirve para cuando sucede este caso. Para solucionarlo, si el tiempo (segundos, minutos u horas) es menor a 10, llamamos a la función "PrintTime()" dos veces y en la primera llamada, le pasamos como primer parámetro el valor de los segundos y en el segundo parámetro el valor "0" que indica que queremos usar la primer matriz (el orden ya lo había dicho). Para la segunda llamada, le pasaremos el valor de "0" cómo primer parámetro y "1" cómo segundo, así cuando pase el caso de siete segundos (por ejemplo) tendremos un número para mostrar en el segundo display. Cuando es el caso contrario o mejor dicho cuando los valores son mayores o iguales a diez, lo único que hacemos dividir y en la primera llamada pasamos el resultado del modulo del valor actual (segundos, minutos u horas) y diez. Para la segunda llamada simplemente dividimos en valor entre diez y esto nos dará el valor que debemos de mostrar en la segunda llamada.

Dentro del bucle principal lo primero que hacemos es llamar a la función "ShowIntro" valiendonos de un flag llamado "Intro" que se inicializa en "true", la condición dice que cuando esta variable es verdadero se hace la animación, al se una variable global, cuando la animación acaba, cambia el valor de la variable "Intro" a "false" por lo que la animación solo se produce una sola vez. Acabada la animación, usamos las funciones de la libreria del reloj. Primero comprobamos si se puede leer desde el módulo, si es así llamamos a la función "PrintTime()" con las horas; "tm.Hour", los minutos; "tm.Minute", y los segundos "tm.Seconds". Con esto mostramos la hora en los "displays". Si no se puede obtener la hora del módulo, se trata de comprobar si el chip está disponible, si es así solamente bastará con subir el ejemplo que viene en la librería (disponible en Ejemplos >> DS1307RTC >> SetTime). Solo tendremos que subirlo antes que este código y ya tendrá la hora ajustada.

Y bien, por ahora es todo, en el próximo post veremos cómo mejorar un poco más el reloj, aunque creo que lo ideal seria usar el código de clock view y solamente adaptar las partes que necesitemos.

Los leo luego.

No hay comentarios.