Enviar datos al monitor serial con SD

CaleBit:
A "congelarse", me refiero aque al detectar el pulso del primer botón (Llamemosle botón mostrar contacto), este me muestre en el monitor (eso ya esta), el registro y también en la lcd (ya está), solo que la lcd dejaría los valores en la pantalla hasta que el botón2 limpiará y nos volviera al Demo.

¿Y en el caso de presionar "botón mostrar contacto" dos veces consecutivas? ¿Actualiza la pantalla o no ocurre nada la segunda vez?

El botónMostrar contacto solo ira mostrando los registros, el botónLimpiar lcd solo nos borrará el registro mostrado y nos llevará de nuevo a la demo.

Si se presionará el botón mostrar contacto dos veces consecutivas, lo que pasaría es que me mostraría un contacto y al volver a presionar el siguiente contacto, solo eso haría este botón, Aunque no se pulse el botón limpiar lcd y el registro aun este en pantalla, el botón mostrar contacto me seguiría mostrando el siguiente registro.

Bueno. Debo decir, entonces, que bien no he entendido hasta ahora lo que querías hacer, o bien han ido cambiando los objetivos. Lo que yo estaba intentando hacer era que al pulsar botón de mostrar contacto, inmediatamente lo mostrara por un tiempo (cinco segundos, creo) y tras ese tiempo continuara con la demo; excepto que se hubiera producido nueva pulsación durante ese tiempo, que encadenaría el siguiente registro otros cinco segundos, etc. Vamos; una especie de buffer de pulsación. Esa temporización de la muestra de los registros, creo que precisamente complicaba un poco el código.

Así es noter pido mil disculpas, lo he ido adecuando un poco para que sea 100% funcional, pero me gustaría que quedará así como lo he explicado ahora.

2 botones una muestra un contacto, y lo deja en pantalla de forma indeterminada, hasta que el segundo boton limpia pantalla y nos vuelve a la demo.

El botón uno de mostrar contacto, solo mostrará registros, y el otro botón solo borrará ese registro de pantalla y nos volverá al demo. Bueno si es posible.

Ya lo capto...

La sección del demo sigue siendo necesario hacerlo con máquina de estados; eso que acabas de mencionar se hace con if y while. Nada de interrupciones entonces...
Sería importante que separas ambas secciones en funciones aparte:

void loop() {
  if (!digitalRead(2)) contacto();
  else demo();
}

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.

noter:
Sin embargo ese loop y separación en dos funciones creo que ayuda mucho a comprender el código.

De ahí que usara el término "mantenibilidad".
Si el código a futuro se quiere adaptar/mejorar/corregir, siempre es buena práctica separar funciones específicas de todo el programa (al menos las de más de 10 líneas o procedimientos que se repiten exactamente igual por tres o más veces), mantener la indentación correcta; pero sobre todo, que visualmente sea fácil de leer. Puede estar acompañado de uno que otro comentario que explique puntos complicados en el código; pero no abusar de ellos ya que a la vez, ese código debería ser auto-explicativo.

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.

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...

Acabo de probar el código y me esta dando problema el delay que le puse al inicio del loop(2000), si no lo pongo corre muy rápido y no se alcanza a ver nada.

Pienso que por eso no me esta detectado los pulsos, me alcanzo a leer uno y también lo pude borrar como se deseaba pero fue uno en 10 pulsaciones que hice.

La acotación que me hiciste acerca del nombre con que abro el archivo de la sd, ya lo cambie a Datos, solo que no lo edite en el código que envié.

No debe haber ningún delay en el loop. Si está corriendo muy rápido sin él, es que tenemos algo mal.
Creo que ahora sería bueno que pongas el código que tienes actualmente, lo que intentas conseguir y lo que está fallando, y así apuntaremos mejor las correcciones.

Básicamente es lo que hemos estado manejando con las correcciones que me han dicho. 

Code: [Select]
#include <EEPROM.h>
#include <Software. Serial.h>
#include <SD.h>
#include <LiquidCrystal.I2C.h>
#include <Wire.h>
#include <Adafruit. Thermal>

LiquidCrystal _I2C lcd(0x27 2,1,0,4,5,6,7,3, POSITIVE);
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
int TX_PIN=6;
int RX_PIN=5;

SoftwareSerial Thermal (RX_PIN, TX_PIN) ;



void setup() {

  pinMode (Salir, INPUT_PULLUP);
  pinMode(Coin, INPUT_PULLUP);

  lcd.begin(16, 2);
  Serial.begin (9600);
  Thermal. 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 ("Datos.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);
      Serial. read ();
      Thermal.print (nom);  //No he podido imprimir aún. 
      Thermal.print (tel);
      lcd.clear();
      lcd.print (nom);
      lcd.setCursor (0, 1);
      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");
  }
}

El loop esta corriendo muy rápido, agregue el software Serial para comenzar a imprimir pero no he podido imprimir algo aun, guardar el último registro en la EEPROM para que al volver a prender me de el siguiente registro, y no me regresé al primero de nuevo y lo que se comento ayer del botónSalir, que borrará el registro que se mantendría en la lcd indefinidamente, al leer el botón de mostrar contacto.

Bueno. Veo algunas cosas un poco raras, como nombres de librerías con espacios en medio, pero si te compila, supongo que tú lo tienes bien.
De momento, la alta velocidad de la demo está producida porque falta un paso importante, justo tras el cierre de llaves del switch/case, que es poner el comienzo del nuevo cronometraje en millis_inicio (pongo sólo el fragmento en el que tienes que agregarlo):

      break;
      // caso 8 igual que 2 y 5
    }
    millis_inicio=millis();
    sigFase++;  // siguiente fase
    if (sigFase > 7) sigFase=0; // si hemos pasado de la 7, rebobinamos

Con eso, cada fase debería durar lo que se establezca en cada momento en millis_espera.

Así es noter faltaba eso.

Te la sabes bro :slight_smile: Gracias mil.

Bueno. Ataquemos el tema de la EEPROM. Hay que añadir tres modificaciones, aparte de incluir la librería en si:

Agregar una variable global donde guardar la posición del siguiente registro:

char nom[17]; // buffer de almacenamiento temporal
char tel[17]; // buffer de almacenamiento temporal
unsigned long regActual; // posición de lectura del archivo

En el setup, leeremos la dirección 0 de la EEPROM y, si el dato es "cabal" (la primera vez será FFFFFFFF) entenderemos que es posición guardada de un registro.

  if (myFile) {
    lcd.print ("NOMBRE:");
    lcd.setCursor (0, 1);
    lcd.print ("TEL:");
    EEPROM.get(0, regActual); 
    if (regActual<myFile.size) { // Si la posición de lectura es menor que el tamaño de archivo
      myFile.seek(regActual); // apuntamos el File hacia dicha dirección
    }
  } else lcd.print ("No se pudo abrir");

Finalmente, cuando se muestra un registro, podemos guardar en la EEPROM la posición siguiente a leer:

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");
    }
    // TRAS HABER LEIDO REGISTRO, GUARDAMOS LA SIGUIENTE POSICIÓN DE LECTURA DE ARCHIVO
    EEPROM.put(0, myFile.position());
  } else {
    lcd.clear();
    lcd.print ("ERROR: no hay SD");
    lcd.setCursor (0, 1);
    lcd.print ("o archivo no exs");
  }
}

Listo gracias, solo tuve que agregar unos paréntesis en el if (regActual<myFile. size()){

Porque me estaba dando problemas al compilar.

Cierto. Se me pasó el detalle, porque lo hice "a ojo"; pero bueno. Así te vas curtiendo en la ardua labor de encontrar los errores de compilación.
Lo importante es que estás más cerca. ¿Entiendo que lo que llevas hecho te funciona correctamente todo?

Así es Brother, gracias por tu enorme ayuda...

Y si tal vez algún día llegue a ser como tú jajaja(ojala).

Solo queda la impresión, y listo a probarlo completamente.

Eres bueno como maestro, deberías dedicarte a la pedagogía Brother...

Gracias Serafín

Bueno. Me alegro doblemente si, además de ir superando obstáculos, estás aprendiendo en el camino. Esa es la finalidad que persigue este foro, creo yo.
Lo de la impresión, ya irás comentando si te da problemas.

Si amigo, gracias a ustedes.

Si ahorita estoy viendo si es la impresora la que no jala, o soy yo porque ya hice la conexión según el manual y no me ha impreso la prueba que debería hacer al tocar el botón de la impresora, pero voy a preguntar al proveedor para ver que podría ser.

Si y ya les iré comentando como va.

Gracias Serafín.