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.

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

1 Answer 1

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.
answered Jan 28, 2019 at 15:36
1
  • Thank you, sir! Learned a lot from your answer and your snippet finally solved the issue. Now I can finally proceed. Thanks again. Commented Jan 28, 2019 at 19:23

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.