Arduino / C++ : how to share the same value from a variable and class variable

Viewed 79

I would like to share the same content of a variable inside a class like this : (here is minimal code to show the problem)

class Form_Manager {
  private:
    char value_char120[120];
    byte ElementsCount = 0;

  public:
    Form_Manager(uint8_t totalNbrOfParameters )  {
      //initialisation de la classe
      Serial.println("initialisation de la classe");
    }
    byte addParameter(int id ,  char(*value)[120]  ) {
      //value_char120 = value ; //this does not work !
      //strcpy(value_char120, value );//this does not work !
    }
    byte showParameter(int id ) {
      Serial.println(value_char120 );

    }
    byte setParameter(int id ,  char* NewValue ) {
      //value_char120=NewValue; //this does not work !
    }
};

Form_Manager FM1 = Form_Manager( 21 );
char AP_ssid[120] = "mySSID";


void setup() {
  Serial.begin(115200);
  FM1.addParameter(1 , &AP_ssid);
  FM1.showParameter(1); //=> should write "mySSID"

  //change value from class
  FM1.setParameter(1 , "NewSSID");
  FM1.showParameter(1); //=> should write "NewSSID"
  Serial.println(AP_ssid); //=> should write also "NewSSID"

  //change value from local variable
  String value="TOTO";
  strcpy(AP_ssid, value.c_str());
  FM1.showParameter(1); //=> should write "TOTO"
}

void loop() {

}

The goal is that the variable AP_ssid and the variable inside the Object (value_char120) are pointing to the same address (IE: share the same value)

*** EDIT : *** At first, I didnt't want to show too much code. But,to show the idea of what I want, here is a complete example of how it works (It works for all types but not for char[120] :


class Form_Manager {
  private:
    //DynamicJsonDocument my_paramJSON;
    enum Type {FIELDSET, STRING , CHAR_ARRAY, CHAR_ARRAY120, CHAR,  INT , UNSIGNED_INT , WORD , LONG , UNSIGNED_LONG , FLOAT , BOOL , BYTE };
    struct Element {
      char id[20] = "" ;
      char placeHolder[120] = "" ;
      char typeChoice[120] = "" ;
      char type[20] = "" ;
      int TYPE ;
      union {
        byte *value_byte;// byte - bool - char
        bool *value_bool;
        char *value_char;
        int *value_int;//int - word - long - float
        word *value_word;
        long *value_long;
        uint32_t *value_uint32_t;
        float *value_float;
        unsigned long * value_unsigned_long;
        //char  value_charArray[120];
        char ** value_charArray;
        char value_char120[120];
      } theValue;
    };
    Element *Elements;
    byte ElementsCount = 0;
  public:
    Form_Manager(uint8_t totalNbrOfParameters )  {
      Elements = new Element[totalNbrOfParameters + 1];
    }
    // Destructor
    ~Form_Manager() {
      delete []Elements;
    }
    int getTYPE(char * type) {
      int TYPE;
      if (type == "int") {
        TYPE = INT;
      } else if (type == "String") {
        TYPE = STRING;
      } else if (type == "word") {
        TYPE = WORD;
      } else if (type == "long") {
        TYPE = LONG;
      } else if (type == "unsigned long" || type == "uint32_t") {
        TYPE = UNSIGNED_LONG;
      } else if (type == "float") {
        TYPE = FLOAT;
      } else if (type == "bool") {
        TYPE = BOOL;
      } else if (type == "byte") {
        TYPE = BYTE;
      } else if (type == "unsigned int") {
        TYPE = UNSIGNED_INT;
      } else if (type == "charArray") {
        TYPE = CHAR_ARRAY;
      } else if (type == "charArray120") {
        TYPE = CHAR_ARRAY120;
      } else {
        TYPE = CHAR;
      }
      return TYPE;
    }
    //, STRING , INT , WORD , LONG , UNSIGNED_LONG , FLOAT ,UNSIGNED_INT , BOOL , BYTE
    byte addParameterDo(char * id, char * placeHolder, char * type  ) {
      strcpy(Elements[ElementsCount].id, id);
      strcpy(Elements[ElementsCount].placeHolder, placeHolder);
      int TYPE = getTYPE(type);
      strcpy(Elements[ElementsCount].type, type);
      Elements[ElementsCount].TYPE = TYPE;
      return ElementsCount++;
    }
    byte addParameter(char * id , char * placeHolder, char**  value  , const char * typeChoice = ""  ) {
      Elements[ElementsCount].theValue.value_charArray = value ;
      byte r = addParameterDo ( id,  placeHolder, "charArray");
      return r;
    }
    byte addParameter(char * id , char * placeHolder,  int &value ) {
      Elements[ElementsCount].theValue.value_int = &value;
      return addParameterDo ( id,  placeHolder, "int");
    }
    byte addParameter(char * id , char * placeHolder,  word & value ) { //"word" == "unsigned int"
      Elements[ElementsCount].theValue.value_word = &value;
      return addParameterDo ( id,  placeHolder, "word");
    }
    byte addParameter(char * id , char * placeHolder,  long & value ) {
      Elements[ElementsCount].theValue.value_long = &value;
      return addParameterDo ( id,  placeHolder, "long");
    }
    byte addParameter(char * id , char * placeHolder,  unsigned long & value ) {
      Elements[ElementsCount].theValue.value_unsigned_long = &value;
      return addParameterDo ( id,  placeHolder, "unsigned long");
    }
    byte addParameter(char * id , char * placeHolder,  float & value ) {
      Elements[ElementsCount].theValue.value_float = &value;
      return addParameterDo ( id,  placeHolder, "float");
    }
    byte addParameter(char * id , char * placeHolder,  bool & value ) {
      Elements[ElementsCount].theValue.value_bool = &value;
      return addParameterDo ( id,  placeHolder, "bool");
    }
    byte addParameter(char * id , char * placeHolder,  byte & value ) { //"byte" == "char"
      Elements[ElementsCount].theValue.value_byte = &value;
      return addParameterDo ( id,  placeHolder, "byte");
    }
    byte addParameter(char * id , char * placeHolder,  String * value ) {
      Serial.println("Please,don't use String !");
    }
    byte setParameter(char * id, String value ) {
      int length = value.length();
      char *s = (char *)malloc(length + 1); // 100 bytes = max 99 characters long string
      strcpy(s, value.c_str());
      s[length] = '\0';
      return setParameter( id, s  ) ;
    }
    byte setParameter(char * id,  char * value) {
      int i = getParameterIndex( id );
      if (i >= 0) {
        switch (Elements[i].TYPE) {
          case INT :
            *Elements[i].theValue.value_int = atoi(value);
            break;
          case WORD :
            break;
          case LONG :
            *Elements[i].theValue.value_long = atol(value);
            break;
          case UNSIGNED_LONG :
            *Elements[i].theValue.value_unsigned_long = atol(value);
            break;
          case FLOAT :
            *Elements[i].theValue.value_float = atof(value);
            break;
          case BOOL :
            *Elements[i].theValue.value_bool = bool(value);
            break;
          case BYTE :
            *Elements[i].theValue.value_byte = atoi(value);
            break;
          case CHAR_ARRAY120 :
            // *** THIS DOES NOT WORK ***
            strncpy(*Elements[i].theValue.value_charArray, value , strlen(value) );
            Elements[i].theValue.value_charArray[strlen(value)] = '\0';
            break;
          case CHAR_ARRAY :
            *Elements[i].theValue.value_charArray = value;
            break;
          case CHAR :
            //Elements[i].theValue.value_char = value;
            break;
          default:
            //Elements[i].theValue.value_char; = value;
            break;
        }
      }
      return i;
    }
    String getParameterValue(char * id ) {
      int i = getParameterIndex( id );
      return getParameterValue( i );
    }
    String getParameterValue(uint8_t i ) {
      if (i >= 0 && i < ElementsCount) {
        switch (Elements[i].TYPE) {
          case FIELDSET :
            return "";
            break;
          case INT :
            return (String) * Elements[i].theValue.value_int;
            break;
          case WORD :
            return (String) * Elements[i].theValue.value_word;
            break;
          case LONG :
            return (String) * Elements[i].theValue.value_long;
            break;
          case UNSIGNED_LONG :
            return (String) * Elements[i].theValue.value_unsigned_long;
            break;
          case FLOAT :
            return String(*Elements[i].theValue.value_float);
            break;
          case BOOL :
            return (String) * Elements[i].theValue.value_bool;
            break;
          case BYTE :
            return (String) * Elements[i].theValue.value_byte;
            break;
          case CHAR_ARRAY120 :
            return (String) * Elements[i].theValue.value_char120;
            break;
          case CHAR_ARRAY :
            return (String) * Elements[i].theValue.value_charArray;
            break;
          case CHAR :
            return (String) * Elements[i].theValue.value_char;
            break;
          default:
            return (String) * Elements[i].theValue.value_char;
            break;
        }
      }
      return "";
    }
    uint8_t countIndex() {
      return ElementsCount;
    }
    char * getParameterNameFromIndex(uint8_t i) {
      return (( i < ElementsCount) ? Elements[i].id : '\0');
    }
    int getParameterIndex(char * id ) {
      int retour = -1;
      for (int i = 0; i < ElementsCount; i++) {
        if (strcmp (Elements[i].id, id) == 0) {
          retour = i;
          break;
        }
      }
      return retour;
    }
    String getParameterForm(char * id ) {
      return getParameterForm( getParameterIndex( id ) );
    }
    String getParameterForm(int i ) {
      String retour = "";
      if (i >= 0 && i < ElementsCount) {
        retour += "<p><label for=\"" ;
        retour +=  Elements[i].id;
        retour +=  "\">" ;
        retour +=  Elements[i].placeHolder;
        retour +=  " : </label>";
        switch (Elements[i].TYPE) {
          case FLOAT :
            retour += "<input type='number' id='";
            retour +=  Elements[i].id;
            retour += "' name='";
            retour +=  Elements[i].id;
            retour += "'  step=\"0.01\" value=\"";
            retour +=  getParameterValue(i)  ;
            retour += "\"/>";
            break;
          case UNSIGNED_INT:
            retour += "<input type='number' id='";
            retour +=  Elements[i].id;
            retour += "'  name='";
            retour +=  Elements[i].id;
            retour += "' min=\"0\" step=\"1\" value=\"";
            retour +=  getParameterValue(i)  ;
            retour += "\"/>";
            break;
          case INT:
            retour += "<input type='number' step='1' id='" ;
            retour +=  Elements[i].id ;
            retour +=  "'  name='";
            retour +=  Elements[i].id;
            retour += "' value=\"";
            retour +=  getParameterValue(i)  ;
            retour += "\"/>";
            break;
          case BYTE:
            retour += "<input type='number' min=\"0\" max=\"255\"  step='1' id='" ;
            retour +=  Elements[i].id ;
            retour +=  "'  name='";
            retour +=  Elements[i].id;
            retour += "' value=\"";
            retour +=  getParameterValue(i)  ;
            retour += "\"/>";
            break;
          default:
            if ( strcmp(Elements[i].typeChoice, "ssid") == 0 ) {
              retour += "<select name='";
              retour +=  Elements[i].id ;
              retour += "' ";
              retour += "id='";
              retour +=  Elements[i].id ;
              retour += "'>";
              retour += "<option disabled selected >**Please select**</option>";
              //retour += getWifiAccessPointOptions(getParameterValue(i));
              retour += "</select>";
            } else {
              retour += "<input type='text' id='";
              retour +=  Elements[i].id ;
              retour += "'  name='";
              retour +=  Elements[i].id;
              retour += "' value=\"";
              retour +=  getParameterValue(i)  ;
              retour += "\" ";
              retour += "/>";
            }
            break;
        }
        retour += "<p>";
      }
      return retour;
    }

};


typedef struct {
  //few example of types : 
  char* ssid = "myWIFI";
  int  gmtOffset = +1 ; //_sec = 3600; //UTC +1 Paris
  float calibrationFactor = 6.6;
  byte PIN_Button = 2;
  char AP_ssid[120] = "MyAP_ID"; // <- *** This type is a problem for me ! ***
} myIOT_parameters;
myIOT_parameters my_parameters;

Form_Manager FM1 = Form_Manager( 21 );

void setup() {
  Serial.begin(115200);
  //char * ->OK:
  FM1.addParameter("SSID" , "Wifi SSID" ,  &my_parameters.ssid , "ssid"    );
  //int ->OK:
  FM1.addParameter("gmtOffset" , "gmtOffset (UTC +1 Paris)" , my_parameters.gmtOffset  );
  //float ->OK:
  FM1.addParameter("calibrationFactor" , "Eau calibrationFactor" , my_parameters.calibrationFactor );
  //byte ->OK:
  FM1.addParameter("PIN_Button" , "PIN_Button" , my_parameters.PIN_Button );
  //char [120]  **** this one does not work !! **** :
  // **** And I would like to make it work  !! **** :
  //FM1.addParameter("AP_ssid" , "Wifi AP_ssid" ,  &my_parameters.AP_ssid , "AP_ssid"    );

  String myNewValue="Toto";                          //<- new value "Toto"
  FM1.setParameter("SSID" , myNewValue );
  Serial.print("SSID New value from Object :");
  Serial.println( FM1.getParameterValue("SSID" ) );  //<- writes "Toto"
  Serial.print("SSID New value from my_parameters :");
  Serial.println( my_parameters.ssid  );             //<- writes "Toto"


  myNewValue="5";                          //<- new value 5
  FM1.setParameter("gmtOffset" , myNewValue );
  Serial.print("gmtOffset New value from Object :");
  Serial.println( FM1.getParameterValue("gmtOffset" ) );  //<- writes 5
  Serial.print("gmtOffset New value from my_parameters :");
  Serial.println( my_parameters.gmtOffset  );             //<- writes 5


  myNewValue="1.1";                          //<- new value 1.1
  FM1.setParameter("calibrationFactor" , myNewValue );
  Serial.print("calibrationFactor New value from Object :");
  Serial.println( FM1.getParameterValue("calibrationFactor" ) );  //<- writes 1.1
  Serial.print("calibrationFactor New value from my_parameters :");
  Serial.println( my_parameters.calibrationFactor  );             //<- writes 1.1

  myNewValue="11";                          //<- new value 11
  FM1.setParameter("PIN_Button" , myNewValue );
  Serial.print("PIN_Button New value from Object :");
  Serial.println( FM1.getParameterValue("PIN_Button" ) );  //<- writes 11
  Serial.print("PIN_Button New value from my_parameters :");
  Serial.println( my_parameters.PIN_Button  );             //<- writes 11

  // how to do the same for char[120] AP_ssid ??
  
}
void loop() {

}

The above code writes this in the console :

SSID New value from Object :Toto
SSID New value from my_parameters :Toto
gmtOffset New value from Object :5
gmtOffset New value from my_parameters :5
calibrationFactor New value from Object :1.10
calibrationFactor New value from my_parameters :1.10
PIN_Button New value from Object :11
PIN_Button New value from my_parameters :11

This shows that I can share the same pointer for my Object and my variable. The goal is to get params received by my ESP32 from POST, from a html form and set the values easily.

0 Answers
Related