Arduino IDE IOT2000 client.connect() crashes

Hi everyone,

I'm trying to send numbers from the IDE serial monitor to a Siemens IOT2040 and then to my Ubidots account.
My code appears to work fine for the first number, but when I try to send a second time it crashes. It shows the message "B0100000063f694" in the serial monitor, and then it gets stuck.
I print a serial message after the client.stop() command and the client.connect(server,80) to check which one was causing the problem.

char* payload  = (char *) malloc(sizeof(char) * 20);
int value = 0;
EthernetClient client;

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(50);
  // put your setup code here, to run once:
  Serial.begin(9600);
  while (!Serial) {
    ; /* wait for serial port to connect */
  }
  Serial.println("connecting...");
  if (client.connect(server, 80)) {
    Serial.println("connected");
  }
  else {
    /* if you didn't get a connection to the server: */
    Serial.println("connection failed");
  }
  digitalWrite(LED_BUILTIN, LOW);
  Serial.println("Ready to transmit");
  
}

void loop() {
  // put your main code here, to run repeatedly:
  if (Serial.available() > 0) {
    value = Serial.parseInt();
    Serial.print("Serial Value: ");
    Serial.println(value,DEC);
    sprintf(payload, "{\"%s\":%d}", variable_label, value);
    client.stop();
    delay(10000);
    Serial.println("Reaches this point");
  if (client.connect(server, 80)) {
    Serial.println("transmiting");
    /* Make the HTTP request to the server*/
    writeToUbidots(device_label, token, payload);
  }
  else {
    /* if you didn't get a connection to the server: */
    Serial.println("transmition failed");
  }
  }
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }
  /* if the server's disconnected, stop the client: */
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();

    /* do nothing forevermore: */
    for (;;)
      ;
  }
}

void writeToUbidots(const char* device_label,const char* token, char* payload){
    int content_length = strlen(payload) + 2;
    client.print(F("POST /api/v1.6/devices/"));
    client.print(device_label);
    client.println(F(" HTTP/1.1"));
    client.println(F("Host: industrial.api.ubidots.com"));
    client.println(F("User-Agent: siemenes/1.1"));
    client.print(F("X-Auth-Token: "));
    client.println(token);
    client.println(F("Connection: close"));
    client.println(F("Content-Type: application/json"));
    client.print(F("Content-Length: "));
    client.println(String(content_length));
    client.println();
    client.print(payload);
    client.println();
    free(payload);
    return ;
  }

How do I avoid it from crashing?
This is the first time I'm doing this kind of project so let me know is there a better way to continuously send data (serial or otherwise) to the cloud.
Thanks everyone!

char* payload  = (char *) malloc(sizeof(char) * 20);

What is the point of mallocing a static array?

char payload[20];
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

If the server sends back 100 characters, read just one of them. Why?

    free(payload);

The next time yo write to payload, you sh*t on memory you don’t own. THAT is why you crash the second time.

Hi PaulS,

I'm not sure about the Malloc, I copied it from an example. I removed it and works fine.

The client.read() reads one char at a time because that's how the messages come in and it doesn't cause any problem, the serial monitor shows the messages complete.

I took the free(payload) out and now the program works as intended.
Thank you very much!!! =)

Anyways, I'm sure my code is not the optimal way to deal with data transmission. So I accept more comments and tips.

The client.read() reads one char at a time because that's how the messages come in and it doesn't cause any problem, the serial monitor shows the messages complete.

Not on a single pass through loop(). If the server sends back 100 characters, loop() will iterate 100 times (or more; possible many, many more) before they are all read.

Usually, one wants to read the server response in a single pass through loop(), like so:

      while(client.connected())
      {
         while(client.available() > 0)
         {
            char c = client.read();
            Serial.print(c);
         }
     }

Note the use of two while statements, nested, not a single if statement. The client.connected() test will return true until the server has finished sending data and disconnected. The inner while condition will be true whenever there is data to be read.

Since you are not making use of the server response, this is all academic. But, if you WERE interested in what the server returns, then reading, printing, and discarding the data over many iterations of loop() would NOT be a good thing.