Enviar datos al monitor serial con SD

Hola a todos agradezco de antemano sus respuestas y orientación.

Estoy a punto de comenzar mi carrera en esto y quisiera involucrarme mas, tengo un arduino uno y también un modulo micro sd, dentro de esta puse un archivo llamado datos. txt y generé algunos datos como por ejemplo;

nombre: Carlos
telefono:5512344321
nombre: Josue
telefono:5544332211

Quisiera agregar aproximadamente 500 datos o mas.

Estos datos quisiera imprimirlos en el monitor serial, y si es posible en mi lcd 16x2 nombre y telefono con sus respectivos datos.

He logrado imprimir toda la lista de datos de la sd, pero no como lo estoy planteando con ustedes.

File myfile=SD.open ("Datos.txt"); 

if (myfile ) {

Serial.println("Datos.txt:");
whyle (myfyle. avaible ()){
Serial.write (myfile. read());
}
myFile. close ();
}else{
Serial. print ("Error al abrir archivo") ;
}
}

Agradecería su ayuda,orientación y si fuere posible un ejemplo ilustrativo para entender mejor.

Gracias.

Lee el privado y edita tu post.

Estos datos quisiera imprimirlos en el monitor serial, pero en par NOMBRE y TELEFONO, por medio de una interrupción que ya tengo declarada y de esta manera leer los datos sucesivamente.

No puedes usar una interrupción para tal tarea.
Ya te van a asesorar con tu problema.

El foro tiene muchas respuestas de este tipo, deberías buscar un poco.

arraba derecha en el buscador: SD registros o SD busqueda

CaleBit:
dentro de esta puse un archivo llamado datos. txt y generé algunos datos como por ejemplo;

nombre: Carlos
telefono:5512344321
nombre: Josue
telefono:5544332211

Quisiera agregar aproximadamente 500 datos o mas.

Estos datos quisiera imprimirlos en el monitor serial, y si es posible en mi lcd 16x2 nombre y telefono con sus respectivos datos.

He logrado imprimir toda la lista de datos de la sd, pero no como lo estoy planteando con ustedes.

No es muy práctico estar repitiendo la descripción de los datos en cada registro, al menos para efectos de recuperación. Sería más fácil guardarlo como CSV en este caso:

Nombre,Telefono
Carlos,5512344321
Josue,5544332211

El formato es fácil de seguir: definimos la cantidad de datos (y la descripción de cada uno) por registro siempre en la primera línea; de ahí en adelante viene la lista de registros almacenados (debe seguir el orden establecido en la primera línea o cabecera).
Nótese que una línea de texto representa un registro, y que los datos de este están separados por comas (,).

En caso de requerir acceso aleatorio, ahí ya deberías considerar implementar registros de longitud fija.

suena a que quieres mostrar un contacto cada que presiones un botón? y cuando lo vuelvas a presionar aparezca el siguiente?

Masticando un poco más la propuesta de Lucario448, suponiendo registros separados en líneas y campos separados por comas, un posible código desde el que partir para la extracción podría ser algo así:

char nom[30]; // buffer de almacenamiento temporal
char tel[30]; // buffer de almacenamiento temporal

while (myFile.available) {
  nom[myfile.readBytesUntil(',', nom, 30)]='\0'; // Cargaría en nom hasta encontrar coma o máximo 30 caracteres. Agregamos terminador de cadena.
  tel[myfile.readBytesUntil('\n', tel, 30)]='\0'; // Cargaría en tel hasta encontrar salto de línea o máximo 30 caracteres. Agregamos terminador de cadena.
  Serial.print("Nombre: ");
  Serial.println(nom);
  Serial.print("Telefono: ");
  Serial.print(tel);
}

Lucario448 No necesito la búsqueda de forma aleatoria, necesito que siga el orden desde el primero hasta el final, pero si que muestre los datos juntos de esta forma:
Nombre:Juan
Teléfono:5544332211 esto es porque
después quiero comprar una impresora que los imprima de esa forma, retomando el comentario de Eduardosanchez así lo tengo contemplado. También tengo en mente cargar más de 500 registros.
Agradezco infinitamente su ayuda y orientación en unos dos meses entraré a la Uni y quisiera no ir en blanco.
Gracias a todos por su ayuda y cooperación.

CaleBit:
pero si que muestre los datos juntos de esta forma:
Nombre:Juan
Teléfono:5544332211

A como lo tenías guardado hace lo mismo.

Formatear los datos en CSV facilita su obtención por separado (véase el ejemplo de noter), por si los necesitaras así para algo en el código. Además me parece que esa era la pregunta, ¿o no?

Así es agradezco infinitamente el tiempo que se toman para contestar, acabo de hacer una prueba y me arroja todavía todos los datos que tengo guardado, como dijo Eduardo tengo un botón que al leer un pulso externo me muestre en el monitor serial y lcd 16x2 si fuera posible solamente un dato.
Nombre:CaleBit
Teléfono:5544332211

Y así sucesivamente, hasta el último. Agradezco tu atención y ayuda Lucario448.

CaleBit:
al leer un pulso externo me muestre en el monitor serial y lcd 16x2 si fuera posible solamente un dato.

Escribir la descripción del dato y este mismo, claramente toma más de 16 caracteres. Para la LCD tienes dos opciones:

Mostrarlo en dos pantallas:

Nombre:
CaleBit
Telefono:
5544332211

Mostrar las descripciones en una pantalla; y luego todos los registros, uno por pantalla:

Nombre:
Telefono:
CaleBit
5544332211
Carlos 
5512344321

Y así sucesivamente...

Ok gracias haré las pruebas. Agradezco su ayuda.

¡Hola a todos!

Antes que nada agradezco su ayuda, colaboración y sobre todo paciencia... He tomado sus consejos y orientaciónes, hice el archivo csv y ordene los datos como me indicaron, pero al final hice un cambio dentro de este para que apareciera completo en la lcd y funcionó, (Hice un archivo txt separandolos por comas), el problema es que al detectar la interrupción me muestra el mismo nombre y teléfono en el monitor y lcd y no hace el salto al siguiente contacto que tengo almacenado en la sd,que aproximadamente quería probarlos con 500 registros.
Adjunto el código que hice a mi alcance.

#include <SPI.h>
#include <SD.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(10, 9, 8, 7, 6, 5);
const int interrupcion =2;
File myFile;
const int chipSelect=4;
char nom[30];
char tel[30];


void setup() {
  lcd.begin(16, 2);
  pinMode(interrupcion,INPUT_PULLUP);
  Serial.begin (9600);

  lcd.begin (16, 2);
  lcd.setCursor (0, 0);
  lcd.print (" COMPROBANDO");
  delay(1000);

  lcd.setCursor (0, 1);
  lcd.print ("   HARDWARE...");
  delay (5000);
  lcd.clear ();
  delay (1000);

  Serial.print ("Inicializando SD card...");
  pinMode (chipSelect, OUTPUT);
  lcd.print ("Inicializando SD");
  delay (2000);
  lcd.clear();

  if (!SD.begin(chipSelect)) {
  Serial.print ("Fallo lectura de tarjeta SD");
  lcd.setCursor (0, 0);
  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.print ("SD inicializada correctamente");
  lcd.setCursor (0, 0);
  lcd.print("BOOT exitoso...");
  delay (2000);
  lcd.clear ();
  myFile = SD.open("Contactos.csv");
  if (myFile) {
    attachInterrupt(digitalPinToInterrupt(interrupcion),Contactos, RISING);
    lcd.setCursor (0, 0);
    lcd.print("Archivo abierto...");
    delay (2000);
    lcd.clear ();    
  }
}

void loop() {


//Estos mensajes estarán mostrándose continuamente mientras no detecte la interrupción
  lcd.print(" Bienvenidos a: ");

  delay(2000);
  lcd.setCursor(0, 0 );

  lcd.setCursor(0, 1);
  lcd.print("ARDUINO ");
  delay(7000);
  lcd.clear();
  delay(1000);

  lcd.print("     Mi");
  delay(1000);
  lcd.setCursor(0, 0);

  lcd.setCursor(0, 1);
  lcd.print("PROYECTO ");
  delay(7000);
  lcd.clear();
  delay(1000);

  lcd.print("Aprendiendo a: ");
  delay(2000);
  lcd.setCursor(0, 0);

  lcd.setCursor(0, 1);
  lcd.print("!!!PROGRAMAR!!!");
  delay(5000);
  lcd.clear();
  delay(900);

    }

 void Contactos()
  
 {
  if (myFile.available()) {
    nom[myFile.readBytesUntil(',', nom, 16)]='\0';
    tel[myFile.readBytesUntil('\n', tel, 16)]='\0';
    Serial.print("NOMBRE:");
    Serial.println(nom);
    Serial.print("TELEFONO:");
    Serial.println(tel);
    lcd.clear ();
    lcd.setCursor (0, 0);
    lcd.print (nom) ;
    lcd.setCursor (0, 1);
    lcd.print (tel);
  } else {

    Serial.print ("Final de archivo") ;
    lcd.setCursor (0, 0);
    lcd.print("Final de archivo");
 } 
}

Hay tanto que decir...

  • No se recomienda usar Serial durante una rutina de interrupción.
  • Al no poder usar delay, mira que prácticamente no puedes mostrar nada.
  • Por lo tanto, una interrupción no es la solución (rima no intencional).

Lo que necesitas hacer es algo llamado "máquina de estados", para poder leer el botón sin atascarse en el "demo". Una pista: requiere aprenderse el uso de millis()
Al momento de mostrar los... ¿contactos?, creo que sí o sí necesitarás los retrasos; o de lo contrario no podrás ver o entender lo que aparece en pantalla. Si todavía necesitas leer la entrada para... digamos que cancelar la acción, tendrás que implementar máquina de estados también (o, ahora sí, usar la interrupción).

Si entiendo, y agradezco su aporte, tal vez la razón de todo esto es que como dije apenas estoy aprendiendo y cuando no hay quien te guíe, cualquier opción puede parecer buena...el hecho es que entiendo el punto pero si pudieran darme un ejemplo lo entendería más.

Con digitalRead hice varias pruebas pero no pude hacer que funcionará como en la interrupción, el código aunque es muy somero me llevó varios días y ahora parece que estoy en ceros nuevamente...necesito hacerlo,entenderlo y procesarlo si hay un buen samaritano viviré eternamente agradecido...Y entiendo que la mayoría de ustedes son pro y tal vez se desesperen con tipos como yo jaja...¡mil disculpas!!

Hola amigos perdón por las molestias, agradezco su ayuda y comentarios. Ayer hice unos cambios que me sugirieron según pude apreciar...Pude imprimir todos los contactos en la lcd y en el monitor de forma continua, supuse que era porque el pin estaba en high, y lo cambie a low en el if, pero ya no me dio ningúna lectura, también cambie el pin 2 a output pero siguió igual sin detectar el pulso. Espero que me puedan seguir ayudando, agradezco infinitamente su paciencia. Gracias

#include <SPI.h>
#include <SD.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(10, 9, 8, 7, 6, 5);
int VO=3;
const int Btn =2;
File myFile;
boolean estado =false;
const int chipSelect=4;
char nom[30];
char tel[30];


void setup() {

analogwrite (VO, 5);
pinMode (Btn, INPUT);

  lcd.begin(16, 2);
  Serial.begin (9600);

  lcd.begin (16, 2);
  lcd.setCursor (0, 0);
  lcd.print (" COMPROBANDO");
  delay(1000);

  lcd.setCursor (0, 1);
  lcd.print ("   HARDWARE...");
  delay (5000);
  lcd.clear ();
  delay (1000);

  Serial.print ("Inicializando SD card...");
  pinMode (chipSelect, OUTPUT);
  lcd.print ("Inicializando SD");
  delay (2000);
  lcd.clear();

  if (!SD.begin(chipSelect)) {
  Serial.print ("Fallo lectura de tarjeta SD");
  lcd.setCursor (0, 0);
  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.print ("SD inicializada correctamente");
  lcd.setCursor (0, 0);
  lcd.print("BOOT exitoso...");
  delay (2000);
  lcd.print(" Bienvenidos a: ");

  delay(2000);
  lcd.setCursor(0, 0 );

  lcd.setCursor(0, 1);
  lcd.print("ARDUINO ");
  delay(7000);
  lcd.clear();
  delay(1000);

  lcd.print("     Mi");
  delay(1000);
  lcd.setCursor(0, 0);

  lcd.setCursor(0, 1);
  lcd.print("PROYECTO ");
  delay(7000);
  lcd.clear();
  delay(1000);

  lcd.print("Aprendiendo a: ");
  delay(2000);
  lcd.setCursor(0, 0);

  lcd.setCursor(0, 1);
  lcd.print("!!!PROGRAMAR!!!");
  delay(5000);
  lcd.clear();
  delay(900);

  myFile = SD.open("Contactos.csv");
  
    lcd.setCursor (0, 0);
    lcd.print("Archivo abierto...");
    
 }

 void loop()
 {
estado =digitalRead (Btn);
If (estado ==HIGH)

  if (myFile.available()) {
    nom[myFile.readBytesUntil(',', nom, 16)]='\0';
    tel[myFile.readBytesUntil('\n', tel, 16)]='\0';
    Serial.print("NOMBRE:");
    Serial.println(nom);
    Serial.print("TELEFONO:");
    Serial.println(tel);
    lcd.clear ();
    lcd.setCursor (0, 0);
    lcd.print (nom) ;
    lcd.setCursor (0, 1);
    lcd.print (tel);
  } else {

    Serial.print ("Final de archivo") ;
    lcd.setCursor (0, 0);
    lcd.print("Final de archivo");
 } 
}

Aquí te lo dejo con algunas correcciones. Mira los comentarios para que puedas aprender lo que está ocurriendo:

#include <SD.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(10, 9, 8, 7, 6, 5);

// Si una constante no lleva un valor superior a 255, preferiblemente debe ser de tipo byte
const byte VO = 3;
const byte Btn = 2;
const byte chipSelect = 4;
char nom[17]; // Se reduce el tamaño a 17 ya que de todos modos está programado para recuperar no más de 16 caracteres
char tel[17];

void setup() {
  pinMode(VO, OUTPUT); // Por la línea siguiente, deduzco que este pin debería ser una salida
  analogwrite (VO, 5); // Dudo que sea la forma adecuada de controlar el contraste; se puede, pero hay que hacer unas configuraciones tanto en hardware como software (código)
  pinMode (Btn, INPUT);

  lcd.begin(16, 2);
  Serial.begin (9600);
  intro(); // Aquí hace lo que restaba del setup
  lcd.print("Esperando boton");
  Serial.println("Esperando boton");
}

void loop()
{
  if (digitalRead(Btn) == HIGH) { // Puedes usar directamente el valor de retorno de digitalRead, sin necesidad de variables intermedias. Es más, se puede hasta omitir el "== HIGH"; tiene el mismo efecto.
    File myFile = SD.open("CONTAC~1.CSV"); // Esta versión de librería no soporta LFN; por lo tanto, creo que "Contactos.csv" se ha truncado a "CONTAC~1.CSV"

    if (myFile) { // ¿Sí se abrió?
      lcd.clear();
      lcd.print("Archivo abierto");
      Serial.println("Archivo abierto");
      while (myFile.available()) { // Por el tipo de retorno de available, puede dar resultados erróneos en archivos mayores a 64 KB
        nom[myFile.readBytesUntil(',', nom, 16)] = '\0'; // Procura que tus entradas no excedan los 16 caracteres; de lo contrario habrían recortes.
        tel[myFile.readBytesUntil('\n', tel, 16)] = '\0'; // Procura que tus entradas no excedan los 16 caracteres; de lo contrario habrían recortes.
        Serial.print("NOMBRE: ");
        Serial.println(nom);
        Serial.print("TELEFONO: ");
        Serial.println(tel);
        lcd.clear(); // El reposicionamiento del cursor a 0,0 se hace implícitamente en esta función
        lcd.print(nom);
        lcd.setCursor(0, 1);
        lcd.print(tel);
        delay(5000); // Esta pausa es la que determinará el tiempo en que el contacto permanecerá en pantalla
      }
      Serial.println("Final de archivo");
      lcd.clear();
      lcd.print("Final de archivo");
      delay(5000);
    } else { // No se abrió
      lcd.clear();
      lcd.print("No se pudo abrir");
      Serial.println("No se pudo abrir el archivo");
      delay(5000);
    }
    lcd.clear();
    lcd.print("Esperando boton");
    Serial.println("Esperando boton");
  }
}

void intro() {
  lcd.print(" COMPROBANDO");
  delay(1000);

  lcd.setCursor (0, 1);
  lcd.print("   HARDWARE...");
  delay (5000);
  lcd.clear(); // El reposicionamiento del cursor a 0,0 se hace implícitamente en esta función
  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.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("     Mi");
  delay(1000);

  lcd.setCursor(0, 1);
  lcd.print("PROYECTO ");
  delay(7000);
  lcd.clear();
  delay(1000);

  lcd.print("Aprendiendo a: ");
  delay(2000);
  lcd.setCursor(0, 1);
  lcd.print("!!!PROGRAMAR!!!");
  delay(5000);
  lcd.clear();
  delay(900);
}

Muchas gracias Lucario 448 por las correcciones y ajustes al código, ahora ha surgido otro problemita y es que estaba lavando mi ropa ja ja (Porque yo la lavo), y me parece que detectó una pequeña alza de voltaje y comenzó a mostrar todos los contactos como si tuviera el botón presionado y también lo probé con el coin que me prestan para estas pruebas, y genera una especie de bucle, estuve investigando un poco y me parece que es el efecto rebote, alguna idea para solucionar esto. Gracias y disculpen tantas molestias.

La cuestión es que creo que el código de Lucario no espera a que toques el botón como querías, sino que muestra los registros separados por una pausa. Para que responda al botón, puedes sustituir el delay del tiempo de muestra en pantalla por un bucle infinito, mientras no se pulse botón (o hacer un delay pequeño y luego el bucle para evitar rebotes).

delay(100);
while (!digitalRead(Btn)); // poniendo punto y coma, cerramos el while

De todas formas, sería conveniente una aclaración de lo que querías obtener, porque creo recordar que buscabas hacer simultáneamente alguna acción más.

Gracias por sus aportaciones y ayuda. Así es noter me parece que no me he dado a entender en ésto, lo que estoy buscando hacer es que los mensajes de bienvenida que tengo en el código estén apareciendo continuamente en un bucle, y que al leer el pulso del coin o botón que pienso que funcionan de la misma manera, me muestre en pantalla un solo registro con un delay de máximo 4 segundos, y desaparezca y siga mostrando los mensajes de bienvenida que tengo en el código.

Al principio lo hice ocupando una interrupción, mientras el bucle estaba mostrando los mensajes de bienvenida, al detectar el pulso del coin o botón (que se me quemó, pero compraré otro), me mostraba un registro en el monitor y en la lcd, el problema aquí era que solo me mostraba uno solo y lo repetía cada vez que leía la interrupción y no hacía el salto al siguiente registro, además, lo mostraba un poco rápido, y volvía de nuevo al bucle, me aconsejaron que esta no era la forma correcta de hacerlo que mejor lo hiciera leyendo el pin con digitalRead y haciendo las pruebas de las correcciones que agradezco infinitamente a Lucario, no espera a que el botón este presionado o que lea el pulso del coin solo lo muestra en un bucle infinito, también probé lo que me pusiste Noter y muestra el bucle mucho más rápido, y no es lo que busco.

Agradezco su ayuda y tiempo, espero me haya dado entender y me puedan ayudar. Mil gracias

Hola he estado leyendo y creo que al fin he comprendido algo de lo que me decía noter, necesito crear un reloj de millis que emule una interrupción de aproximadamente 5 segundos en millis =5000 milisegundos tiempo necesario para mostrar un registro en la LCD, necesito también crear otras variables para conocer el estado del coin (Ya que no he comprado mi botón), estoy haciendo los ejemplos simples de prender y apagar un Led para entenderlo mejor.

Si alguien me puede guiar y ayudar a entender mejor se lo agradeceré.

1-Una primera duda el coin que tengo funciona también como un botón, es decir al entrar una moneda, sería como pulsar un botón?

2- He visto la configuración de este equipo y según yo esta en NC que sería en LOW por eso en la interrupción la tenia en RISSING el flanco de voltaje era de subida.
Pregunta ¿Al poner el cable en pin 2 este espera el pulso para activarse(HIGH)?, o todo el tiempo esta entregando un voltaje porque si es así como podría conocer su estado.

Gracias

Cree nuevas variables aparte de las demás.

const byte Btn=2;
bool EstadoBtn =False ;
MostrarContacto=millis();

Alguien conoce la sintaxis de esta función?

De antemano gracias por su ayuda.

Pónte cómodo, agarra palomitas y refresco que esta respuesta se me ha alargado tanto por acumulación de varias preguntas/respuestas de este hilo.

CaleBit:
Al principio lo hice ocupando una interrupción, mientras el bucle estaba mostrando los mensajes de bienvenida, al detectar el pulso del coin o botón (que se me quemó, pero compraré otro), me mostraba un registro en el monitor y en la lcd, el problema aquí era que solo me mostraba uno solo y lo repetía cada vez que leía la interrupción y no hacía el salto al siguiente registro, además, lo mostraba un poco rápido, y volvía de nuevo al bucle, me aconsejaron que esta no era la forma correcta de hacerlo que mejor lo hiciera leyendo el pin con digitalRead y haciendo las pruebas de las correcciones que agradezco infinitamente a Lucario

De nada.

Aunque de ser así, tendrás que implementar máquina de estados para no quedarte atascado en el "demo" y no detectar el botón a tiempo. La idea era leer un registro por cada pulso, entonces esta rutina no tenía que ser cíclica (cosa que hice en mi sugerencia por la falta de entendimiento), y la variable File debe ser global (o static).

Las rutinas de interrupción realmente no se crean para "repentinamente" cambiar el flujo de ejecución del programa principal, sino para atender tareas cortas pero que tienen prioridad de atención. No vas a dejar de ver televisión (programa principal) solo porque fuiste a atender el teléfono (interrupción).

No digo que no sea posible; lo que pasa es que por algo no se debe hacer.
Una de las razones son las "operaciones moleculares", que usualmente suelen ser operaciones matemáticas con float y otros tipos de datos de más del "ancho" del CPU (en este caso, 8 bits); en general las operaciones matemáticas combinadas en una sola línea son "moleculares".
Lo opuesto a la "operación molecular", es la "operación atómica"; la cuál, por definición, no se puede dividir; o mejor dicho, no se puede interrumpir. Las atómicas básicamente son aquellas que se pueden ejecutar una sola instrucción máquina; cabe aclarar que una instrucción máquina no necesariamente equivale a una línea de código (excepto en lenguaje ensamblador).

A todo esto, ¿entonces qué tiene de malo hacerlo? ¿Recuerdas cuando dije que las operaciones atómicas no se pueden interrumpir? Bueno pues ese el problema: sólo las atómicas.
Imagina que en plena suma de dos int se dispara una interrupción, se ejecuta su respectiva rutina pero al terminar, en vez de retomar esa suma, ejecuta otro proceso completamente distinto. ¿Qué ocurrió con la suma? La respuesta puede variar dependiendo del momento exacto en que se disparó, pero las posibilidades son: se realizó con éxito (en el mejor de los casos), la variable del resultado tiene un valor incorrecto (no es ni el anterior ni el esperado), o no ocurrió absolutamente nada (en el peor de los casos).
Sé que en "demo" no hay operaciones matemáticas, ¿pero en print, clear y setCursor? Ahí quizá sí; el no completar la ejecución como se debe, podría incluso ser fatal.

Utilizar una interrupción para alterar el flujo del programa principal es mucho más complicado de lo parece (y no recomendado por lo antes dicho); y no, no hablo de simplemente modificar el valor de una "bandera" porque eso implicaría máquina de estados de todos modos (es igual que con digitalRead).
Es tan complicado como estudiar la estructura de la pila de ejecución ("stack" en inglés) para así poder alterar el valor previo a la interrupción del "program counter"; lo cual debería resultar, efectivamente, en la alteración del flujo del programa principal posterior a esta rutina. Con decirte que eso solo es posible hacerlo con un fragmento de código en ensamblador, quizá eso te eche para atrás y prefieras mejor quedarte con lo de la máquina de estados.
Encima habrían otros efectos secundarios como perder el rastro de la pila, que a la larga provoca cuelgues por el desbordamiento de esta; a menos que con más código ensamblador, conviertas la rutina de mostrar un contacto, en algo parecido a una interrupción (capacidad de retornar al punto en el que realmente estaba) pero con poder usar Serial y delay.

Tengo entendido que eres principiante, así que si quieres evitar tanta confusión, te sugiero que prosigas con lo de la máquina de estados y nos preguntes por dónde te perdiste. Pero eso sí, ¡que se vea un esfuerzo de tu parte!

CaleBit:
estuve investigando un poco y me parece que es el efecto rebote, alguna idea para solucionar esto

Por software: un pequeño delay apenas se detecta el pulso.
Por hardware: un condensador de 10 uF paralelo al botón.

CaleBit:
1-Una primera duda el coin que tengo funciona también como un botón, es decir al entrar una moneda, sería como pulsar un botón?

Correcto. Al pasar la moneda, se cierra un circuito durante una fracción de segundo; pero lo suficiente para que el programa lo detecte mientras no esté atascado en retrasos.

CaleBit:
¿Al poner el cable en pin 2 este espera el pulso para activarse(HIGH)?, o todo el tiempo esta entregando un voltaje porque si es así como podría conocer su estado.

Eso de sí se conecta a tierra o a voltaje depende de la lógica de la salida: el "estado activo" puede ser alto o bajo. O también determina en un botón u otro contacto simple si usar resistencia pull-up o pull-down (usados para estabilizar los estados digitales, pero no soluciona los rebotes).

CaleBit:
Alguien conoce la sintaxis de esta función?

millis() no requiere parámetros. Retorna un unsigned long que representa los milisegundos transcurridos desde que el Arduino se enciende o reinicia. Se desborda cada 49.71 días.

CaleBit:
Gracias y disculpen tantas molestias.

¿Molestias de qué? Para eso estamos, y con más razón para los que apenas empiezan :wink: