Hola amigos.
Estoy intetando hacer un reloj despertador usando el reloj interno de un Arduino Nano y ahora mismo estoy en esta fase del prototipo:
Por ahora solo muestra horas y minutos y hace parpadear el punto intermedio un segundo ON un segundo OFF.
Con los pulsadores se pone en hora de una forma muy sencilla (más adelante utilizaré algo mas eficiente en el uso de pines): los cuatro de mas a la izquierda incrementan en una unidad cada dígito y el quinto resetea los segundos.
El código es el siguiente:
//RELOJ DIGITAL CON ALARMA Y CALENDARIO
//Miguel Berbegal
//15/1/2017
//VARIABLES
//puertos y salidas digitales
byte ud_min = 7; //pin del dígito unidades de los minutos
byte dec_min = 8; //pin del dígito decenas de los minutos
byte ud_hor=9; //pin del dígito unidades de las horas
byte dec_hor=10; //pin del dígito decenas de las horas
byte d0 = 2; //d0 a d3 son los dígitos del número en binario que se quiera mostrar en un dígito
byte d1 = 3;
byte d2 = 4;
byte d3 = 5;
byte punto=6; //pin para el punto
byte output[] = {d0, d1, d2, d3}; //número en binario que se va a introducir al 74hc4511
//variables del reloj
byte segundos = 0;
byte minutos = 0;
byte horas = 0;
byte dia = 1;
byte mes = 1;
int anno = 2017;
byte seg_unidades = 0;
byte seg_decenas = 0;
byte min_unidades = 0;
byte min_decenas = 0;
byte hor_unidades = 0;
byte hor_decenas = 0;
byte dia_unidades = 0;
byte dia_decenas = 0;
byte mes_unidades = 0;
byte mes_decenas = 0;
byte anno_unidades = 0;
byte anno_decenas = 0;
byte anno_centenas = 0;
byte anno_miles = 0;
//contadores
unsigned long contador = 0;
//unsigned long timer1 = 0;
//unsigned long timer2 = 0;
//parpadeo del punto
byte estado_punto=0;
//entradas digitales
byte pulsadores[]={14,15,16,17,18}; //pines de los pulsadores
byte estado_pulsador[]={1,1,1,1,1}; //estados para el detector de flanco
byte estado_pulsador_ant[]={1,1,1,1,1};
//INICIALZACION
void setup() {
for (int i = 0; i < 4; i++) {
pinMode(output[i], OUTPUT);
}
pinMode(6,OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9,OUTPUT);
pinMode(10,OUTPUT);
for (int i = 0; i < 5; i++) {
pinMode(pulsadores[i], INPUT);
}
digitalWrite(ud_min, LOW);
digitalWrite(dec_min, LOW);
digitalWrite(ud_hor, LOW);
digitalWrite(dec_hor, LOW);
digitalWrite(d0, LOW);
digitalWrite(d1, LOW);
digitalWrite(d2, LOW);
digitalWrite(d3, LOW);
digitalWrite(punto,LOW);
contador = millis();
}
//BUCLE
void loop() {
//puesta en hora con pulsadores
for(int i=0;i<5;i++){ //almacenamiento de los datos del bucle anterior
estado_pulsador_ant[i]=estado_pulsador[i];
}
for(int i=0;i<5;i++){ //lectura de los pulsadores
estado_pulsador[i]=digitalRead(pulsadores[i]);
}
if((estado_pulsador[0]==0)&&(estado_pulsador[0]!=estado_pulsador_ant[0])){
minutos++;
}
if((estado_pulsador[1]==0)&&(estado_pulsador[1]!=estado_pulsador_ant[1])){
minutos=minutos+10;
}
if((estado_pulsador[2]==0)&&(estado_pulsador[2]!=estado_pulsador_ant[2])){
horas++;
}
if((estado_pulsador[3]==0)&&(estado_pulsador[3]!=estado_pulsador_ant[3])){
horas=horas+10;
}
if((estado_pulsador[4]==0)&&(estado_pulsador[4]!=estado_pulsador_ant[4])){
contador = millis();
segundos=0;
estado_punto=0;
//timer1=timer2;
}
//lógica de segundos minutos horas dias meses y año, utilizando contador para saber cuando ha pasado un segundo
if ((millis() - contador) > 999) { //incremento de segundos usando millis
contador = millis();
segundos++;
estado_punto^=1; //cambiar cada segundo el punto de ON a OFF
}
// timer2=(millis()/1000); //otra forma que probe para incrementar segundos
// if ( timer1 != timer2 ) {
// timer1=timer2;
// segundos++;
// estado_punto^=1;
// }
if (segundos > 59) {
segundos = 0;
minutos++;
}
if (minutos > 59) {
minutos = 0;
horas++;
}
if (horas > 23) {
horas = 0;
dia++;
}
if ((mes == 1) || (mes == 3) || (mes == 5) || (mes == 7) || (mes == 8) || (mes == 10) || (mes == 12)) {
if (dia > 31) {
dia = 1;
mes++;
}
} else if (mes == 2) {
if (dia > 28) {
dia = 1;
mes++;
}
} else {
if (dia > 30) {
dia = 1;
mes++;
}
}
if (mes > 12) {
mes = 1;
anno++;
}
//división en dígitos
seg_decenas = int(segundos / 10);
seg_unidades = segundos - seg_decenas * 10;
min_decenas = int(minutos / 10);
min_unidades = minutos - min_decenas * 10;
hor_decenas = int(horas / 10);
hor_unidades = horas - hor_decenas * 10;
dia_decenas = int(dia / 10);
dia_unidades = dia - dia_decenas * 10;
mes_decenas = int(mes / 10);
mes_unidades = mes - mes_decenas * 10;
anno_miles = int(anno / 1000);
anno_centenas = int((anno - anno_miles * 1000) / 100);
anno_decenas =int((anno-anno_miles*1000-anno_centenas*100)/10);
anno_unidades = anno-anno_miles*1000-anno_centenas*100-anno_decenas*10;
//control de displays
//minutos
digitalWrite(dec_hor, LOW);
for (int i = 0; i < 4; i++) {
if (((min_unidades >> i) & 1) == 1) {
digitalWrite(output[i], HIGH);
} else {
digitalWrite(output[i], LOW);
}
}
digitalWrite(ud_min, HIGH);
delay(2.5);
digitalWrite(ud_min, LOW);
for (int i = 0; i < 4; i++) {
if (((min_decenas >> i) & 1) == 1) {
digitalWrite(output[i], HIGH);
} else {
digitalWrite(output[i], LOW);
}
}
digitalWrite(dec_min, HIGH);
delay(2.5);
//horas
digitalWrite(dec_min, LOW);
digitalWrite(punto, estado_punto); //para que el punto intermedio se ilumine si le toca
for (int i = 0; i < 4; i++) {
if (((hor_unidades >> i) & 1) == 1) {
digitalWrite(output[i], HIGH);
} else {
digitalWrite(output[i], LOW);
}
}
digitalWrite(ud_hor, HIGH);
delay(2.5);
digitalWrite(ud_hor, LOW);
digitalWrite(punto, LOW); //para que no se iluminen los puntos de los otros digitos
for (int i = 0; i < 4; i++) {
if (((hor_decenas >> i) & 1) == 1) {
digitalWrite(output[i], HIGH);
} else {
digitalWrite(output[i], LOW);
}
}
digitalWrite(dec_hor, HIGH);
delay(2.5);
}
El problema que tengo es que el reloj se retrasa unos segundos cada hora... No veo donde está el fallo. ¿Hay algo mal en cómo estoy contando los segundos? ¿Los delays que uso para multiplexar los displays hacen que mis segundos sean mas largos? ¿Podría ser problema del propio Arduino y su oscilador?
Gracias de antemano