0

The following code reads a txt file from a SD card, finds the corresponding character and prints the next 12 characters:

...
      char temp;
      byte who = random(1, 13); // 1 to 12
      temp = findName(who);
      Serial.print(who);
      Serial.print("  ==> ");
      Serial.println(temp);
...

    char findName (byte number) {
      char text[12];
      byte i;
      txt = SD.open("test.txt");
      txt.seek(12 * (number - 1));
      for (i = 0; i < 11; i++) text[i] = txt.read();
      txt.close();
      return text;
    }

But the following, on a LCD, does not. (setCursor, etc. ommited for clarity)

...
char temp;
byte who = random(1, 13); // 1 to 12
temp = findName(who);
lcd.print(who);
lcd.print("  ==> ");
lcd.print(temp);
...

I'm certain the cause is a variable data type mismatch, but I don't know how to solve it. Any help is appreciated.

Thank you.

  • what is the variable lcd – Jaromanda X Jan 28 at 3:34
  • how do you know that your LCD works? ... run the LCD example sketch in the Arduino IDE to make certain – jsotola Jan 28 at 4:03
  • the LCD does work. The variable is a char array, made by the findName() routine. – ghpg2 Jan 28 at 4:25
  • lcd type and library? – Juraj Jan 28 at 6:10
  • The variable is a char array ... so, why would a char array have a print method? – Jaromanda X Jan 28 at 8:48
0

In the findName() function, you declare a char array of name text. Internally, text is a pointer to a block of memory 12 bytes in size.

When you return text within the findName() function, you are passing back the pointer to the block of memory. The return type of char is inconsistent with the return command. But probably more problematic is that once findName() ends, the memory set aside for the text array is marked as unused. It is no longer reserved for holding anything and may be reallocated at any time by some other function or operation.

In C/C++, array variables do not refer to the entire array, but to the first element in the array. The fact that your program works with Serial.print() is probably just good luck. lcd.print() may declare some variable or buffer which overwrites what the findName() function had put in those 12 bytes.

There are many approaches to take to resolve this. One way is to declare char arrays in the "highest" scope in which it will be used, and to declare it with the largest size that you could ever see in the operation of your program.

In your case, you can:

...
      char temp[12];
      byte who = random(1, 13); // 1 to 12
      findName(temp, who);
      Serial.print(who);
      Serial.print("  ==> ");
      Serial.println(temp);
...

    void findName (char *text, byte number) {
      byte i;
      txt = SD.open("test.txt");
      txt.seek(12 * (number - 1));
      for (i = 0; i < 11; i++) text[i] = txt.read();
      txt.close();
    }

What this does:

  1. temp is now the char array
  2. findName() takes the pointer to the char array, and the number as arguments
  3. findName() modifies text, which refers to the same block of already-allocated memory as temp, and that block of memory does not go away at the end of findName().
  4. Because findName() is not returning a value, it's return type is void.
  • Thank you, sir! Learned a lot from your answer and your snippet finally solved the issue. Now I can finally proceed. Thanks again. – ghpg2 Jan 28 at 19:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.