Go Down

Topic: Enviar datos al monitor serial con SD  (Read 3373 times) previous topic - next topic

CaleBit

Apr 09, 2018, 06:09 am Last Edit: Apr 09, 2018, 09:37 pm by CaleBit
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.

 

Code: [Select]

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.

surbyte

#1
Apr 09, 2018, 05:25 pm Last Edit: Apr 09, 2018, 05:29 pm by surbyte
Lee el privado y edita tu post.

Quote
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

Lucario448

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:
Code: [Select]
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.

Eduardosanchez

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

noter

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í:

Code: [Select]

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);
}

CaleBit

#5
Apr 10, 2018, 07:09 pm Last Edit: Apr 10, 2018, 08:36 pm by CaleBit
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.

Lucario448

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?

CaleBit

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.

Lucario448

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:
Code: [Select]
Nombre:
CaleBit

Code: [Select]
Telefono:
5544332211




Mostrar las descripciones en una pantalla; y luego todos los registros, uno por pantalla:
Code: [Select]
Nombre:
Telefono:

Code: [Select]
CaleBit
5544332211

Code: [Select]
Carlos
5512344321

Y así sucesivamente...

CaleBit

Ok gracias haré las pruebas. Agradezco su ayuda.

CaleBit

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

 
Code: [Select]

#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");
 }
}






Lucario448

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

CaleBit

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

CaleBit

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

Code: [Select]

#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");
 }
}








Lucario448

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

Code: [Select]
#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);
}

Go Up