| EL RELOJ DIGITAL GRANDE |
|
EL RELOJ DIGITAL GRANDE
El objetivo de este proyecto fue el de poder contar con un reloj digital que fuera extremadamente
fácil de ver, por lo que sus dígitos debían ser lo más grandes que fuera posible, y con luz propia.
Además, era necesario que el mismo brindase siempre la hora exacta.
Los cuatro dígitos fueron montados en una plaqueta perforada, en dos grupos de dos, separados
levemente por dos LEDs pequeños que cumplen la función de mostrar los dos puntos separadores
de las horas respecto de los minutos. En esta plaqueta, se montaron también 8 resistencias de
330 ohms, una por cada uno de los 7 segmentos y otra para el punto de los displays. En cuanto
a las conexiones, se juntaron los contactos de cada segmento (y los de los puntos) en una misma
conexión para los cuatro dígitos, interponiendo una de las resistencias para limitar la corriente
y evitar que se quemen. Si bien en este proyecto no se utilizan los puntos, se incluyeron sus
conexiones en la plaqueta por si en un futuro fuese necesario destinarla a otro proyecto.
Entre el frente de cartón y los dígitos, se colocó un rectángulo de acrílico de color rojo oscuro, transparente, para mejorar el contraste de la luz emitida por el módulo. La plaqueta Arduino con el módulo de conexión a Ethernet acoplado fueron adheridos al interior del gabinete mediante una tira de velcro, y los cables de alimentación y de conexión a la red, fueron adheridos al gabinete utilizando una pistola de resina plástica, de manera que soporten tironéos moderados sin que estos puedan afectar a los circuitos. Finalmente se cargó en el Arduino, un sketch con la programación necesaria para la configuración inicial del sistema y un lazo cerrado en el que constantemente se consulta la hora en los servidores NTP y se la muestra en los dígitos.
#include "Arduino.h"
#include <SPI.h> //
#include <Ethernet.h> // PARA LA CONEXION A LA RED E INTERNET
#include <EthernetUdp.h> // PROTOCOLO UDP EN LA RED E INTERNET
#include <Dns.h> // PARA TRABAJAR CON DNS
// VARIABLES PARA LA CONEXION EN RED
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// INICIALIZACION DE UDP
unsigned int localPort = 80;
IPAddress timeServer(193, 92, 150, 3);
const int NTP_PACKET_SIZE= 48;
byte packetBuffer[NTP_PACKET_SIZE];
const char* host="nsath.forthnet.gr";
EthernetUDP Udp;
DNSClient Dns;
IPAddress rem_add;
int horas;
int minutos;
// ***********************************************
// ** SETUP **
// ***********************************************
void setup() {
pinMode(22,OUTPUT); // Display 1 - común
pinMode(24,OUTPUT); // Display 2 - común
pinMode(26,OUTPUT); // Display 3 - común
pinMode(28,OUTPUT); // Display 4 - común
pinMode(30,OUTPUT); // Dígito -
pinMode(32,OUTPUT); // Dígito -
pinMode(34,OUTPUT); // Dígito -
pinMode(36,OUTPUT); // Dígito -
pinMode(38,OUTPUT); // Dígito -
pinMode(40,OUTPUT); // Dígito -
pinMode(42,OUTPUT); // Dígito -
pinMode(44,OUTPUT); // Dígito -
digitalWrite(22,HIGH);
digitalWrite(24,LOW);
digitalWrite(26,LOW);
digitalWrite(28,LOW);
digitalWrite(30,HIGH); // Inferior derecho
digitalWrite(32,HIGH); // Punto
digitalWrite(34,HIGH); // Inferior izquierdo
digitalWrite(36,HIGH); // Abajo y al centro
digitalWrite(38,HIGH); // Al centro
digitalWrite(40,HIGH); // Superior izquierdo
digitalWrite(42,HIGH); // Superior izquierdo
digitalWrite(44,HIGH); // Superior
Serial.begin(9600);
if (Ethernet.begin(mac) == 0) {
Serial.println("ERROR EN DHCP");
}
Udp.begin(localPort);
Dns.begin(Ethernet.dnsServerIP());
horas = 0;
minutos = 0;
}
// **************************
// ** RUTINAS DE APOYO **
// **************************
// ACTIVAR DIGITO
void activarDigito(int digito, int valor) {
switch (digito) {
case 1:
digitalWrite(22,HIGH);
digitalWrite(24,LOW);
digitalWrite(26,LOW);
digitalWrite(28,LOW);
break;
case 2:
digitalWrite(22,LOW);
digitalWrite(24,HIGH);
digitalWrite(26,LOW);
digitalWrite(28,LOW);
break;
case 3:
digitalWrite(22,LOW);
digitalWrite(24,LOW);
digitalWrite(26,HIGH);
digitalWrite(28,LOW);
break;
case 4:
digitalWrite(22,LOW);
digitalWrite(24,LOW);
digitalWrite(26,LOW);
digitalWrite(28,HIGH);
break;
}
switch (valor) {
case 0:
digitalWrite(40,LOW); // Superior izquierdo
digitalWrite(44,LOW); // Superior
digitalWrite(42,LOW); // Superior derecho
digitalWrite(38,HIGH); // Al centro
digitalWrite(30,LOW); // Inferior derecho
digitalWrite(36,LOW); // Abajo y al centro
digitalWrite(34,LOW); // Inferior izquierdo
digitalWrite(32,HIGH); // Punto
break;
case 1:
digitalWrite(40,HIGH); // Superior izquierdo
digitalWrite(44,HIGH); // Superior
digitalWrite(42,LOW); // Superior derecho
digitalWrite(38,HIGH); // Al centro
digitalWrite(30,LOW); // Inferior derecho
digitalWrite(36,HIGH); // Abajo y al centro
digitalWrite(34,HIGH); // Inferior izquierdo
digitalWrite(32,HIGH); // Punto
break;
case 2:
digitalWrite(40,HIGH); // Superior izquierdo
digitalWrite(44,LOW); // Superior
digitalWrite(42,LOW); // Superior derecho
digitalWrite(38,LOW); // Al centro
digitalWrite(30,HIGH); // Inferior derecho
digitalWrite(36,LOW); // Abajo y al centro
digitalWrite(34,LOW); // Inferior izquierdo
digitalWrite(32,HIGH); // Punto
break;
case 3:
digitalWrite(40,HIGH); // Superior izquierdo
digitalWrite(44,LOW); // Superior
digitalWrite(42,LOW); // Superior derecho
digitalWrite(38,LOW); // Al centro
digitalWrite(30,LOW); // Inferior derecho
digitalWrite(36,LOW); // Abajo y al centro
digitalWrite(34,HIGH); // Inferior izquierdo
digitalWrite(32,HIGH); // Punto
break;
case 4:
digitalWrite(40,LOW); // Superior izquierdo
digitalWrite(44,HIGH); // Superior
digitalWrite(42,LOW); // Superior derecho
digitalWrite(38,LOW); // Al centro
digitalWrite(30,LOW); // Inferior derecho
digitalWrite(36,HIGH); // Abajo y al centro
digitalWrite(34,HIGH); // Inferior izquierdo
digitalWrite(32,HIGH); // Punto
break;
case 5:
digitalWrite(40,LOW); // Superior izquierdo
digitalWrite(44,LOW); // Superior
digitalWrite(42,HIGH); // Superior derecho
digitalWrite(38,LOW); // Al centro
digitalWrite(30,LOW); // Inferior derecho
digitalWrite(36,LOW); // Abajo y al centro
digitalWrite(34,HIGH); // Inferior izquierdo
digitalWrite(32,HIGH); // Punto
break;
case 6:
digitalWrite(40,LOW); // Superior izquierdo
digitalWrite(44,LOW); // Superior
digitalWrite(42,HIGH); // Superior derecho
digitalWrite(38,LOW); // Al centro
digitalWrite(30,LOW); // Inferior derecho
digitalWrite(36,LOW); // Abajo y al centro
digitalWrite(34,LOW); // Inferior izquierdo
digitalWrite(32,HIGH); // Punto
break;
case 7:
digitalWrite(40,HIGH); // Superior izquierdo
digitalWrite(44,LOW); // Superior
digitalWrite(42,LOW); // Superior derecho
digitalWrite(38,HIGH); // Al centro
digitalWrite(30,LOW); // Inferior derecho
digitalWrite(36,HIGH); // Abajo y al centro
digitalWrite(34,HIGH); // Inferior izquierdo
digitalWrite(32,HIGH); // Punto
break;
case 8:
digitalWrite(40,LOW); // Superior izquierdo
digitalWrite(44,LOW); // Superior
digitalWrite(42,LOW); // Superior derecho
digitalWrite(38,LOW); // Al centro
digitalWrite(30,LOW); // Inferior derecho
digitalWrite(36,LOW); // Abajo y al centro
digitalWrite(34,LOW); // Inferior izquierdo
digitalWrite(32,HIGH); // Punto
break;
case 9:
digitalWrite(40,LOW); // Superior izquierdo
digitalWrite(44,LOW); // Superior
digitalWrite(42,LOW); // Superior derecho
digitalWrite(38,LOW); // Al centro
digitalWrite(30,LOW); // Inferior derecho
digitalWrite(36,LOW); // Abajo y al centro
digitalWrite(34,HIGH); // Inferior izquierdo
digitalWrite(32,HIGH); // Punto
break;
case 10:
digitalWrite(40,HIGH); // Superior izquierdo
digitalWrite(44,HIGH); // Superior
digitalWrite(42,HIGH); // Superior derecho
digitalWrite(38,HIGH); // Al centro
digitalWrite(30,HIGH); // Inferior derecho
digitalWrite(36,HIGH); // Abajo y al centro
digitalWrite(34,HIGH); // Inferior izquierdo
digitalWrite(32,LOW); // Punto
break;
}
}
void mostrarHora(int horas, int minutos) {
activarDigito(1,(int) horas/10);
delay(1);
activarDigito(2, horas%10);
delay(1);
activarDigito(3,(int) minutos/10);
delay(1);
activarDigito(4, minutos%10);
delay(1);
}
// RESETEA POR SOFTWARE AL ARDUINO
void (* resetFunc)(void) = 0;
// SEND AN NTP REQUEST TO THE TIME SERVER AT THE GIVEN ADDRESS
unsigned long sendNTPpacket(IPAddress& address) {
memset(packetBuffer, 0, NTP_PACKET_SIZE);
packetBuffer[0] = 0b11100011;
packetBuffer[1] = 0;
packetBuffer[2] = 6;
packetBuffer[3] = 0xEC;
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
Udp.beginPacket(address, 123);
Udp.write(packetBuffer,NTP_PACKET_SIZE);
Udp.endPacket();
}
// ***********************************************
// ** LOOP **
// ***********************************************
void loop() {
if(Dns.getHostByName(host, rem_add) == 1 ){
Serial.println("DNS resolve...");
Serial.print(host);
Serial.print(" = ");
Serial.println(rem_add);
sendNTPpacket(rem_add);
} else {
Serial.print("DNS fail...");
Serial.print("time.nist.gov = ");
Serial.println(timeServer);
sendNTPpacket(timeServer);
}
for (int iii=1; iii<5000; iii++) {
mostrarHora(horas,minutos);
delay(1);
}
if ( Udp.parsePacket() ) {
Udp.read(packetBuffer,NTP_PACKET_SIZE); // read the packet into the buffer
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
unsigned long secsSince1900 = highWord << 16 | lowWord;
const unsigned long seventyYears = 2208988800UL;
unsigned long epoch = secsSince1900 - seventyYears - 3*60*60;
Serial.println(epoch);
horas = ((epoch % 86400L) / 3600);
minutos = ((epoch % 3600) / 60);
}
for (int iii=1; iii<5000; iii++) {
mostrarHora(horas,minutos);
delay(1);
}
}
|