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.