noter:
Jugada inteligente, Lucario. Por un momento me estaba temiendo que ibas a atacar con clases y objetos, lo que sería un poco precipitado para el nivel de CaleBit. Sin embargo ese loop y separación en dos funciones creo que ayuda mucho a comprender el código.
A ver si podemos sacar un ratillo y desarrollamos sobre esa idea.
Si gracias Lucario y noter todavía estoy verdeson, al parecer se han vuelto mis mentores.
Estoy dispuesto a ser moldeado por sus conocimientos. Unos cursos estarían bien ¿No?
noter:
Bueno. A ver si ahora se aproxima a lo que buscas. Los pines para mostrar siguiente registro y para retornar a demo son el 2 y 3 respectivamente.
#include <SD.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(10, 9, 8, 7, 6, 5);
File myFile;
const byte chipSelect = 4;
const byte Coin = 2; // pin siguiente registro
const byte Salir = 3; // tomaré este pin como el de salir a demo
unsigned long millis_inicio=0, millis_espera=0;
bool demo=true; // si estamos en modo demo (o mostrando registro)
int sigFase=0; // siguiente fase de la demo a ejecutar
bool estadoAnteriorSalir = LOW; // guardado del último estado de los botones...
bool estadoAnteriorMostrar = LOW; // ...para saber si cambió el estado
char nom[17]; // buffer de almacenamiento temporal
char tel[17]; // buffer de almacenamiento temporal
void setup() {
pinMode (Salir, INPUT_PULLUP);
pinMode(Coin, INPUT_PULLUP);
lcd.begin(16, 2);
Serial.begin (9600);
lcd.print (" COMPROBANDO");
delay(1000);
lcd.setCursor (0, 1);
lcd.print (" HARDWARE...");
delay (5000);
lcd.clear ();
delay (1000);
Serial.println ("Inicializando SD card...");
pinMode (chipSelect, OUTPUT);
lcd.print ("Inicializando SD");
delay (2000);
lcd.clear();
if (!SD.begin(chipSelect)) {
Serial.println ("Fallo lectura de tarjeta SD");
lcd.print("ERROR al iniciar SD");
delay (1000);
lcd.setCursor (0, 1);
lcd.print ("Inserta la SD");
delay (5000);
lcd.clear ();
delay (1000);
return;
}
Serial.println ("SD inicializada correctamente");
lcd.setCursor (0, 0);
lcd.print("BOOT exitoso...");
delay (2000);
lcd.clear ();
lcd.print(" Bienvenidos a: ");
delay(2000);
lcd.setCursor(0, 1);
lcd.print("ARDUINO");
delay(7000);
lcd.clear();
delay(1000);
lcd.print(" APRENDE");
delay(1000);
lcd.setCursor(0, 0);
lcd.setCursor(0, 1);
lcd.print("CADA DIA");
delay(7000);
lcd.clear();
delay(1000);
lcd.print("NO ESPERES MAS");
delay(2000);
lcd.setCursor(0, 1);
lcd.print("!!!!!!");
delay(5000);
lcd.clear();
delay(900);
myFile = SD.open ("Contactos.txt"); // ¿Seguro que abre con ese nombre? Según mis "cálculos", al ser uno que no cumple con el formato 8.3; se deberá referenciar por "CONTAC~1.TXT"
if (myFile) {
lcd.print ("NOMBRE:");
lcd.setCursor (0, 1);
lcd.print ("TEL:");
} else lcd.print ("No se pudo abrir");
}
void loop() {
if (digitalRead(Coin) != estadoAnteriorMostrar) { // Cambio estado pulsador
estadoAnteriorMostrar = !estadoAnteriorMostrar; // cambiamos el último estado
if (estadoAnteriorMostrar == LOW) { // si el cambio es de no pulsado a pulsado
muestra_registro(); // muestra registro siguiente
demo=false; // salimos de modo demo (quedará registro fijo en pantalla)
}
}
else if (digitalRead(Salir) != estadoAnteriorSalir) { // Lo anterior con el pulsador de salida a demo
estadoAnteriorSalir = !estadoAnteriorSalir;
if (estadoAnteriorSalir == LOW) {
millis_espera=0L; // establecemos espera a cero para que no espere para repintar
demo=true; // cambiamos a modo demo, con lo que en el siguiene paso continuaremos con nuestra demo.
}
}
if (demo) {
muestraDemo(); // si estamos en modo demo entramos en el control de la demo
}
}
void muestraDemo(void) {
if ( (millis() - millis_inicio) >= millis_espera ) { // si ha pasado millis_espera desde la última fase, entramos a fase nueva
switch (sigFase){
case 0:
lcd.clear();
lcd.print("Bienveniddos a:");
millis_espera = 2000;
break;
case 1:
lcd.setCursor(0, 1);
lcd.print("ARDUINO ");
millis_espera = 7000;
break;
case 2: // Aprovechamos para poner todos los casos en los que hay lo mismo (borrado de pantalla y espera 1000)
case 5:
case 8:
lcd.clear();
millis_espera = 1000;
break;
case 3:
lcd.setCursor(0, 0 );
lcd.print("Aprender a");
//millis_espera = 1000; // no es necesrio , porque ya es 1000 desde el case anterior.
break;
case 4:
lcd.setCursor(0, 1 );
lcd.print("Programar");
millis_espera = 7000;
break;
// caso 5 igual que 2
case 6:
lcd.setCursor(0, 0 );
lcd.print("Bienvenidos");
millis_espera = 2000;
break;
case 7:
lcd.setCursor(0, 1 );
lcd.print("¡¡¡Todos!!!");
millis_espera = 5000;
break;
// caso 8 igual que 2 y 5
}
sigFase++; // siguiente fase
if (sigFase > 7) sigFase=0; // si hemos pasado de la 7, rebobinamos
}
}
// muestra el siguiente registro
void muestra_registro(void){
if (myFile) {
if (myFile.available()) {
nom[myFile.readBytesUntil(',', nom, 16)] = '\0';
tel[myFile.readBytesUntil('\n', tel, 16)] = '\0';
Serial.println(nom);
Serial.println(tel);
lcd.clear();
lcd.print ("NOMBRE:");
lcd.print (nom);
lcd.setCursor (0, 1);
lcd.print ("TEL:");
lcd.print (tel);
} else {
Serial.println ("Final del Archivo");
myFile.seek (0L);
lcd.clear ();
lcd.print ("Final del Archivo");
}
} else {
lcd.clear();
lcd.print ("ERROR: no hay SD");
lcd.setCursor (0, 1);
lcd.print ("o archivo no exs");
}
}
No lo he probado, pero no debería estar muy lejos de funcionar como querías. Faltaría cambiar el lcd a i2c y los comandos de impresión.
Ya cambie el lcd a i2c aunque me dio un poco de problemas pero al final quedó, estoy tratando de hacer lo de la EEPROM haber que da aunque lo veo difícil, los comandos de impresión encontré algo como serial. Read y thermal. Print que imprime y bueno otros más para despertarla y ponerla a dormír cuando, termine su trabajo, pero bueno agradezco su ayuda y disculpen sino puedo corresponder como se debe. Probaré ésto...