Function returning a String. How to call / how to write

Hello

I’m lost… Learning the basic of C coding. Keep reading but problem not resolved.

How to properly declare and code so the value of the returned function is a string. I keep getting different kind of compiling error

A function is use to decode if a key switch has been pressed. The returned value from the function is a string.

In the main loop, how to properly declare and call the function and use the returned string value in a if condition ?

This is the main loop and the function

void loop(){
char aButton "";
aButton = Button();
  if (aButton = "S2"){Serial.print("   à , voilà le bouton");
}


String Button(){
  byte _data;
  const int debounce = 225;
  String aButton;
  Wire.begin();
  Wire.requestFrom(0x20, 1);
  if(Wire.available()){
     _data = Wire.read();
     if(_data < 255){  
      delay(debounce);
      switch (_data){
        case (254): Serial.println ("bouton S1"); Button == ("S1");  break;
        case (251): Serial.println ("bouton S3"); Button == ("S3");  break;
        case (247): Serial.println ("bouton S4"); Button == ("S4");  break;
        case (239): Serial.println ("bouton S5"); Button == ("S5");  break;
        case (223): Serial.println ("bouton S6"); Button == ("S6");  break;
        case (191): Serial.println ("bouton S7"); Button == ("S7");  break;
        
        return Button;
        } 
     }
   }
 }

Any help appreciated
Martin

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. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with ‘\0’ (NULL).

Note, that cstrings must be declared at their maximum size before they are used.

Note, also that variables (including a cstring) that are defined within a function will not exist outside the function and consequently cannot the passed back to the code that called the function.
Note also that you can pass a single value in a return statement but a cstring is an array of characters and if you define it within a function all you can pass to the calling function is the address of the array - however that is meaningless because there will be no data at that address after the function concludes.

IMHO the simplest thing is to define the cstrings as global variables and then the function can act on the cstring without needing to return it. (This may upset the purists).

…R

Edit to make comment more comprehensive - apologies for any confusion

assign aButton, return aButton

Button is the name of the function, not the name of the variable

If you would reveal which errors you get it would be easier to help. Do not use the “String” class, it will cause problems on Arduino’s - in your case a simple “byte” would be much better to identify the buttons.

Thanks for your input.

Still in the smog…

Let’s go step by step

First: Is this function is OK and properly coded to return a string value between “s1 to s7” depending of the decoded switch? The basic code and the read value are OK and has been tested outside of a function.

char Button(){
  byte _data;
  const int debounce = 225;
  char aButton;
  Wire.begin();
  Wire.requestFrom(0x20, 1);
  if(Wire.available()){
     _data = Wire.read();
     if(_data < 255){  
      delay(debounce);
      switch (_data){
        case (254): Serial.println ("bouton s1"); aButton = ("s1");  break;
        case (251): Serial.println ("bouton s3"); aButton = ("s3");  break;
        case (247): Serial.println ("bouton s4"); aButton = ("s4");  break;
        case (239): Serial.println ("bouton s5"); aButton = ("s5");  break;
        case (223): Serial.println ("bouton s6"); aButton = ("s6");  break;
        case (191): Serial.println ("bouton s7"); aButton = ("s7");  break;
        
        return aButton;
        } 
     }

You have a bunch of unnecessary brackets, but they’re harmless. A char is a single character. You can’t store “S1” in one. Since everything has an S prefix though, it’s not telling you anything, so you could drop it. The line for S1 would then look like this:

        case 254: Serial.println ("bouton s1"); aButton = '1';  break;

The compiler will probably complain that there is no return at the end for the case when nothing was read from wire.

If you are new to C, then please don't get used to using the String class. You will hear this a lot.

Here is a very good description of stack and heap and why String class is so evil.

Learning to not use Strings was more difficult for me because I had been using Strings for a couple of years. But learning to use c-strings (more commonly called 'strings' which confuses newbies and search engines equally) will help you in other good programming practices such as arrays.

It's also much easier to pass a string pointer in and out of a function.

First, in your Button() function you have the statement:

  • char aButton;*

which defines variable aButton as a char data type. As such, in memory you have 1 byte of storage for that variable. However in your code, you have the statement:

aButton = ("s1");

If you looked at this assignment in memory, it would look like:

+-----+-----+-----+ | s | 1 | \0 | +-----+-----+-----+

Double quotes denote a string (no capital 'S') variable which, in your case, would need to have 3 bytes of memory. You've only reserve 1 byte, which means two bytes of that data is going to slop all over the floor. (In reality, it will overwrite whatever comes after aButton in memory.) The last character in the S1 assignment is called the NULL character, and it is used as a sentinel to mark the end of a C string. Therefore, you need to define aButton as:

char aButton[3];

to make it a character array big enough to hold 2 *char*s plus the NULL termination character ('\0'). As others have suggested, forget about the String class. They can cause memory problems and give you nothing you can't do with simple C string. (For a list of C string functions, see here.)