Config save, read from file with loop

Hi!

I need to tell i'm not too professional in c, now learning, i readed books, and mutch of forums, and i have a question. And my english is poor.

I try to create a function to configuration save and reload program parameters. The configuration setted up a web page and the saved to SPIFFS. It's working. But i'm hit the wall in restore config.

the configuration parameters (now) has all in separate files.

I'm read config files with a for cycle, and i like'd to set variables in this for cycle. So, like this (caricature):

for (int i = 0; i < configparms; i++){
      file open(configparams[i]);
      tempvariable = file read;
      variablearray[i] = tempvariable;
      file close(configparams[i]);
}

In this config files need to kept wifi ssid password, runtime parameters, saved status numbers, actual controlled devices status etc. Some devices wait for weeks or months to activate, i need to save counters if power outage or someting similar happened. The setup is come from a webpage (asyncwebserver) and stored to SPIFFS And i would like it to be easily expandable

i know maybe has an easier mode to this do work this. But now io need to resolve this. If anybody send an easier mode, thank s but if possible now i would like to try to done it like this. I post to save method (please not hate me, i learning the language, so if this terrible, sorry)

server.on("/savecfg", HTTP_POST, [](AsyncWebServerRequest *request){

    if(!request->authenticate(http_username, http_password))
    {
      return request->requestAuthentication();
    }
    logger("for ciklus indul...",1,0);
    
    for (int i = 0; i < confparms; i++){
      logger("form tartalom ellenőrzés lekérés: " + configparams[i],1,0);
       if (request->hasParam(configparams[i],true))
        {
          logger(configparams[i] + " mező parameter lekérése",1,0);
          String tempstr;
          tempstr = request->getParam(configparams[i], true)->value();
          
          logger("parameter lekérés vége "  + configparams[i],1,0);
  
          logger("Kapott paraméter: "  + tempstr,1,0);
          succ = true;
          String savePath = "/config_"+configparams[i] +".conf";
          logger("Megpróbálom menteni a " + savePath + " fájlba a következő adatot: " + tempstr,1,0);
          if(SPIFFS.exists(savePath)){
            logger("A fájl " + savePath + "létezik, törlöm...",0,0);
            if(SPIFFS.remove(savePath)){
              logger("A fájl " + savePath + "törlése sikeres",0,0);
            } else {
              logger("A fájl " + savePath + "törlése sikertelen",0,0);
            }
          }
          File file = SPIFFS.open(savePath, FILE_WRITE);
          if (!file) {
            logger("Hiba a " +savePath + " irásra való megnyításakor...",0,0);
            return;
          }
          if (file.print(tempstr)) {
            logger("File was written: " + savePath,1,0);
          } else {
            logger("File write failed: " + savePath,0,0);
          }
          file.close();
        } else {
          succ = false;
          logger("Gond van a getparammal: " + String(i) + " " + configparams[i],0,0);
        }
        
        savePath = "/config_bagfill.conf";
        String tempstr ="";
        if(SPIFFS.exists(savePath)){
          File file = SPIFFS.open(savePath, FILE_READ);
          if(!file){
            logger("Nem tudom megnyitni a " + savePath + "fájlt olvasásra",0,0);
          } else {
            while (file.available()){
              tempstr = tempstr + file.read();
            }
          }
          bagfilltime = tempstr.toInt();
          file.close();
        }
        savePath = bagfillfile;
        if(SPIFFS.exists(savePath)){
          File file = SPIFFS.open(savePath, FILE_WRITE);
          if(!file){
            logger("Nem tudom megnyitni a " + savePath + "fájlt írásra",0,0);
          } else {
            hourstobagfill = bagfilltime * 7 * 24;
            file.print(hourstobagfill);
          }
          bagfilltime = tempstr.toInt();
          file.close();
        }


    }

  request->send(200,"text/plain","Got it!");
  }); 
}

the variables:

char ssid[] = "Soimessid";     // CHANGE IT
char password[] = "somepassword";  // CHANGE IT

char http_username[] = "xxxxxx";
char http_password[] = "zzzzzzz";
char param_delete_path[] = "delete_path";
char param_edit_path[] = "edit_path";
char param_edit_textarea[] = "edit_textarea";
char param_save_path[] = "save_path";
const char *NTPserver = "hu.pool.ntp.org";

String allowedExtensionsForEdit = "txt, h, htm, html, css, cpp, js";
String logmsg = "";
String logfile = "/syslog.txt";

const char* jquery = "/jquery.min.js";

String wifi_mode = "";    //wifi mode AP or client
String filesDropdownOptions = "";
String textareaContent = "";
String savePath = "";
String savePathInput = "";
String status_wifi = "";
String status_ip = "";
String status_boardtemp = "";   //alapl hőmérséklet

String smtpserver ="mail.example.com";      //smtp server address
String smtpuser ="user@example.com";    //smtp user address
String smtppass ="password";    //smtp password
String smtpport ="578";
String recipientaddress ="";
String smtpfrom = "user@example.com";
String messagebody = "";
String host = "SZTCont";

bool enableTLS = false; //tls enabled
int rtcupdate = 0;
int onAPmode = 0;
int APreboot = 600;

//startup beállítás
bool rtcisok = false;
bool wifiOK = false;
int startedtime = 0;
int lastntptry = 0;
bool apreboot = true;

//Ledek
const int workledpin = 13;
const int relaypin1 = 33;   //27
const int relaypin2 = 14;     //14
const int relaypin3 = 12;   //12

const int currpin1 = 4;
const int currpin2 = 2;
const int currpin3 = 15;

const int dspin = 26;


int runtime = 5;      //Compressor ontime minutes
int sleeptime = 5;    //Compressol halt time minutes
int bagfilltime = 2;  //Extraction BAG fill time weeks
int pumplasttime = 0;
int hourstobagfill = 0;
String bagfillfile = "/hourstobagfill.txt";

bool rebooting = false;
String configparams[15]
  = { 
      "SSID", 
      "wifipwd", 
      "sysname", 
      "smtpserv", 
      "smtpusr", 
      "smtppwd", 
      "smtpport", 
      "tlsenabled", 
      "recipient1", 
      "recipient2", 
      "recipient3", 
      "recipient4", 
      "subj" 
      "comprun", 
      "compstop", 
      "bagfill"
    };

The whole program is 8 files in memory (in arduino ide) and 9 on SPIFFS (+config files) but if need i'm post all here for help.

Thanks for any help.

for saving a few system configuration parameters I tend to use esp32-preferences

I don't know about json, but I use the SD to store network settings.
The file on my SD card is named network.txt. Each setting is on its own line in this order:
mac
ip
netmask
gateway
dns server

#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>

byte myMac[6];
byte myIP[4];
byte myNM[4];
byte myGW[4];
byte myDNS[4];

void setup() {
  Serial.begin(115200);  

// disable ethernet
  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);

  if(!SD.begin(4)) Serial.println("SD fail");
  else Serial.println("SD ok");

  File fh = SD.open("network.txt",FILE_READ);
  char netBuffer[32];
  
  if(!fh)
  {
    Serial.println("SD open fail");
    return;    
  }

  int chPos = 0;
  int lineNo = 0;
  
  while(fh.available())
  {
    char ch = fh.read();
    if(ch == '\n') {
      chPos = 0;

      switch(lineNo) {
        case 0:
//          Serial.print("mac ");        
  sscanf(netBuffer,"%2x:%2x:%2x:%2x:%2x:%2x",&myMac[0],&myMac[1],&myMac[2],&myMac[3],&myMac[4],&myMac[5]);  
        break;

        case 1:
//          Serial.print("ip ");        
  sscanf(netBuffer,"%u.%u.%u.%u",&myIP[0],&myIP[1],&myIP[2],&myIP[3]);  
        break;

        case 2:
//          Serial.print("netmask ");        
  sscanf(netBuffer,"%u.%u.%u.%u",&myNM[0],&myNM[1],&myNM[2],&myNM[3]);  
        break;

        case 3:
//          Serial.print("gateway ");        
  sscanf(netBuffer,"%u.%u.%u.%u",&myGW[0],&myGW[1],&myGW[2],&myGW[3]);  
        break;

        case 4:
//          Serial.print("dns ");        
  sscanf(netBuffer,"%u.%u.%u.%u",&myDNS[0],&myDNS[1],&myDNS[2],&myDNS[3]);  
        break;
      }

//      Serial.println(netBuffer);
      lineNo++;
    }
    else if(ch == '\r') {
      // do nothing
    }
    else if(chPos < 31) {
      netBuffer[chPos] = ch;
       chPos++;
      netBuffer[chPos] = 0;
    }
  }
  
  fh.close();

  int x;
  
  Serial.print("\r\nmac ");
  for(x=0;x<6;x++) {
    Serial.print(myMac[x],HEX);
    if(x<5) Serial.print(":");
  }

  Serial.print("\r\nip ");
  for(x=0;x<4;x++) {
    Serial.print(myIP[x],DEC);
    if(x<3) Serial.print(".");
  }

  Serial.print("\r\nnetmask ");
  for(x=0;x<4;x++) {
    Serial.print(myNM[x],DEC);
    if(x<3) Serial.print(".");
  }

  Serial.print("\r\ngateway ");
  for(x=0;x<4;x++) {
    Serial.print(myGW[x],DEC);
    if(x<3) Serial.print(".");
  }

  Serial.print("\r\ndns ");
  for(x=0;x<4;x++) {
    Serial.print(myDNS[x],DEC);
    if(x<3) Serial.print(".");
  }

  Serial.println("\r\nStarting ethernet");
  Ethernet.begin(myMac,myIP,myDNS,myGW,myNM);
  digitalWrite(10,HIGH);
  
  Serial.println(Ethernet.localIP());
}

void loop() {
}

This is true. But this "problem" can be solved.
I guarantee you that your postings will be much easier to understand if you use this method.

Your english will be improved "on the fly" in two ways:
Easier to understand for others
You will expand your knowledge about english.

Lot's of words for advertising but what is this great method?
The first step is to write down all you want to write in your mother-language which seems to be hungarian.

and the second step?

Use google translate. I know hungarian is a "difficult" language which deviates a lot from most other languages. Still I am very sure that the result of a hungarian text translated to english by google will be easiER to understand than your poor english. If you are skeptical at least give it a try.

kattintson a háromszögre, hogy elolvassa a google-fordítást angolról magyarra

kattintson a háromszögre, hogy elolvassa a google-fordítást angolról magyarra
Garantálom, hogy hozzászólásaid sokkal könnyebben érthetőek lesznek, ha ezt a módszert alkalmazod.

Az angol nyelvtudását kétféleképpen javítják "on the fly":
Könnyebben érthető mások számára
Bővíteni fogja angol tudását.

Sok szó a reklámról, de mi ez a nagyszerű módszer?
Első lépésként írd le mindazt, amit le akarsz írni az anya nyelvén, ami magyarnak tűnik.

és a második lépés?

Használj Google fordítót. Tudom, hogy a magyar egy "nehéz" nyelv, ami nagyon eltér a legtöbb más nyelvtől. Mégis nagyon biztos vagyok abban, hogy a google által angolra fordított magyar szöveg eredménye könnyebben ER érthető lesz, mint a rossz angolod. Ha szkeptikus vagy, legalább próbáld ki.

same text translated from

hungrian to taiwaneese then
taiwaneese to samoa
samoa to german
german back to hungarian.

Some words changed but the sense is still the same
Kattintson a háromszögre, hogy elolvassa a Google fordítását angolról magyarra.
Biztos vagyok benne, hogy bejegyzése sokkal könnyebben érthető lesz, ha ezt a módszert alkalmazza.

Az angol nyelvtudásod két módon fog „gyorsan” fejlődni:
Másoknak könnyebb lesz megérteni.
Fejleszted angoltudásodat.

Sok sztori szól a reklámozásról. De mi is ez a csodálatos út?
Először írjon le mindent, amit a saját nyelvén szeretne írni. ami hasonló a magyarhoz

És a második lépés?

Használd a Google fordítót. Tudom, hogy a magyar sok más nyelvtől eltérően „nehéz” nyelv, de biztos vagyok benne, hogy könnyebb lesz megérteni a magyarról angolra fordítás eredményét. Ha tudni akarod, próbáld ki.

Hello!

I am making this post with the google translator you suggested. The same as the previous one, with the difference that I wrote it in English for practice and translated it back to Hungarian with the translator to check.

Then I'll write it down in Hungarian and the translator will solve it.

Thanks in advance to Horace for his constructive comment and I will try the method he suggested. But I am still interested in the solution to this problem that I have imagined, it may come in handy later, elsewhere.

My problem is that I want to store setting parameters in my esp32 device. The setting is done via a website form, I have already successfully stored them in SPIFFS files.

I read the form in a loop using this array:

String configparams[15]
  = { 
      "SSID", 
      "wifipwd", 
      "sysname", 
      "smtpserv", 
      "smtpusr", 
      "smtppwd", 
      "smtpport", 
      "tlsenabled", 
      "recipient1", 
      "recipient2", 
      "recipient3", 
      "recipient4", 
      "subj" 
      "comprun", 
      "compstop", 
      "bagfill"
    };

I use the same array to create the files, save the data, and read the data back, also in a FOR loop.

What I want to achieve is that the variables that I will use during the program can also be somehow accessed from the cycle. for example, to put the saved and reloaded SSID into the char with which I can then set up the wifi. As I read, there were a couple of ideas that are being tested, but since the variable names no longer exist at runtime, they are unusable. But in principle they can have the memory address. if I knew where they are in memory, I could build an array containing the addresses. that array would also have 15 elements and, like the "configparams" array, it would be assignable. so the first element of the configparams variable is the SSID, the first element of the other array (let's call it vararray) would contain a memory address, which would be the memory address of the char SSID. Then I could "put" the value in the SSID variable with a memcpy command and then use it to connect. But I haven't figured that out yet. I diligently read the forums and descriptions, but I wonder if there will be someone here who has already done something like this or at least has an idea of ​​how this could be solved.

Thank you for the advices.

I will also thank Horace separately!

Thanks for the advice, it looks promising and I will try it. but now I'm trying the harder way for learning and practice purposes.

Your response was quick and helpful, thank you again!

So you are using a ESP32-microcontroller

If your code works like this using the preference-library will be really very easy.

What exactly do you mean with the workd "cycle" ??

Your ESP32-code has somewhere some lines of code for establishing the WiFi-connection.

const char *ssid     = "my_SSID";
const char *password = "myPassword";

WiFi.begin(ssid, password);

in the above example constant arrays of char are used.
But this can be an non-constant arrays of char or a String too

example

String my_ssid    = "my_SSID";
String  myPWD = "myPassword";

WiFi.begin(my_ssid.c_str(), myPWD.c_str() );

And these Strings can be used in combination with the preferences library

Me personal I prefer using SafeStrings over Strings

So here are two demo-functions for read and write SafeStrings to the flash by using the preference-library

void LoadPreferences() {
  Serial.println("LoadPreferences");
  myPrefInstance.begin(myNameSpace, ReadOnly);
  //                                    ID       default value
  text1_SS = myPrefInstance.getString ("Text_1", "Text 1").c_str();
  text2_SS = myPrefInstance.getString ("Text_2", "Text 2").c_str();
  text3_SS = myPrefInstance.getString ("Text_3", "Text 3").c_str();

  myPrefInstance.end();
}


void SafePreferences() {
  Serial.println("SafePreferences");

  myPrefInstance.begin(myNameSpace, ReadWrite);
  //myPrefInstance.clear();

  myPrefInstance.putString ("Text_1"     , text1_SS.c_str() );
  myPrefInstance.putString ("Text_2"     , text2_SS.c_str() );
  myPrefInstance.putString ("Text_3"     , text3_SS.c_str() );

  LoadPreferences();
}

and here is a demo-code that demonstrates the use of the SafeString-library in combination with the preferences-library

// MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START *
// Take it for granted at the moment scroll down to void setup
// start of macros dbg and dbgi
#define dbg(myFixedText, variableName) \
  Serial.print( F(#myFixedText " "  #variableName"=") ); \
  Serial.println(variableName);
// usage: dbg("1:my fixed text",myVariable);
// myVariable can be any variable or expression that is defined in scope

#define dbgi(myFixedText, variableName,timeInterval) \
  do { \
    static unsigned long intervalStartTime; \
    if ( millis() - intervalStartTime >= timeInterval ){ \
      intervalStartTime = millis(); \
      Serial.print( F(#myFixedText " "  #variableName"=") ); \
      Serial.println(variableName); \
    } \
  } while (false);
// usage: dbgi("2:my fixed text",myVariable,1000);
// myVariable can be any variable or expression that is defined in scope
// third parameter is the time in milliseconds that must pass by until the next time a
// Serial.print is executed
// end of macros dbg and dbgi
// MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END *


#include <Preferences.h>     // add sourcecode file
Preferences myPrefInstance;  // create an instance of the object

#include <SafeString.h>      // add sourcecode file
createSafeString(mySafeString1_SS, 128); // create variable of type SafeString
createSafeString(mySafeString2_SS, 128);

//print automatically updated fileinfo to the serial monitor
void PrintFileNameDateTime() {
  Serial.println( F("Code running comes from file ") );
  Serial.println( F(__FILE__) );
  Serial.print( F("  compiled ") );
  Serial.print( F(__DATE__) );
  Serial.print( F(" ") );
  Serial.println( F(__TIME__) );
}


// helper-function for easy to use non-blocking timing
boolean TimePeriodIsOver (unsigned long &expireTime, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - expireTime >= TimePeriod ) {
    expireTime = currentMillis; // set new expireTime
    return true;                // more time than TimePeriod) has elapsed since last time if-condition was true
  }
  else return false;            // not expired
}

unsigned long MyTestTimer = 0;  // Timer-variables MUST be of type unsigned long
const byte    OnBoard_LED = 2;


void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
  static unsigned long MyBlinkTimer;
  pinMode(IO_Pin, OUTPUT);

  if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
    digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
  }
}

#define myNameSpace "myPrefSection1"
const boolean ReadOnly  = true;
const boolean ReadWrite = !ReadOnly; // not-operator inverts the value


// defining variables "my" shall indicate you can choose the name
unsigned char myUChar;
char  myChar;
int   myInt;
long  myLong;
float myFloat;
bool  myBool;


void myInitFunction() {
  myUChar = 255;
  myChar  = 'C';
  myInt   =     -23456;
  myLong  = 2100200300;
  myFloat =       1234.567;
  myBool  = true;

  mySafeString1_SS = "learn how preferences work";
  mySafeString2_SS = "use them to store values in flash";
}

void deleteAllVars() {
  Serial.println("deleteAllVars");

  myUChar = 0;
  myChar  = 'Z';
  myInt   = 0;
  myLong  = 0;
  myFloat = 0.1;
  myBool  = false;

  mySafeString1_SS = "empty";
  mySafeString2_SS = "empty";
  
  dbg("1:", myUChar);
  dbg("2:", myChar);
  dbg("3:", myInt);
  dbg("4:", myLong);
  dbg("5:", myFloat);
  dbg("6:", myBool);
  dbg("7:", mySafeString1_SS);
  dbg("8:", mySafeString2_SS);

  Serial.println("all vars deleted");
  Serial.println();
  Serial.println();

}

void SafePreferences() {
  Serial.println("SafePreferences");

  myPrefInstance.begin(myNameSpace, ReadWrite);
  myPrefInstance.clear();

  myPrefInstance.putUChar  ("ID", myUChar);
  myPrefInstance.putChar   ("Version_Letter", myChar);
  myPrefInstance.putInt    ("SerialNo"      , myInt);
  myPrefInstance.putLong   ("NoOfFans"      , myLong);
  myPrefInstance.putFloat   ("Distance"      , myFloat);
  myPrefInstance.putBool   ("Demo"          , myBool);
  myPrefInstance.putString ("Message_1"     , mySafeString1_SS.c_str() );
  myPrefInstance.putString ("Message_2"     , mySafeString2_SS.c_str() );
  Serial.println();
}

void LoadPreferences() {
  Serial.println("LoadPreferences");
  myPrefInstance.begin(myNameSpace, ReadWrite);
  //myPrefInstance.clear();

  mySafeString1_SS = "learn how preferences work";
  mySafeString2_SS = "use them to store values in flash";

  myUChar = myPrefInstance.getUChar  ("ID", 99);
  myChar  = myPrefInstance.getChar   ("Version_Letter", 'A');
  myInt   = myPrefInstance.getInt    ("SerialNo"      , 1234);
  myLong  = myPrefInstance.getLong   ("NoOfFans"      , 9999);
  myFloat = myPrefInstance.getFloat  ("Distance"      , 9876.543);
  myBool  = myPrefInstance.getBool   ("Demo"          , false);

  mySafeString1_SS = myPrefInstance.getString ("Message_1"     , "Hello 1").c_str();
  mySafeString2_SS = myPrefInstance.getString ("Message_2"     , "Hello 2" ).c_str();
  Serial.println();
  myPrefInstance.end();
}



void setup() {
  Serial.begin(115200);
  Serial.println("Setup-Start");
  PrintFileNameDateTime();

  myInitFunction();
  SafePreferences();
}


void loop() {
  BlinkHeartBeatLED(OnBoard_LED, 250);

  if ( TimePeriodIsOver(MyTestTimer, 1000) ) {
    deleteAllVars();
    LoadPreferences();
    dbg("1:", myUChar);
    dbg("2:", myChar);
    dbg("3:", myInt);
    dbg("4:", myLong);
    dbg("5:", myFloat);
    dbg("6:", myBool);
    dbg("7:", mySafeString1_SS);
    dbg("8:", mySafeString2_SS);
  }
}

best regards Stefan

Hi Stefan!

Thanks for the exhaustive explanation, I'm going to use it too.

"Cycle" comes from the fact that there are sometimes many words for a given thing in my language, and the translator, by definition, is not always able to define the correct one. In Hungarian, the "loop" function is called "ciklus". The translator thus translated the word cycle instead of loop. I didn't notice that.

Although your description is precise and detailed, I may still have questions about it. Thanks for the help.

Hi Stefan!

I have a question. This detail:

void LoadPreferences() {
  Serial.println("LoadPreferences");
  myPrefInstance.begin(myNameSpace, ReadWrite);
  //myPrefInstance.clear();

  mySafeString1_SS = "learn how preferences work";
  mySafeString2_SS = "use them to store values in flash";

  myUChar = myPrefInstance.getUChar  ("ID", 99);
  myChar  = myPrefInstance.getChar   ("Version_Letter", 'A');
  myInt   = myPrefInstance.getInt    ("SerialNo"      , 1234);
  myLong  = myPrefInstance.getLong   ("NoOfFans"      , 9999);
  myFloat = myPrefInstance.getFloat  ("Distance"      , 9876.543);
  myBool  = myPrefInstance.getBool   ("Demo"          , false);

  mySafeString1_SS = myPrefInstance.getString ("Message_1"     , "Hello 1").c_str();
  mySafeString2_SS = myPrefInstance.getString ("Message_2"     , "Hello 2" ).c_str();
  Serial.println();
  myPrefInstance.end();
}

Can it be done by a loop (or something similar), or does it have to be written line by line?

I understand by this that I currently have 15 parameters that I need to save, it works with a loop, but is it possible to restore it that way? I mean something like this:

for (int i = 0; i < 15; i++){
 switch(conftype[i]){
 case 0: //string
 myvariables[i] = myPrefInstance.getString(idList[i]);
 return;
 case 1: //integer
 myvariables[i] = myPrefInstance.getInt(idList[i]);
 return;
 [...]
 }

The part of the program that performs the current save looks like this:

server.on("/savecfg2", HTTP_POST, [](AsyncWebServerRequest *request){
  bool succ;
  if(!request->authenticate(http_username, http_password))
  {
    return request->requestAuthentication();
  }
  prefs.begin(myNS, RW);
  prefs.clear();
  for (int i = 0; i < configparms; i++){
    if (request->hasParam(configparams[i],true))
        {
            String tempstr;
            tempstr = request->getParam(configparams[i], true)->value();
            succ = true;
            switch(configtypes[i]){
              case 0:{   //"string"
                logger("Saving string",1,0);
                prefs.putString(configparams[i].c_str(),tempstr);
              }
              break;
              case 1:{   //"integer"
                int tempint = tempstr.toInt();
                prefs.putInt(configparams[i].c_str(),tempint);
              }
              break;
            }
          }
        }
  request->send(200,"text/plain","Got it!");
}); 

my demo-code demonstrates how to use different variable-types

Of course you can create an array of any standard-variable.
I do not use variable-type String
So I can't tell for this variable-type if it works with arrays

SafeStrings do not work as arrays.

You can find out by simply starting to modify my demo-code in small steps.
I recommend modifying in small steps because then
if an error or a malfunction occurs
you will always know it is caused by this small change I did last.

In the long run this method needs less time than trying to be fast by doing a lot of modifications at once and then searching hours long for what is causing the error

I do not recommend that you use an array here. If you use variables line by line the code does document itself if you use self-explaining names for everything.

Of course if you use
myParameter1
myParameter2
...
myParameter15
nothing is explained.

If you come back in half a year to modify your code
selfexplaining names will safe you a lot of time to re-understand your own code and to avoid bugs that are simply obvious if you really use self-explaining names

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.