Read a row/line from a CSV file

Good evening friends, I hope to explain well the problem I have .
I’m working with a database in which use a similar format:

2344,cereal,verdura,fruta
1234,cereal,fruta,
2323,fruta,verdura,
2324,cereal,
3232,fruta,verdura,

I want to do is that when you type 2344 in the serial monitor, only the data unfold : cereal , verdura and fruta in the serial monitor.

I have understood that I must make a function that allows me to read the data until a newline ( \ n ) .
This code only lets you know if the number 2344 or another exists in the file and also shows the position in which the request is .

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

const int chipSelect = 4;
File Archivo;
String readString;
char c;

char rx_byte = 0;
String rx_str = "";

void setup() {
  Serial.begin(9600);
  Serial.println("Inicializando Base de Datos ETS");
  
  if (!SD.begin(chipSelect)) {
    Serial.println("Tarjeta no Encontrada");
    // don't do anything more:
    return;
  }
  
  Serial.println("Tarjeta inicializada");
  
  Serial.println("Introduce tu numero de solicitud.");
}


void loop() {
  if (Serial.available() > 0) {    // is a character available?
    rx_byte = Serial.read();       // get the character
    
    if (rx_byte != '\n') {
      // a character of the string was received
      rx_str += rx_byte;
    }
    else {
      // end of string
      Serial.print("Bienvenido ");
      Serial.println(rx_str);
      busqueda();
      
      rx_str = "";     
      readString = "";      // clear the string for reuse
      Serial.println("");
      Serial.println("Introduce tu numero de solicitud.");
    }
  } // end: if (Serial.available() > 0)
}

void busqueda(){
  Archivo = SD.open("solicitud.csv");
  
  //Si el archivo se ha abierto correctamente se muestran los datos.
  if (Archivo){
    
    //Se muestra por el monitor que la información que va a aparecer es la del
    //archivo datos.txt.
    Serial.println("Base de Datos actual:");
    
    //Se implementa un bucle que recorrerá el archivo hasta que no encuentre más
    //información (Archivo.available()==FALSE).
   
    while (Archivo.available()){
      c = Archivo.read();
      //store characters to string
      readString += c;  
    }
    
    Serial.println(readString);
    
    if (readString.indexOf(rx_str)>0) { // Puedes cambiar las palabras que sabes que si esta o que no estan en el texto para ver como funciona este sistema
      Serial.println("La solicitud " + rx_str + " fue hecha correctamente");
      Serial.println(readString.indexOf(rx_str));
    }

    else{
      Serial.println("La solicitud " + rx_str + " no fue hecha");
    }
   
    //Si todo ha ido bien cierra el archivo para no perder datos.
    Archivo.close();
  }
}

I think you could use the same process for reading the CSV file as you used for getting data from the Serial Monitor.

You should read in the file until you get to a newline character and then parse the data to see if it matches. If not read in another line.

The examples in Serial Input Basics include a parse example.

...R

Hey,

you can make your life a lot easier if you use Arduino's "high level" string class.

Have a look at the readStringUntil() methods. Both SD and also Serial provide that method.

They return a 'String' object, which has easy-to-use member functions that you can use. For example 'substring' or 'indexOf' (finds a token within the string).

The String class has a bad reputation when used with the Arduino. There used to be bugs with it and although they are probably fixed in later versions of the IDE and compiler they still hog memory and cause memory fragmentation.

There are several equivalent functions available for use with C style null terminated char arrays that don’t share the problems of the String class.

Thanks for the Info.

Back to gomez696: What's your actual question, by the way? :)

Seems you already know how to do it. Where are you stuck?

When you print "La solicitud " + rx_str + " fue hecha correctamente", you just need to reed further, then you have your entry.

One serious problem will occur if the filesize gets big. It's just a matter of time regardless of the Arduino model before the application will start showing unexpected behaviour if you run out of memory.

If your Arduino is an Uno, there is only 2kByte and it's shared between all variables. You're trying to read all file data into memory in your busqueda() so problems will occur.

So what is the maximum size of a record? Of the fields? And how many records maximum? Depending on what needs to be done with the record, the approach can vary slightly

A far better way is 1) to get rid of the use of String (capital S) and use good old character arrays (string with lowercase s) 2a) read a line at a time and check for the requested string 2b) read the number till the first comma and check; if you need to display the record, display the number followed by all characters till the '\n'

Choose either 2a or 2b from above; it will define how big your character array needs to be.

Thank you very much everyone for your reply.
The final file will have 300 rows and 15 columns , approximately.
I think it would be appropriate to use an additional arduino to perform processing tasks , since the main idea is to take the data and send them to a thermal printer.

I found a code that allows locate an end of a row , now I would like to join the code beginning with this one.

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

const int chipSelect = 4;
String linea = "";

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("ETS.csv");

  // if the file is available, write to it:
  if (dataFile) {
    while (dataFile.available()) {
      linea = dataFile.readStringUntil('\n'); 
      Serial.println(linea);
      dataFile.close();
    }
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  }
}

void loop()
{
}

How could send each data item is in a row ?
That is, the main arduino send the data that are separated by a comma , one by one, to the second arduino that will perform printing.

Note: To print only one row will be taken.