Is it possible to split unknown string into array?

I am making my first steps with arduino environment, and I hit a bit of a wall.
I am using an ESP32 to control pins using the Google Assistant.
I got it to function properly, but it controls one pin per cycle.

To explain this a bit more, here is the idea how it works:

  1. Google assistant receives a command an forwards it to IFTTT.
  2. IFTTT sends GET request to a PHP script like this:
GET http://automationsite.com/data_put.php?action=set&device=201&gpio=23&value=1
  1. PHP script updates the database for the device 201 setting the pin 23 to 1, along with setting the time stamp for the request, and changing time stamp for confirmed to NULL.

  2. The ESP32 is connected to the wifi, and every 5 seconds sends a GET request:

GET http://automationsite.com//data_get.php?device_id=201
  1. The php script responds with a blank answer if there is no change, and if there is (it looks for the time requested is later than time confirmed) it returns string like this:
 {"gpio":"19","value":"1"},{"gpio":"13","value":"0"},{"gpio":"2","value":"1"}{"gpio":"19","value":"0"},{"gpio":"13","value":"0"},{"gpio":"2","value":"0"}
  1. ESP32 returns the confirmation for the pin changed to PHP script, that sets the timestamp for the confirmation.

The string is generated with JSONE_Encode in PHP, and in Arduino I’ve used <ArduinoJson.h> library, however the “” brackets were throwing it off, so I’ve removed them.

Now only the first value is applied, and is removed from the next query, eventually setting all pins to the desired value.

What I would like to do is apply all changes at once, by creating the array from the incoming string, and then loop the code through all elements of the array.

However, I could not make compiler to validate since the incoming string is unknown, and therefore the size of the array cannot be calculated.

Here is the current working code that sets the pins on the ESP32:

        StaticJsonBuffer<200> jsonBuffer;
        JsonObject& root = jsonBuffer.parseObject(line);
        if(!root.success()) {
          Serial.println("parseObject() failed");
        }
        else {
        String Sgpio = root["gpio"];
        String Sgpio_val = root["value"];
        int gpio = root["gpio"];
        int gpio_val = root["value"];
        if (gpio_val == 0){pinMode(gpio, OUTPUT);digitalWrite(gpio, LOW);}
        if (gpio_val == 1){pinMode(gpio, OUTPUT);digitalWrite(gpio, HIGH);}
        if (gpio_val == 2){pinMode(gpio, INPUT);}
        if (gpio_val == 3){pinMode(gpio, INPUT_PULLUP);}
        String ConfirmationURL = url + "&action=confirm&gpio=" + Sgpio;
        if (!client.connect(host, httpPort)) {Serial.println("update connection failed");return;}
        else {client.print(String("GET ") + ConfirmationURL + "\r\n" + "Connection: close\r\n\r\n" );}
        Serial.println( "\r\n setting GPIO " + Sgpio + " with value " + Sgpio_val + "\r\n" );
        }

I have not included attempted string to array conversion as I tried all I could find on the internet for hours, but it should look like this in pseudo code:

String line = client.readStringUntil('\r');
incomingData[]= StringToArray(line,",");

x=0;

while (incomingData) {
      
    do commands with incomingData[x] 
    x++;
}

Again, this is the first ever I worked with C++(ish), the whole thing is created from the example pieces, and the whole thing might seem lame, but I’d appreciate any help.

You are looking for a "union". See this forum post to learn how the poster solved a similar problem.

Paul

You must know in advance the maximum size for the string. For example, you expect a maximum of 5 commands in one string. So declare an array which is big enough.

Then your code needs to be able to work with a partially-filled array. Maybe another variable with numCommands ?

You should also code defensively so that if a hacker attempts to send 6 commands and cause your code to write off the end of the array, your code will ignore or defer the additional data.

Paul_KD7HB:
You are looking for a "union". See this forum post to learn how the poster solved a similar problem.

Paul

This example has a fixed length.

Is there really no way of setting the array size on the fly ?

It is generally not a good idea with the limited memory on a typical Arduino.

The C malloc() function is available to allocate dynamic memory at any time. You should try to find examples using it.

Thank you all !

I guess I will:

  1. limit the number of responses to 1 in PHP,
  2. increase frequency of queries if the last result was not blank,
  3. and call this a feature that prevents start current overload for the attached devices :slight_smile: