Vamos a programar #43 - Actualizando clock view.

Hola de nuevo a todos, el día de hoy vamos a ver una actualizacion del código de clock view.
Cómo recordarás, hace un buen rato dije que iba a actualizar el código, pero por varias razones lo pospuse, hasta que finalmente casí lo olvide. No se le hicieron muchos cambios, solo optimizaron algunas partes y se saco un poco más de provecho a las partes que ya se usaban y se agregaron unas cuantas más. Sí previamente ya habías hecho el proyecto, solo bastará con cargar el código al arduino, de cualquier forma, el código estará disponible para su descarga.

El código.

El código actualizado del Clock View es el siguiente:
//Clockview 2.0
#include <DS1302.h>
#include "LedControl.h"
#include <SD.h>
/*
	Para la conexión del modulo SD se siguen los siguientes:
	** MOSI - pin 11
	** MISO - pin 12
	** CLK - pin 13
	** CS - pin 10 - Este es el que se puede cambiar
*/
//Pin SD
int CS_PIN = 10;
//Constantes para los pines usados en la matriz
const int MaxDIn = 9;
const int MaxCS = 8;
const int MaxCLK = 7;
int MaxNDevices = 3;
bool IsConnected = false;
//Constantes para los pines usados en el reloj
const int kCePin = 6;  // RST
const int kIoPin = 5;  // Dat
const int kSclkPin = 4;  // Serial Clock
//Inicializacion de la matriz
//DIN,CLK,CS
LedControl lc = LedControl(MaxDIn, MaxCLK, MaxCS, MaxNDevices);
//Inicializacion del reloj
DS1302 rtc(kCePin, kIoPin, kSclkPin);
//Algunas variables
File Archivo;
char Texto[24];
int MatrixB = 10;
bool H24 = true;
bool HalfSecond = true;
bool IsScreenEnable = true;
bool ShowSeconds = true;
bool SDCardReady = false;
bool EditMode = false;
bool ShowDate = false;
bool Demo = false;
//Matriz con los "Numeros"
const unsigned char Numbers[] = {
	B11111110, B10000010, B11111110, //0
	B10000100, B11111110, B10000000, //1
	B11110010, B10010010, B10011110, //2
	B10000010, B10010010, B11111110, //3
	B00011110, B00010000, B11111110, //4
	B10011110, B10010010, B11110010, //5
	B11111110, B10010010, B11110010, //6
	B00000010, B00000010, B11111110, //7
	B11111110, B10010010, B11111110, //8
	B00011110, B00010010, B11111110, //9
	B11111110, B00010010, B11111110, //A - 10
	B11111110, B00011100, B11111110, //M - 11
	B11111110, B00010010, B00011110, //P - 12
	B11111110, B00010000, B11111110, //H - 13
	B11111110 ,B00110010, B11011110, //R - 14
};
//Definimos simbolos
const unsigned char Symbols[] = {
	B01000100, B00101000, B00010000, B11111110, B01010100, B00101000, //BT 0
	B00111100, B01000110, B01011010, B01001010, B01001010, B00111100, //Clock Adjust 1
	B11010110, B10111010, B01000100, B01000100, B10111010, B11010110//Brightness 2
};
//Imprimir simbolos
void PrintSymbol(byte Index,byte SymDevice){
	for (int Y = 1; Y < 7; Y++){
		lc.setRow(SymDevice, Y, Symbols[Index * 5 + Y - 1]);
	}
}
//Funcion para escribir los numero en la matriz.
void PrintNumber(byte NumberOne, byte NumberTwo, byte Device){
	for (int X = 1; X < 8; X++){
		if (X < 4){
			lc.setRow(Device, X, Numbers[NumberOne * 3 + X - 1]);
		}
		if (X == 4){
			lc.setRow(Device, 4, 0);
		}
		if (X > 4){
			lc.setRow(Device, X, Numbers[NumberTwo * 3 + X - 5]);
		}
	}
}
void printDate(){
	Time t = rtc.time();
	const String day = dayAsString(t.day);
	char buf[50];
	snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d",
	day.c_str(), t.yr, t.mon, t.date, t.hr, t.min, t.sec);
	int ShortYear = t.yr % 100;
	PrintNumber(t.date / 10, t.date % 10, 0);
	PrintNumber(t.mon / 10, t.mon % 10, 1);
	PrintNumber(ShortYear / 10, ShortYear % 10, 2);
}
//Imprimir el tiempo en las matrices y en el monitor serie.
void printTime(){
	Time t = rtc.time();
	const String day = dayAsString(t.day);
	char buf[50];
	snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d",
		day.c_str(), t.yr, t.mon, t.date, t.hr, t.min, t.sec);
	PrintNumber(AdjustTime(t.hr, H24) / 10,AdjustTime(t.hr, H24) % 10, 0);
	PrintNumber(t.min / 10, t.min % 10, 1);
	if (ShowSeconds){
		PrintNumber(t.sec / 10, t.sec % 10, 2);	
	}else{
		if(H24)
			PrintNumber(13, 14, 2);
		if(!H24 && t.hr < 13)
			PrintNumber(10, 11, 2);
		if(!H24 && t.hr > 12)
			PrintNumber(12, 11, 2);
	}
	//PrintSymbol(0, 2);
	if (IsScreenEnable == true)
	{
		if (HalfSecond == true){
			digitalWrite(3, HIGH);
			HalfSecond = false;
		}else{
			digitalWrite(3, LOW);
			HalfSecond = true;
		}
	}
	Serial.println(buf);
}
//Demo directo del ejemplo de la libreria
void ScreenDemo(){
	int devices=lc.getDeviceCount();
	for(int row=0;row<8;row++) {
		for(int col=0;col<8;col++) {
			for(int address=0;address<devices;address++) {
				int DemoButton = analogRead(A5);
				if(DemoButton < 200){
					Demo = false;
					break;
				}
				delay(40);
				lc.setLed(address,row,col,true);
				delay(40);
				lc.setLed(address,row,col,false);
			}
		}
	}
}
//Ajustar la hora
int AdjustTime(int Hour, bool In24Hformat){
	if(In24Hformat == true){
		return Hour;
	}
	if(In24Hformat == false && Hour > 12){
		Hour = Hour - 12;
		return Hour;
	}else{
		return Hour;
	}
}
//Guardar los ajustes
void SaveSettings(){
	Archivo = SD.open("Settings.clv", O_WRITE | O_CREAT);
	char SaveBuf[8];
	snprintf(SaveBuf, sizeof(SaveBuf), "%s%02d",">SETB", MatrixB);
	Serial.println(SaveBuf);
	if (Archivo){
		Archivo.seek(0);
		Archivo.println(SaveBuf);
		if(H24)
			Archivo.println(">SETF");
		else
			Archivo.println("XSETF");
		if (ShowSeconds)
			Archivo.println(">DISS");
		else
			Archivo.println("XDISS");
			Archivo.flush();
			Archivo.close();
		Serial.println("Guardado");
	} else {
		Serial.println("error writing test.txt");
	}
}
//Enviar un resumen de las configuraciones actuales
void SendResume(){
	
}
//Cargar los ajustes
void LoadSettings(){
	Archivo = SD.open("Settings.clv", FILE_READ);
	int B = 0;
	byte CurRead;
	char SettBuf[22];
	if (Archivo) {
		while (Archivo.available() > 0){
			CurRead = Archivo.read();
			if	(CurRead != 10 && CurRead != 13){
				SettBuf[B] = CurRead;
				B++;
				Serial.print(B);
			}else{
				CheckPetition(SettBuf, false);
				Serial.print(B);
				B = 0;
				for (int BF = 0; BF < 22; BF++)
					SettBuf[BF]=0;
			}
		}
		Archivo.close();
	}else{
		Serial.println("error opening file");
	}	
}
//Comprobar si hay algun comando
void CheckPetition(char DATA[], bool Save){
	int i = 0;
	int j = 0;
	String Texto(DATA);
	//>SETH2016122119001004
	if (Texto.startsWith(">DISS")){
		ShowSeconds = !ShowSeconds;
		if (Save)
			SaveSettings();
		Serial.print("No/Se muestran los segundos");
		for (int CurrentDevice = 0; CurrentDevice < MaxNDevices; CurrentDevice++){
			lc.shutdown(CurrentDevice, !IsScreenEnable);
		}
		for (j = 0; j < 11; j++) {
			DATA[j] = 0;
		}
		i = 0;
	}
	if (Texto.startsWith(">SCRA")){
		IsScreenEnable = !IsScreenEnable;
		Serial.print("Las matrices se apagaron/encendieron");
		for (int CurrentDevice = 0; CurrentDevice < MaxNDevices; CurrentDevice++){
			lc.shutdown(CurrentDevice, !IsScreenEnable);
		}
		for (j = 0; j < 11; j++) {
			DATA[j] = 0;
		}
		i = 0;
	}	
	if (Texto.startsWith(">RESET")){
		SD.remove("Settings.clv");
		for (int CurrentDevice = 0; CurrentDevice < MaxNDevices; CurrentDevice++){
			lc.shutdown(CurrentDevice, !IsScreenEnable);
		}
		for (j = 0; j < 11; j++) {
			DATA[j] = 0;
		}
		i = 0;
	}	
	if (Texto.startsWith(">SETF")){
		H24 = !H24;
		if (Save)
			SaveSettings();
		Serial.print("EL reloj cambio de formato 12H-24H");
		for (j = 0; j < 11; j++) {
			DATA[j] = 0;
		}
		i = 0;
	}
	if (Texto.startsWith(">SETH")){
		AdjustTime(Texto.substring(9, 5).toInt(),Texto.substring(11,9).toInt(),Texto.substring(13, 11).toInt(),
		Texto.substring(15, 13).toInt(), Texto.substring(17, 15).toInt(), Texto.substring(19, 17).toInt(),
		Texto.substring(21, 19).toInt());
		for (j = 0; j < 11; j++) {
			DATA[j] = 0;
		}
		i = 0;
	}
	if (Texto.startsWith(">SETB")){
		MatrixB = Texto.substring(5).toInt();
		if (Save)
			SaveSettings();
		Serial.println("El brillo se cambio");
		for (int CurrentDevice = 0; CurrentDevice < MaxNDevices; CurrentDevice++){
			lc.setIntensity(CurrentDevice, MatrixB);
		}
		for (j = 0; j < 11; j++) {
			DATA[j] = 0;
		}
		i = 0;
	}
	else {
		for (j = 0; j < 11; j++) {
			DATA[j] = 0;
		}
		i = 0;
	}
}
//Convertir los dias
String dayAsString(const Time::Day day){
	switch (day){
		case Time::kSunday: return "DOM";
		case Time::kMonday: return "LUN";
		case Time::kTuesday: return "MAR";
		case Time::kWednesday: return "MIE";
		case Time::kThursday: return "JUE";
		case Time::kFriday: return "VIE";
		case Time::kSaturday: return "SAB";
	}
	return "(unknown day)";
}
//Ajustar la hora
void AdjustTime(int Year,int Month, int Day, int Hour, int Minute, int Second, int DayOfWeek){
	Time::Day CurrentDay;
	switch (DayOfWeek){
		case 1:
			CurrentDay = Time::kSunday;
			break;
		case 2:
			CurrentDay = Time::kMonday;
			break;
		case 3:
			CurrentDay = Time::kTuesday;
			break;
		case 4:
			CurrentDay = Time::kWednesday;
			break;
		case 5:
			CurrentDay = Time::kThursday;
			break;
		case 6:
			CurrentDay = Time::kFriday;
			break;
		case 7:
			CurrentDay = Time::kSaturday;
			break;
	}
	//Esta parte se usa para actualizar la hora.
	rtc.writeProtect(false);
	rtc.halt(false);
	Time t(Year, Month, Day, Hour, Minute, Second, CurrentDay);
	rtc.time(t);	
}
//Inicializar la tarjeta SD para usarla
void InitializeSD(){
	pinMode(CS_PIN, OUTPUT);
	if (SD.begin()){
		SDCardReady = true;
		Serial.println("La tarjeta SD esta lista");
	}else{
		SDCardReady = false;
		Serial.println("La tarjeta SD no esta lista");
		return;
	}
}
//Setup
void setup(){
	Serial.begin(9600);
	for (int CurrentDevice = 0; CurrentDevice < MaxNDevices; CurrentDevice++){
		lc.shutdown(CurrentDevice, false);
		lc.setIntensity(CurrentDevice, MatrixB);
		lc.clearDisplay(CurrentDevice);
	}
	InitializeSD();
	pinMode(A2, INPUT_PULLUP);
	pinMode(A3, INPUT_PULLUP);
	pinMode(A4, INPUT_PULLUP);
	pinMode(A5, INPUT_PULLUP);
	pinMode(3, OUTPUT);
	if(SDCardReady){
		LoadSettings();
	}else{
		Serial.println("La tarjeta no está lista");
	}
}
//Loop
void loop(){
	int SetEditButton = analogRead(A2);
	int ShowDateButton = analogRead(A3);
	int TurnOffMatrixButton = analogRead(A4);
	int DemoButton = analogRead(A5);
	
	while (Demo == true){
		ScreenDemo();
	}
	if(DemoButton < 200){
		Demo = !Demo;
	}
	Serial.println(SetEditButton);	
	if(SetEditButton < 200){
		EditMode = !EditMode;
	}
	if(ShowDateButton < 200){
		ShowDate = true;
	}
	if(TurnOffMatrixButton < 200){
		IsScreenEnable = !IsScreenEnable;
		for (int CurrentDevice = 0; CurrentDevice < MaxNDevices; CurrentDevice++){
			lc.shutdown(CurrentDevice, IsScreenEnable);
		}
	}	
	if(ShowDate){
		printDate();
		delay(3000);
		ShowDate = false;
	}
	if(EditMode){
		int PotB = analogRead(A0);
		// print out the value you read:
		int MatrixB = map(PotB, 0, 1000, 1, 15);
		char SaveBuf[8];
		snprintf(SaveBuf, sizeof(SaveBuf), "%s%02d",">SETB", MatrixB);
		CheckPetition(SaveBuf, false);
		PrintNumber(MatrixB / 10,MatrixB % 10, 2);
		PrintSymbol(2,1);
		delay(100);
	}else{
		int i = 0;
		printTime();
		delay(100);
		if (Serial.available()) {
			while (Serial.available() > 0) {
				Texto[i] = Serial.read();
				i++;
			}
			Texto[i] = '\0';
		}
		CheckPetition(Texto, true);	
	}
}



El código es funcional, pero demostrativo. Uno de los cambios más notorios que se puede observar, es que los número son más grandes.
Los números eran de 3x5 LEDs, en su lugar, ahora son de 7x3
Además se hace uso de pulsadores para que tambien sea manipulable, en este caso, el código hace uso de 4, pero tal vez en un futuro, se usen solo 3, he visto muchos relojes que solo hacen el uso de ese número.
El código se actualizará nuevamente, pero por ahora lo público así para que te sientas libre de probar con tus propios ajustes. Si no dispones de pulsadores, no te preocupes, aun es totalmente utilizable solo por medio de bluetooth. El código anterior lo puedes descargar de la seccion de descargas y si quieres hacer uso de este, basta con copiarlo; todas las conexiones vienen en el código.
Por ahora es todo, los leo luego.

No hay comentarios.