¿Cuántos días llevas vivo en este mismo instante? No los años, los días exactos. Es una pregunta simple que casi nadie puede responder de memoria, y resulta ser una excusa perfecta para construir tu primera calculadora física con Arduino.

En este tutorial vas a montar un aparato de bolsillo que recibe tu fecha de nacimiento por un teclado, la compara con la fecha de hoy y muestra en una pantalla LCD el total de días transcurridos, tomando en cuenta los años bisiestos. Es un proyecto ideal para entrar en serio al mundo Arduino: combina entrada por teclado matricial, una pantalla 16x2 controlada por I2C y un poco de matemática de calendario. Al terminar vas a saber leer un teclado 4x4, escribir en una LCD usando solo dos pines y armar una máquina de estados sencilla para guiar al usuario paso a paso.

Calculadora de días vividos con Arduino, teclado matricial y pantalla LCD

Qué vas a necesitar

El hardware es mínimo y todo cabe en una protoboard o, si quieres el acabado final, dentro de una caja de proyecto:

  • Placa Arduino Uno como cerebro del proyecto.
  • Teclado matricial 4x4 (16 teclas) para ingresar las fechas.
  • Pantalla LCD 16x2 para mostrar el resultado.
  • Módulo serial I2C para la LCD, que reduce el cableado de la pantalla a solo 2 pines de datos.
  • Fuente de 5V o un cable USB para alimentar la placa.
  • Cables Dupont para conectar el teclado y la pantalla a los pines de la Arduino.
  • Opcional: una caja de proyecto y un conector DC hembra con rosca para dejarlo prolijo y portátil.

La gran ventaja del módulo I2C es justamente esa: una LCD 16x2 tradicional ocupa 6 o 7 pines digitales de la Arduino, pero con el adaptador I2C soldado por detrás solo usas dos líneas (SDA y SCL). Eso te deja libres los pines digitales que el teclado necesita.

Módulo serial I2C soldado en la parte trasera de una pantalla LCD 16x2

Conexiones del hardware

Vamos por partes. Primero el teclado, después la pantalla.

El teclado matricial 4x4

Un teclado matricial no tiene un pin por tecla, sería imposible: 16 botones se manejan con apenas 8 pines gracias a una matriz de 4 filas por 4 columnas. La Arduino energiza una fila a la vez y revisa qué columna se activa, así deduce qué tecla apretaste sin gastar 16 entradas.

Conecta los 8 pines del teclado en orden a los pines digitales del 2 al 9 de la Arduino. Los pines 2 a 5 corresponden a las filas y los pines 6 a 9 a las columnas, tal como los define el código más abajo.

Diagrama de conexión del teclado matricial 4x4 y la pantalla LCD a la Arduino Uno

La pantalla LCD por I2C

Como usamos el módulo serial I2C, la pantalla se alimenta con 5V y GND, y los datos viajan por dos pines especiales de la Arduino: SCL en A5 y SDA en A4. Ojo con esto: en el Arduino Uno los pines I2C son A4 y A5, pero en otras placas (Mega, Leonardo, etc.) están en otra posición, así que revisa siempre el diagrama de tu modelo antes de conectar.

Detalle del cableado del módulo I2C a los pines SDA (A4) y SCL (A5) del Arduino

Un detalle de depuración que ahorra horas: si cargas el código y la pantalla queda en blanco o muestra solo rectángulos, casi siempre es una de dos cosas. O la dirección I2C del módulo no es 0x27 (algunos vienen en 0x3F), o el potenciómetro azul del adaptador está girado al extremo y hay que ajustar el contraste con un destornillador.

La matemática detrás del cálculo

Acá está el corazón del proyecto. Para contar los días entre dos fechas sin armar un calendario completo, el truco es usar la duración del año tropical: el tiempo que tarda la Tierra en dar una vuelta completa alrededor del Sol, que son 365,242189 días. Ese decimal es el que absorbe los años bisiestos de forma estadística, sin tener que preguntarse si un año puntual tuvo 28 o 29 de febrero.

La fórmula que usa el programa toma la diferencia de años, le suma la diferencia de días y reparte la diferencia de meses como fracciones del año:

C++
total = ((anosh-anosc)*(365.242189)) + ((diah-diac) + ((mesh-mesc)*(365.242189/12)));

Donde diac, mesc y anosc son el día, mes y año de cumpleaños (tu nacimiento) y diah, mesh, anosh son la fecha de hoy. El resultado es una aproximación muy cercana al conteo real de días.

Vale la pena entender una sutileza: total está declarado como int, así que aunque la fórmula usa decimales, el valor final se trunca a un número entero de días (se descarta la parte decimal). Para una calculadora de días vividos es perfecto, pero si más adelante quieres precisión al día exacto, conviene migrar a una librería de tiempo real como TimeLib.

El programa completo

El sketch está escrito de forma deliberadamente larga y repetitiva: en lugar de comprimir la lógica, el autor original separó cada dígito en su propio bloque switch para que se entienda paso a paso cómo se construye cada número. Es código de aprendizaje, no de producción, y se agradece para entender el flujo.

Antes de cargarlo, instala desde el gestor de librerías del IDE de Arduino la librería Keypad (para el teclado) y una librería LiquidCrystal I2C compatible con tu módulo. El código completo y comentado es este:

C++
///////////////////¿Cuantos días has vivido?
/*
Programa para calcular los dias transcurridos de una fecha determinada a otra.
Materiales:
-Teclado Matrical 4x4
-Display LCD 16x2 con Modulo Serial I2C
-Placa Arduino 

Aunque este código puede ser reducido, en este caso esta escrito
de tal forma que se puedan identificar facilmente los pasos que
se siguieron para llegar al resultado final. La formula que se utilizó 
para determinar la cantidad de días transcurridos toma en cuenta los 
años bisietos y otras variantes. Recuerda descargar las librerias Keypad 
y Liquid Crystal para Modulo serial I2C.
*/
#include <Keypad.h>
#include <Wire.h>                 
#include <LiquidCrystal_I2C.h>    
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
const byte ROWS = 4; 
const byte COLS = 4; 
char keys[ROWS][COLS] = {
 {'1','2','3','A'},
 {'4','5','6','B'},
 {'7','8','9','C'},
 {'*','0','#','D'}
};
byte rowPins[ROWS] = {2,3,4,5}; //Filas
byte colPins[COLS] = {6,7,8,9}; //Columnas
Keypad keypad = Keypad( makeKeymap(keys), rowPins, 
colPins, ROWS, COLS );
int val=0;//Valor de referencia
int cuadro= 1023;// El numero 1023 dibuja un cuadro en el LCD
//////////////Bases para el calculo
int diah= 0;// Dia de hoy
int mesh= 0;//Mes de Hoy
int anosh= 0;//Año de hoy
int diac= 0;//Dia de cumple
int mesc= 0;//Mes de cumple
int anosc= 0;//Año de cumple
int anosvividos= 0;//Años vividos
int total= 0;//Total de dias vividos
///////////////////////////////////////////////////////////////////////////////VOID SETUP
void setup(){    
lcd.begin(16,2);//Arranca LCD
}
///////////////////////////////////////////////////////////////////////////////VOID LOOP
void loop(){
char key = keypad.getKey();
////////////////////////////Inicio
if (val == 0){//si val es igual a 0 entonces..
lcd.setCursor(1,0);             
lcd.print("Oprime A para");
lcd.setCursor(4,1);            
lcd.print("iniciar");
}
//////////////////////////////////BORRAR FECHA
if(key && val==1 | val==2 |val==3 | val==4 | val==5 |val==6 | val==7 | val==8 | val==9) {//Si se oprima la tecla C y val esta en alguno de los valores del 1 al 9 entonces..
switch (key)
{
case 'C':
val= 1;
diah=0;
mesh=0;
anosh=0;
lcd.clear();
lcd.setCursor(1,0);           
lcd.print("Fecha de hoy:");
lcd.setCursor(2,1);            
lcd.print("dd/mm/aaaa");
break;
}
}
//////////////////////////////////INGRESA FECHA DE HOY
if(key && val==0) {//Si val es igual a 0 entonces..
switch (key)
{
case 'A'://Al oprimir la letra A el display escribe..
val= 1;//val cambia a 1
lcd.clear();
lcd.setCursor(2,0);           
lcd.print("Fecha de hoy:");
lcd.setCursor(2,1);            
lcd.print("dd/mm/aaaa");
break;
}
}
//////////////////////////////////PRIMER NUMERO DIAH
if(key && val==1) {//Si val es 1 entonces..
 switch (key)
{
case '0'://al escribir el numero 0
lcd.setCursor(2,1);            
lcd.print(key);//El display escribe el numero que se oprimio
val= 2;//el valor cambia a 2
diah=diah+0;// se suman 0 dias a los dias
break;
case '1':
lcd.setCursor(2,1);            
lcd.print(key);
val= 2;
diah=diah+10;
break;
case '2':
lcd.setCursor(2,1);            
lcd.print(key);
val= 2;
diah=diah+20;
break;
case '3':
lcd.setCursor(2,1);            
lcd.print(key);
val= 2;
diah=diah+30;
break;
}
}
//////////////////////////////////////SEGUNDO NUMERO DIAH
else if(key && val==2) {
switch (key)
{
case '0':
val= 3;
diah=diah+0;
lcd.setCursor(3,1);           
lcd.print(key);
break;
case '1':
val= 3;
diah=diah+1;
lcd.setCursor(3,1);           
lcd.print(key);
break;
case '2':
val= 3;
diah=diah+2;
lcd.setCursor(3,1);           
lcd.print(key);
break;
case '3':
val= 3;
diah=diah+3;
lcd.setCursor(3,1);           
lcd.print(key);
break;
case '4':
val= 3;
diah=diah+4;
lcd.setCursor(3,1);           
lcd.print(key);
break;
case '5':
val= 3;
diah=diah+5;
lcd.setCursor(3,1);           
lcd.print(key);
break;
case '6':
val= 3;
diah=diah+6;
lcd.setCursor(3,1);           
lcd.print(key);
break;
case '7':
val= 3;
diah=diah+7;
lcd.setCursor(3,1);           
lcd.print(key);
break;
case '8':
val= 3;
diah=diah+8;
lcd.setCursor(3,1);           
lcd.print(key);
break;
case '9':
val= 3;
diah=diah+9;
lcd.setCursor(3,1);           
lcd.print(key);
break;
}
}
//////////////////////////////////PRIMER NUMERO MESH
else if(key && val==3) {
switch (key)
{
case '0':
val= 4;
lcd.setCursor(5,1);           
lcd.print(key);
break;
case '1':
val= 4;
mesh=mesh+10;
lcd.setCursor(5,1);           
lcd.print(key);
break;
}
}
//////////////////////////////////SEGUNDO NUMERO MESH
else if(key && val==4) {
switch (key)
{
case '0':
val= 5;
mesh= mesh+0;
lcd.setCursor(6,1);           
lcd.print(key);
break;
case '1':
val= 5;
mesh= mesh+1;
lcd.setCursor(6,1);           
lcd.print(key);
break;
case '2':
val= 5;
mesh= mesh+2;
lcd.setCursor(6,1);           
lcd.print(key);
break;
case '3':
val= 5;
mesh= mesh+3;
lcd.setCursor(6,1);           
lcd.print(key);
break;
case '4':
val= 5;
mesh= mesh+4;
lcd.setCursor(6,1);           
lcd.print(key);
break;
case '5':
val= 5;
mesh= mesh+5;
lcd.setCursor(6,1);           
lcd.print(key);
break;
case '6':
val= 5;
mesh= mesh+6;
lcd.setCursor(6,1);           
lcd.print(key);
break;
case '7':
val= 5;
mesh= mesh+7;
lcd.setCursor(6,1);           
lcd.print(key);
break;
case '8':
val= 5;
mesh= mesh+8;
lcd.setCursor(6,1);           
lcd.print(key);
break;
case '9':
val= 5;
mesh= mesh+9;
lcd.setCursor(6,1);           
lcd.print(key);
break;
}
}
//////////////////////////////////PRIMER NUMERO AÑO
else if(key && val==5) {
switch (key)
{
case '1':
val= 6;
anosh= anosh+1000;
lcd.setCursor(8,1);           
lcd.print(key);
break;
case '2':
val= 6;
anosh= anosh+2000;
lcd.setCursor(8,1);           
lcd.print(key);
break;
}
}
//////////////////////////////////SEGUNDO NUMERO AÑOH
else if(key && val==6) {
switch (key)
{
case '0':
val= 7;
lcd.setCursor(9,1);           
lcd.print(key);
break;
case '9':
val= 7;
anosh=anosh+900;
lcd.setCursor(9,1);           
lcd.print(key);
break;
}
}
//////////////////////////////////TERCER NUMERO AÑOH
else if(key && val==7) {
switch (key)
{
case '0':
val= 8;
lcd.setCursor(10,1);           
lcd.print(key);
break;
case '1':
val= 8;
anosh=anosh+10;
lcd.setCursor(10,1);           
lcd.print(key);
break;
case '2':
val= 8;
anosh=anosh+20;
lcd.setCursor(10,1);           
lcd.print(key);
break;
case '3':
val= 8;
anosh=anosh+30;
lcd.setCursor(10,1);           
lcd.print(key);
break;
case '4':
val= 8;
anosh=anosh+40;
lcd.setCursor(10,1);           
lcd.print(key);
break;
case '5':
val= 8;
anosh=anosh+50;
lcd.setCursor(10,1);           
lcd.print(key);
break;
case '6':
val= 8;
anosh=anosh+60;
lcd.setCursor(10,1);           
lcd.print(key);
break;
case '7':
val= 8;
anosh=anosh+45;
lcd.setCursor(10,1);           
lcd.print(key);
break;
case '8':
val= 8;
anosh=anosh+80;
lcd.setCursor(10,1);           
lcd.print(key);
break;
case '9':
val= 8;
anosh=anosh+90;
lcd.setCursor(10,1);           
lcd.print(key);
break;
}
}
//////////////////////////////////CUARTO NUMERO AÑOH
else if(key && val==8) {
switch (key)
{
case '0':
val= 9;
lcd.setCursor(11,1);           
lcd.print(key);
break;
case '1':
val= 9;
anosh=anosh+1;
lcd.setCursor(11,1);           
lcd.print(key);
break;
case '2':
val= 9;
anosh=anosh+2;
lcd.setCursor(11,1);           
lcd.print(key);
break;
case '3':
val= 9;
anosh=anosh+3;
lcd.setCursor(11,1);           
lcd.print(key);
break;
case '4':
val= 9;
anosh=anosh+4;
lcd.setCursor(11,1);           
lcd.print(key);
break;
case '5':
val= 9;
anosh=anosh+5;
lcd.setCursor(11,1);           
lcd.print(key);
break;
case '6':
val= 9;
anosh=anosh+6;
lcd.setCursor(11,1);           
lcd.print(key);
break;
case '7':
val= 9;
anosh=anosh+7;
lcd.setCursor(11,1);           
lcd.print(key);
break;
case '8':
val= 9;
anosh=anosh+8;
lcd.setCursor(11,1);           
lcd.print(key);
break;
case '9':
val= 9;
anosh=anosh+9;
lcd.setCursor(11,1);           
lcd.print(key);
break;
}
}
//////////////////////////////////BORRAR FECHA DE NACIMIENTO
if(key && val==10 | val==11 |val==12 | val==13 | val==14 |val==15 | val==16 | val==17 | val==18) {
switch (key)
{
case 'C':
val= 10;
diac=0;
mesc=0;
anosc=0;
lcd.clear();
lcd.setCursor(2,0);           
lcd.print("Nacimiento:");
lcd.setCursor(2,1);            
lcd.print("dd/mm/aaaa");
break;
}
}
//////////////////////////////////INGRESA FECHA DE NACIMIENTO////////////////////////////////
if(key && val==9) {
switch (key)
{
case 'B':
val= 10;
lcd.clear();
lcd.setCursor(2,0);           
lcd.print("Nacimiento:");
lcd.setCursor(2,1);            
lcd.print("dd/mm/aaaa");
break;
}
}
//////////////////////////////////PRIMER NUMERO DIAC
if(key && val==10) {
 switch (key)
{
case '0':
lcd.setCursor(2,1);            
lcd.print(key);
val= 11;
diac=diac+0;
break;
case '1':
lcd.setCursor(2,1);            
lcd.print(key);
val= 11;
diac=diac+10;
break;
case '2':
lcd.setCursor(2,1);            
lcd.print(key);
val= 11;
diac=diac+20;
break;
case '3':
lcd.setCursor(2,1);            
lcd.print(key);
val= 11;
diac=diac+30;
break;
}
}
//////////////////////////////////////SEGUNDO NUMERO DIAC
else if(key && val==11) {
switch (key)
{
case '0':
val= 12;
diac=diac+0;
lcd.setCursor(3,1);           
lcd.print(key);
break;
case '1':
val= 12;
diac=diac+1;
lcd.setCursor(3,1);           
lcd.print(key);
break;
case '2':
val= 12;
diac=diac+2;
lcd.setCursor(3,1);           
lcd.print(key);
break;
case '3':
val= 12;
diac=diac+3;
lcd.setCursor(3,1);           
lcd.print(key);
break;
case '4':
val= 12;
diac=diac+4;
lcd.setCursor(3,1);           
lcd.print(key);
break;
case '5':
val= 12;
diac=diac+5;
lcd.setCursor(3,1);           
lcd.print(key);
break;
case '6':
val= 12;
diac=diac+6;
lcd.setCursor(3,1);           
lcd.print(key);
break;
case '7':
val= 12;
diac=diac+7;
lcd.setCursor(3,1);           
lcd.print(key);
break;
case '8':
val= 12;
diac=diac+8;
lcd.setCursor(3,1);           
lcd.print(key);
break;
case '9':
val= 12;
diac=diac+9;
lcd.setCursor(3,1);           
lcd.print(key);
break;
}
}
//////////////////////////////////PRIMER NUMERO MESC
else if(key && val==12) {
switch (key)
{
case '0':
val= 13;
lcd.setCursor(5,1);           
lcd.print(key);
break;
case '1':
val= 13;
mesc=mesc+10;
lcd.setCursor(5,1);           
lcd.print(key);
break;
}
}
//////////////////////////////////SEGUNDO NUMERO MESC
else if(key && val==13) {
switch (key)
{
case '0':
val= 14;
mesc= mesc+0;
lcd.setCursor(6,1);           
lcd.print(key);
break;
case '1':
val= 14;
mesc= mesc+1;
lcd.setCursor(6,1);           
lcd.print(key);
break;
case '2':
val= 14;
mesc= mesc+2;
lcd.setCursor(6,1);           
lcd.print(key);
break;
case '3':
val= 14;
mesc= mesc+3;
lcd.setCursor(6,1);           
lcd.print(key);
break;
case '4':
val= 14;
mesc= mesc+4;
lcd.setCursor(6,1);           
lcd.print(key);
break;
case '5':
val= 14;
mesc= mesc+5;
lcd.setCursor(6,1);           
lcd.print(key);
break;
case '6':
val= 14;
mesc= mesc+6;
lcd.setCursor(6,1);           
lcd.print(key);
break;
case '7':
val= 14;
mesc= mesc+7;
lcd.setCursor(6,1);           
lcd.print(key);
break;
case '8':
val= 14;
mesc= mesc+8;
lcd.setCursor(6,1);           
lcd.print(key);
break;
case '9':
val= 14;
mesc= mesc+9;
lcd.setCursor(6,1);           
lcd.print(key);
break;
}
}
//////////////////////////////////PRIMER NUMERO AÑOC
else if(key && val==14) {
switch (key)
{
case '1':
val= 15;
anosc= anosc+1000;
lcd.setCursor(8,1);           
lcd.print(key);
break;
case '2':
val= 15;
anosc= anosc+2000;
lcd.setCursor(8,1);           
lcd.print(key);
break;
}
}
//////////////////////////////////SEGUNDO NUMERO AÑOC
else if(key && val==15) {
switch (key)
{
case '0':
val= 16;
lcd.setCursor(9,1);           
lcd.print(key);
break;
case '9':
val= 16;
anosc=anosc+900;
lcd.setCursor(9,1);           
lcd.print(key);
break;
}
}
//////////////////////////////////TERCER NUMERO AÑOC
else if(key && val==16) {
switch (key)
{
case '0':
val= 17;
lcd.setCursor(10,1);           
lcd.print(key);
break;
case '1':
val= 17;
anosc=anosc+10;
lcd.setCursor(10,1);           
lcd.print(key);
break;
case '2':
val= 17;
anosc=anosc+20;
lcd.setCursor(10,1);           
lcd.print(key);
break;
case '3':
val= 17;
anosc=anosc+30;
lcd.setCursor(10,1);           
lcd.print(key);
break;
case '4':
val= 17;
anosc=anosc+40;
lcd.setCursor(10,1);           
lcd.print(key);
break;
case '5':
val= 17;
anosc=anosc+50;
lcd.setCursor(10,1);           
lcd.print(key);
break;
case '6':
val= 17;
anosc=anosc+60;
lcd.setCursor(10,1);           
lcd.print(key);
break;
case '7':
val= 17;
anosc=anosc+45;
lcd.setCursor(10,1);           
lcd.print(key);
break;
case '8':
val= 17;
anosc=anosc+80;
lcd.setCursor(10,1);           
lcd.print(key);
break;
case '9':
val= 17;
anosc=anosc+90;
lcd.setCursor(10,1);           
lcd.print(key);
break;
}
}
//////////////////////////////////CUARTO NUMERO AÑOC
else if(key && val==17) {
switch (key)
{
case '0':
val= 18;
lcd.setCursor(11,1);           
lcd.print(key);
break;
case '1':
val= 18;
anosc=anosc+1;
lcd.setCursor(11,1);           
lcd.print(key);
break;
case '2':
val= 18;
anosc=anosc+2;
lcd.setCursor(11,1);           
lcd.print(key);
break;
case '3':
val= 18;
anosc=anosc+3;
lcd.setCursor(11,1);           
lcd.print(key);
break;
case '4':
val= 18;
anosc=anosc+4;
lcd.setCursor(11,1);           
lcd.print(key);
break;
case '5':
val= 18;
anosc=anosc+5;
lcd.setCursor(11,1);           
lcd.print(key);
break;
case '6':
val= 18;
anosc=anosc+6;
lcd.setCursor(11,1);           
lcd.print(key);
break;
case '7':
val= 18;
anosc=anosc+7;
lcd.setCursor(11,1);           
lcd.print(key);
break;
case '8':
val= 18;
anosc=anosc+8;
lcd.setCursor(11,1);           
lcd.print(key);
break;
case '9':
val= 18;
anosc=anosc+9;
lcd.setCursor(11,1);           
lcd.print(key);
break;
}
}
//////////////////////////////////CALCULANDO
else if(key && val==18) {
switch (key)
{
case 'B':
val= 20;
lcd.clear();
lcd.setCursor(2,0);           
lcd.print("Calculando...");
lcd.setCursor(0,1);           
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.clear();
lcd.setCursor(2,0);           
lcd.print("Calculando...");
lcd.setCursor(0,1);           
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.clear();
lcd.setCursor(2,0);           
lcd.print("Calculando...");
lcd.setCursor(0,1);           
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
lcd.write(cuadro);
delay (45);
break;
}
}
//////////////////////////////////Calculo
total=((anosh-anosc)*(365.242189))+((diah-diac)+((mesh-mesc)*(365.242189/12)));// Formula par determinar los dias 
anosvividos=anosh-anosc;
//////////////////////////////////USTED HA VIVIDO
if(val==20 && anosvividos <=89) {//Si los años vividos son menos que 89 y val es igual a 20 entonces...
val= 21;
lcd.clear();
lcd.setCursor(0,0);           
lcd.print("Usted ha vivido:");
lcd.setCursor(2,1);           
lcd.print(total);
lcd.setCursor(9,1);           
lcd.write("dias");
}

else if (val==20){// De lo contrarios, es decir si los años ingresados son mayores que 89 entonces..
val= 21;
lcd.clear();
lcd.setCursor(1,0);           
lcd.print("Usted deberia");
lcd.setCursor(1,1);           
lcd.write("estar muerto");
}

//////////////////////////////////RESET
if(key) {//Volvemos a poner todos los valores en 0 para que inicie de nuevo
switch (key)
{
case '*':
lcd.clear();
diah= 0;
mesh= 0;
anosh= 0;
diac= 0;
mesc= 0;
anosc= 0;
anosvividos= 0;
total= 0;
val= 0;
break;
}
}
//////////////////////////////////FIN
}
//ElectroCrea.com

Cómo se usa

El programa funciona como una máquina de estados guiada por cuatro teclas de control. La pantalla te va indicando qué hacer en cada momento:

  • A: inicia el programa y te pide la fecha de hoy.
  • B: confirma un paso y avanza al siguiente (primero la fecha de hoy, después la de nacimiento, y por último dispara el cálculo).
  • C: borra la fecha que estás ingresando para repetir el paso si te equivocaste.
  • *: reinicia todo el programa desde cero.

El flujo es: aprietas A, escribes la fecha de hoy en formato dd/mm/aaaa, aprietas B, escribes tu fecha de nacimiento, aprietas B de nuevo y la pantalla muestra una animación de "Calculando..." antes de mostrarte el total de días que llevas vivo. Como curiosidad, el código tiene un guiño de humor: si ingresas una edad mayor a 89 años, en vez del resultado te dice que "deberías estar muerto".

Variantes y mejoras

Una vez que tengas la versión base andando, hay varias formas de subir el nivel del proyecto:

  • Reloj automático con RTC: en lugar de teclear la fecha de hoy cada vez, agrega un módulo RTC DS1307 o DS3231. Comparten el mismo bus I2C que la pantalla, así que solo conectas SDA y SCL en paralelo y el aparato siempre sabe el día actual sin que lo ingreses.
  • Más métricas en la pantalla: con el total de días ya calculado puedes mostrar también las horas vividas (multiplicando por 24) o las semanas, rotando la información en la LCD cada par de segundos.
  • Versión sin teclado: si quieres un proyecto de escritorio fijo, reemplaza el teclado por dos potenciómetros o un encoder rotatorio para seleccionar la fecha, y libera los pines digitales.
  • Alerta de cumpleaños: combinando el RTC con un buzzer, puedes hacer que el aparato suene cuando diah y mesh coincidan con tu fecha de nacimiento.

Personalización para Chile

El tutorial original es de una tienda mexicana, pero todo el hardware lo consigues en Chile en MechatronicStore con stock local:

  • Placa Arduino Uno R3 (SKU X4-8): la placa base del proyecto.
  • Teclera keypad tipo membrana 4x4 (SKU G-303): el teclado matricial de 16 teclas que usa el código tal cual.
  • Pantalla LCD1602 16x2 con I2C incorporado: trae la pantalla y el adaptador I2C ya integrados, así te ahorras soldar el módulo por separado.
  • Módulo I2C para LCD (SKU D-108): si ya tienes una LCD 16x2 "pelada", este es el adaptador serial que la convierte al bus I2C de 2 pines.

Donde el original menciona una "Caja para proyecto Steren" o un "DC hembra con rosca", cualquier caja de proyecto y conector de alimentación equivalente cumplen la misma función para dejar el armado portátil.

Recursos

Versión chilena, inspirada en el proyecto original de ElectroCrea, con componentes en stock local en MechatronicStore.