string

hey guys
i have a question code and i enter data into String
but when i want to print the String to the monitor
it doesnt print the whole string
i think there is not enough space in the string himself
what can i do to print the whole data?

thanks in advance

Please post a program that exhibits the problem.

Note that a String and a string are different things

The purpose of the program is to receive information from a sd card and print specific information to glcd
but now i’m trying to find the information i need to print and only then i will combine it with the glcd
the problem is that not all the information comes in
because string is not big enough
i tried to reset the sting after it printed single char (in loop) and it printed everything
so i realized there was not enough space in the string

#include<SPI.h>
#include<SD.h>
File MyFile;
[b]String JDAMmsg;[/b]
bool isLoop = false;
int cntLoop = 0;
int numLoop = 2000;
void setup()
{
  Serial.begin(9600);
  if (!SD.begin(4))
  {
    while (1);
  }
}

void loop()
{
  MyFile = SD.open("dalg122.txt");
  while (MyFile.available() && !isLoop)
  {
    char data = char(MyFile.read());
    JDAMmsg += data;
    Serial.print(JDAMmsg);
    cntLoop++;
    if (cntLoop > numLoop)
      isLoop = true;
  }
  MyFile.close();
  Serial.println(JDAMmsg);
  bool exist = JDAMmsg.indexOf("Firmware:");
  if (exist = true)
  {
    for (int place = 293; place < 310; place++)
    {
      Serial.print(JDAMmsg[place]);
    }
  }
  while (true);
}

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. Just use cstrings - char arrays terminated with 0.

...R

How many characters in the file? How many on a line? How many lines? Which Arduino?

Worst case you're storing 2000 characters in your String. String can handle that but e.g. an Uno does not have enough memory for that.

I do agree that you should not use String, but that's not necessarily the cause of the problem.

sterretje:
How many characters in the file? How many on a line? How many lines? Which Arduino?

Worst case you're storing 2000 characters in your String. String can handle that but e.g. an Uno does not have enough memory for that.

I do agree that you should not use String, but that's not necessarily the cause of the problem.

there is more then 5000 characters in the file
for now i use uno

avibd:
there is more then 5000 characters in the file
for now i use uno

By the looks of it, you're only reading 2000 of them. Why? What are you trying to achieve?

If you just want to print the content, do a simple print of the character that you read.

But your code is doing more. You're doing a search and an search in memory as your currently doing does not work with that amount of data.

So you need a different approach. How is that data organised? Can you post the content of the file so we can suggest ideas?

sterretje:
By the looks of it, you're only reading 2000 of them. Why? What are you trying to achieve?

If you just want to print the content, do a simple print of the character that you read.

But your code is doing more. You're doing a search and an search in memory as your currently doing does not work with that amount of data.

So you need a different approach. How is that data organised? Can you post the content of the file so we can suggest ideas?

i reading only 2000 because i dont have enough memory to read everything

btw how can i post here the file?

how can i post here the file?

Reply to the post (not Quick Reply) and the Attachments link

avibd:
i reading only 2000 because i dont have enough memory to read everything

btw how can i post here the file?

Practically you will not have 2000 bytes.

I have performed an experimental study to understand the meanings of various key concepts of the posts of this thread; the findings of my study are:

I have stored 3030 characters in the SD Card as 30 lines; each line contains 100 characters + newline character.

I read them back from the SD Card and displayed them charcater-by-charctaer on the Serial Monitor. At the same time time, I have updated the instance str1 of the object String.

At the end, I have displayed the value of str1 on the Serial Monitor where only 848 (including newline characters) characters have appeared.

RAM capacity of ATmega328P is 2048-byte. The str1 has accepted only 848 characters. Global variables use 898 bytes (str1, str[5], MyFile); 1150 bytes for local variable. (898 + 1150 = 2048).

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

File MyFile;
char str[5] = "G1023";
String str1 = "";
void setup()
{
  Serial.begin(9600);
  SD.begin(4);
  SD.remove("Test1.txt");
  MyFile = SD.open("Test1.txt", FILE_WRITE);
  for (int j = 0; j<30; j++)
  {
    for (int i=0; i<20; i++)
    {
      MyFile.print(str);
    }
    MyFile.println();
  }
  
  MyFile.close();
  MyFile = SD.open("Test1.txt", FILE_READ);
  while(MyFile.available())
  {
    char x = (char)MyFile.read();
    Serial.print(x);
    str1 += x;
  }
  
  MyFile.close();
  Serial.println("OK"); //marker
  Serial.print(str1);
  Serial.print("LK"); //marker
}

void loop()
{
  
}

BTW: The Arduino IDE does not compile the VC++ (2010)'s class string. I attempted to replace Java’s object String by the VC++'s class string in order to see the difference in memory consumption.

the file below
and i can not write the file as I want
i read it as it is and it is accepted in specific wat

DALG122.TXT (1.95 KB)

avibd:
the file below
and i can not write the file as I want
i read it as it is and it is accepted in specific wat

Few questions:
1. This is a non-document Text File, and the format I can see by opening it using notepad. It contains a number of variable length lines. Where is it located now (I mean the original source)? Is it in the SD card or in a file in your computer.

2. Assume that it is in your SD card, then what do you want to do it with it? Do you want to read it from the SD Card and then save in your computer?

3. Assume that file is in your computer and then you want to write it into SD card.

4. What is being done by this instruction Serial.print(JDAMmsg[place]); of your Post#2? The JDAMmsg is subjected to have some valid methods of Java; JDAMmsg[place] refers to what? What does the index place refer to?

Read a line at a time. Although it is not the best (better to say, it's highly discouraged) to use the String class because you might run out of memory without realising it resulting in possible unexplained behaviour of your code, use of readStringUntil will be the quickest way to solve your problem.

String line = myFile.readStringUntil('\n');

Next you can use line.indexOf to check if the line contains the keyword that you're looking for. Just a comment here, indexOf does not return a bool. It returns -1 if not found, else the zero based position.

You will have to loop through your file until there is nothing more to read or you have found what you're looking for.

I will (try to) post a complete alternative code (based on Robin2's updated Serial Input Basics) later.

Below a modified version of the second example. I’ve renamed functions and variables to better reflect their function for this case.

// maximum line length in file; note that '\r' is also considered to be part of the line
// currently your longest line seems to be 88 characters (excluding line ending)
const byte maxLength = 100;
// an array to store a line
char line[maxLength];
// flag indicating that a complete line was read
bool lineComplete = false;
// flag indicating that reading a line is in progress
bool lineInProgress = false;

void setup()
{
  ...
  ...
}

void loop()
{
  ...
  ...
}


/*
  Read a line from a stream object (serial, file, ...)
  In:
    stream object
*/
void readLine(Stream &s)
{
  static byte ndx = 0;
  char endMarker = '\n';
  char rc;

  // clear the line
  if (ndx == 0)
  {
    memset(line, 0, sizeof(line));
  }

  while (s.available() > 0 && lineComplete == false)
  {
    rc = s.read();

    if (rc != endMarker)
    {
      // indicate that we got the first character of a line
      lineInProgress = true;
      // save in buffer
      line[ndx] = rc;
      ndx++;
      if (ndx >= maxLength)
      {
        ndx = maxLength - 1;
      }
    }
    else
    {
      line[ndx] = '\0'; // terminate the string
      ndx = 0;
      // indicate that we have a complete line
      lineComplete = true;
      // indicate that we're not reading a line
      lineInProgress = false;
    }
  }
}

The readLine function takes a stream object as an argument so you can use it for e.g. Serial, for networking and for files (not at the same time though as there will be problems sharing e.g. the buffer but in one progrm you can use it for serial and in another one for files).

There is one new variable (lineInProgress) which is needed because your last line does not end with a CR/LF; if that can be fixed, you don’t need it.

To demonstrate the use

void setup()
{
  Serial.begin(57600);

  // init SD card
  Serial.print("Initialising SD card...");
  if (!SD.begin(4))
  {
    Serial.println("failed!");
    // hang forever
    for (;;);
  }
  Serial.println("done.");

  // open the file
  myFile = SD.open("DALG122.TXT");

  if (myFile == NULL)
  {
    Serial.println("Error opening file");
    // hang forever
    for (;;);
  }
  Serial.println("Ready");

  // while there is (still) something to read
  while (myFile.available() > 0)
  {
    readLine(myFile);
    if (lineComplete == true)
    {
      // reset the flag
      lineComplete = false;

      // print the line
      Serial.println(line);
    }
  }
  myFile.close();

  // if a line was partially read (basically no endMarker found)
  if (lineInProgress == true)
  {
    Serial.println(line);
  }
}

If you run this, you should see the content of your file scrolling over the screen in e.g. Serial Monitor.

Next you want to search for certain keywords and print if they are found. I wrote a small function for that and you can define the keywords that you want to find in an array

...
...
// keywords for lines that need to be printed
char *keyWords[] =
{
  "Firmware",
  "IMU Type",
  "IOFP: TXA Latch off",  // last line of file
};

void setup()
{
  ...
  ...
}

void loop()
{
  ...
  ...
}

/*
  Read a line from a stream object (serial, file, ...)
  In:
    stream object
*/
void readLine()
{
  ...
  ...
}

/*
  check if keywords occur in line and print them if so
*/
void checkKeywords()
{
  for (int cnt = 0; cnt < sizeof(keyWords) / sizeof(keyWords[0]); cnt++)
  {
    if (strstr(line, keyWords[cnt]) != NULL)
    {
      Serial.print("Got '");
      Serial.print(keyWords[cnt]);
      Serial.println("'");
      Serial.print("Full line: '");
      Serial.print(line);
      Serial.println("'");
    }
  }
}

And in setup

void setup()
{
  Serial.begin(57600);
  // init SD card
  Serial.print("Initialising SD card...");
  if (!SD.begin(4))
  {
    Serial.println("failed!");
    // hang forever
    for (;;);
  }
  Serial.println("done.");

  // open the file
  myFile = SD.open("DALG122.TXT");

  if (myFile == NULL)
  {
    Serial.println("Error opening file");
    // hang forever
    for (;;);
  }
  Serial.println("Ready");

  // while there is (still) something to read
  while (myFile.available() > 0)
  {
    readLine(myFile);
    if (lineComplete == true)
    {
      // reset the flag
      lineComplete = false;

      // print the line
      //Serial.println(line);

      // check for the keywords
      checkKeywords();
    }
  }
  myFile.close();

  // if a line was partially read (basically no endMarker found)
  if (lineInProgress == true)
  {
    Serial.println("Last line");
    checkKeywords();
  }
}

Understand it before you use it; after all, you’re the one that needs to maintain the code.

The result:

Initialising SD card...done.
Ready
Got 'Firmware'
Full line: '<    0.40>  Firmware:    13.5     
'
Got 'IMU Type'
Full line: '<    0.47>   IMU Type: SIMULTANEOUS   IMU Grade: GRADE_A
'
Last line
Got 'IOFP: TXA Latch off'
Full line: '<    0.51>  IOFP: TXA Latch off...'

Note:
I notice that in the forum, the ’ at the end of the line is printed on a new line; this is due to the ‘\r’ that is not stripped off. Your line ending is “\r\n” (CR/LF). You can strip the ‘\r’ off. E.g.

/*
  check if keywords occur in line and print them if so
*/
void checkKeywords()
{
  for (int cnt = 0; cnt < sizeof(keyWords) / sizeof(keyWords[0]); cnt++)
  {
    if (strstr(line, keyWords[cnt]) != NULL)
    {
      Serial.print("Got '");
      Serial.print(keyWords[cnt]);
      Serial.println("'");
      Serial.print("Full line: '");
      // strip off the '\r'
      if (line[strlen(line) - 1] == '\r')
        line[strlen(line) - 1] = '\0';
      Serial.print(line);
      Serial.println("'");
    }
  }
}

GolamMostafa:
Few questions:
1. This is a non-document Text File, and the format I can see by opening it using notepad. It contains a number of variable length lines. Where is it located now (I mean the original source)? Is it in the SD card or in a file in your computer.

2. Assume that it is in your SD card, then what do you want to do it with it? Do you want to read it from the SD Card and then save in your computer?

3. Assume that file is in your computer and then you want to write it into SD card.

4. What is being done by this instruction Serial.print(JDAMmsg[place]); of your Post#2? The JDAMmsg is subjected to have some valid methods of Java; JDAMmsg[place] refers to what? What does the index place refer to?

JDAMmsg refer to information i receive from system called JDAM
place refer to the specific information i want to print
the information comes from this system and i put it in file by arduino code
i just need to read it from the file and print to GLCD btw i just start today to work with GLCD-st7920

by the way thank you all. i use arduino mega now and it work fine