HTTPclient/TCPClient request not performed inmediately on startup

Hello guys, I’m trying to send post/get to a URL as soon as the spark core starts up. I need to be this as soon as possible. I have noticed that If I don’t insert a delay of 5 seconds before the request is done, it is actually never executed. No idea why.

I have tried both the HTTPClient library and done my own with no library just for the sake of trying. Both do not work. The example that comes with HTTPClient only works after the first request. I’m pasting the code of the example, with a small modification that will execute the request only once. If you add the while(!Serial.available()) SPARK_WLAN_Loop(); to the setup the request is indeed done.
Because of this you won’t be able to see the request output on time by serial, If you want to see the request response after it has been done, connect to the serial and press a key and insert this code right after loop() opens:

if (Serial.available()) {
    Serial.read();
    Serial.println(response.body)
}
unsigned int nextTime = 0;    // Next time to contact the server
HttpClient http;

// Headers currently need to be set at init, useful for API keys etc.
http_header_t headers[] = {
    //  { "Content-Type", "application/json" },
    //  { "Accept" , "application/json" },
    { "Accept" , "*/*"},
    { NULL, NULL } // NOTE: Always terminate headers will NULL
};

http_request_t request;
http_response_t response;

void setup() {
    Serial.begin(9600);
}

void loop() {
    if (nextTime) {
        return;
    }

    Serial.println();
    Serial.println("Application>\tStart of Loop.");
    // Request path and body can be set at runtime or at setup.
    request.hostname = "www.timeapi.org";
    request.port = 80;
    request.path = "/utc/now";

    // The library also supports sending a body with your request:
    //request.body = "{\"key\":\"value\"}";

    // Get request
    http.get(request, response, headers);
    Serial.print("Application>\tResponse status: ");
    Serial.println(response.status);

    Serial.print("Application>\tHTTP Response Body: ");
    Serial.println(response.body);

    nextTime = millis() + 10000;
}

I have tried the SEMI_AUTOMATIC mode as well, and noticed that if I enable Wifi only and make the request 10 seconds later it’s not actually done. I need to enable Wifi, connect to the cloud, wait 5 seconds and then it’s done.

Any ideas? and thanks in advance.


I’ve edited your post to properly format the code. Please check out this post, so you know how to do this yourself in the future. Thanks in advance! ~Jordy

Could it be that you’re making the HTTP request before things are fully initialized?

Maybe if you do something before your first HTTP transmission, like while (!WiFi.ready()) { delay(10); } it will behave a bit better. Can’t hurt to try.

Someone else with more experience can shed more light, I’m sure.

edited for clarity and correct suggestion

Thanks @naikrovek, I did actually tried that as well.
Not only:

if (WiFi.ready()) {
//Send request
}

but also

if (WiFi.ready() && Spark.connected()) {
//Send request
}

and none of them worked

Right, because those will not wait for things to be ready before continuing. You’re not making sure that things are ready, you’re checking to see if they are, and continuing if they aren’t.

Try the while loop. If you do it right, it will wait until things are ready then continue, which is what you want.

Thanks for your suggestions @naikrovek. However, I will have to disagree…

function loop() {
  while (!WiFi.ready()) { delay(10); }
  sendHTTPrequest();
}

in general terms is the same as


function loop() {
   if (WiFi.ready()) {
      sendHTTPrequest();
   }
}

Of course I also need to check if it was already sent or not inside sendHTTPrequest(), otherwise it will send the request repeteadly.

Right, but you’re looking to send an HTTPRequest as soon as possible, correct? I guess if there is no difference it doesn’t matter. I would hold on the first transmission until I was capable of sending it, myself.

I didn’t know your loop() was that small.

I completely agree with you in that I should wait until the Core is ready. However, the firmware should allow me to do that, just like you suggested, I should be able to check WiFi.ready() and/or Spark.connected()… The problem is that those functions are telling me “yes, I’m are ready” and when trying to do request it then fails and having a delay of 5 seconds after this function says “We are ready” seems just random, there should be a reason of this happening.

Anyone has any other ideas?

This is sort of a bug. It’s not behaving like it should. If WiFi.ready() and Spark.connected() both return true and then a HTTP call is perform, why does it fail?

Don’t know. Might be time to employ the use of a hardware debugger to figure out what’s going on. I have one right here, but I don’t have time to look into this for a few days.