HTTP POST issue, especially when using deep sleep

I tried another library to read the temperature sensor, the SparkCoreDallasTemperature library. It isn’t helping much: a lot of the HTTP posts are still failing. It seems to be very irregular lately. Sometimes I would have 15 posts of which 10 are successful, followed by 2 days of failure. Resetting the Spark or unplugging doesn’t seem to be helping when it’s on a failure streak. I haven’t given up yet and am still looking for solutions. To be continued…

I read through this and while I know it’s super old, I, so far, have found a solution that works for me so thought I’d share. You can find it here:

What made the magic happen specifically was:

if(response.status == 200)
sleep = true;
if(sleep)
Spark.sleep(SLEEP_MODE_DEEP, 60);

So sleep gets set to false when the program fires up, and gets set to true only after I get the proper return code. That does mean that if, say, the server is down, the Core will never sleep, but it’s ok enough for me for now.

Hopefully this helps you out if you’re still struggling with this! Took me less than an hour to hook up the temperature probe (though that wasn’t my first time) and the remainder of the day figuring out how to make sleep work reliably :slight_smile:

So far, so good though!

I’ve been messing with the HTTP client library lately and can’t seem to get a response from “if(response.status == 200)” if I’m connected. I do think I’m connected due to the fact that I can see "Serial.println(response.body); " return data. Am I doing this correctly?

response.body:
    <link href="/assets/css/bootstrap.css" rel="stylesheet"/>

    <link href="/assets/css/font-awesome.css" rel="stylesheet"/>

    <link href="/assets/css/custom.css" rel="stylesheet"/>

    <link href="/assets/js/morris/morris-0.4.3.min.css" rel="stylesheet"/>

    <script src="/assets/js/jquery-1.10.2.js"></script>

    <script src="/assets/js/flexiload.js"></script>

    <script src="/assets/js/highstock.js"></script>


    <link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css' />

    <meta name="description" content="The description of my page" />
</head>
<body>
    <div id="wrapper">
        <nav class="navbar navbar-default navbar-cls-top " role="navigation" style="margin-bottom: 0">
            <div class="navbar-header">

My code:

#include "HttpClient.h"

String myID = System.deviceID();
byte mac[6];

unsigned int nextTime = 0;    // Next time to contact the server

HttpClient http;
http_header_t headers[] = {
  //  { "Content-Type", "application/json" },
  //  { "Accept" , "application/json" },
  { 
    "Accept" , "*/*"    }
  ,
  { 
    NULL, NULL     } // NOTE: Always terminate headers will NULL
  //{ "Host","softmeter.meinwebserver.de"},
};

http_request_t request;
http_response_t response;

void setup() {
  pinMode(7, OUTPUT);
  //emon1.current(A3, 111.1);             // Current: input pin, calibration.

  Particle.process();
  Serial.begin(9600);

  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
  WiFi.macAddress(mac);
  Serial.print("MAC Address: ");
  for (int i=0; i<6; i++) {
    if (i) Serial.print(":");
    Serial.print(mac[i], HEX);
  }

}

void loop() {
  double Amps1 = 1;  //dumb data to prove a pass of numbers to home based server
  double Amps2 = 2;
  double Amps3 = 3;
  double Amps4 = 4;
  double Amps5 = 5;
  double Amps6 = 6;
  double Amps7 = 7;
  double Amps8 = 8;
  double Amps9 = 9;
  double Amps10 = 10;

  char buff[200]; 

  if (nextTime > millis()) {            //loop every 10 seconds
    return;
  }
  request.hostname = "192.168.1.2";     //home based server static ip
  request.port = 80;                    //home based server port
  sprintf(buff, "/GrabData/New/?MCID=%s&Amps1=%.1f&Amps2=%.1f&Amps3=%.1f&Amps4=%.1f&Amps5=%.1f&Amps2=6=%.1f&Amps7=%.1f&Amps8=%.1f&Amps9=%.1f&Amps10=%.1f\n",myID.c_str(),Amps1,Amps2,Amps3,Amps4,Amps5,Amps6,Amps7,Amps8,Amps9,Amps10);
  request.path = buff;
  Serial.println("start");
  http.get(request, response, headers);

  digitalWrite(7, HIGH);
  Particle.process();

  Serial.println("response.body:");      //I CAN SEE THE BODY RETURN IN SERIAL
  Serial.println(response.body);         //I CAN SEE THE BODY RETURN IN SERIAL


  if (http.client.connected())           //I never see this loop run
  {
    Serial.print("beginning of loop and milliseconds is ");
    Serial.println(millis());

    Serial.println("response.status:");
    Serial.println(response.status);
  }

  if(response.status == 200)             //I never see this loop run
  {
    Serial.println("Connected");
    Serial.println(response.status);
  }

  digitalWrite(7, LOW);
  nextTime = millis() + 10000;
}

Just print out the status you actually get, this might give you a clue why the "conditional block" (it's not a loop) never gets executed :wink:


You are still using

request.hostname = "192.168.1.2"; 

But - as said in your other question - you should better use

request.ip = IPAddress(192,168,1,2); 
// or
request.ip = {192,168,1,2};

This is even expressed in this thread further up

If you want help, try to apply the suggestions otherwise people will just start ignoring your questions as you are ignoring their well meant advice!

response.status returns 0 if it’s placed outside the if loop. response.status’s output is below the body.

I didn’t change “request.hostname = “192.168.1.2”;” because it is compiling and working and while I was concentrating on the sprintf format you mentioned which helped me out a lot, I didn’t want to change other things that were working. I can do that now though. I appreciate your experience here.

Responses

start
response.body:
    <link href="/assets/css/bootstrap.css" rel="stylesheet"/>

    <link href="/assets/css/font-awesome.css" rel="stylesheet"/>

    <link href="/assets/css/custom.css" rel="stylesheet"/>

    <link href="/assets/js/morris/morris-0.4.3.min.css" rel="stylesheet"/>

    <script src="/assets/js/jquery-1.10.2.js"></script>

    <script src="/assets/js/flexiload.js"></script>

    <script src="/assets/js/highstock.js"></script>


    <link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css' />

    <meta name="description" content="The description of my page" />
</head>
<body>
    <div id="wrapper">
        <nav class="navbar navbar-default navbar-cls-top " role="navigation" style="margin-bottom: 0">
            <div class="navbar-header">
            
response.status
0
end

My code:

#include "HttpClient.h"

String myID = System.deviceID();
byte mac[6];

unsigned int nextTime = 0;    // Next time to contact the server

HttpClient http;
http_header_t headers[] = {
  //  { "Content-Type", "application/json" },
  //  { "Accept" , "application/json" },
  { 
    "Accept" , "*/*"    }
  ,
  { 
    NULL, NULL     } // NOTE: Always terminate headers will NULL
  //{ "Host","softmeter.meinwebserver.de"},
};

http_request_t request;
http_response_t response;

void setup() {
  pinMode(7, OUTPUT);
  //emon1.current(A3, 111.1);             // Current: input pin, calibration.

  Particle.process();
  Serial.begin(9600);

  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
  WiFi.macAddress(mac);
  Serial.print("MAC Address: ");
  for (int i=0; i<6; i++) {
    if (i) Serial.print(":");
    Serial.print(mac[i], HEX);
  }

}

void loop() {
  double Amps1 = 1;  //dumb data to prove a pass of numbers to home based server
  double Amps2 = 2;
  double Amps3 = 3;
  double Amps4 = 4;
  double Amps5 = 5;
  double Amps6 = 6;
  double Amps7 = 7;
  double Amps8 = 8;
  double Amps9 = 9;
  double Amps10 = 10;

  char buff[200]; 

  if (nextTime > millis()) {            //loop every 10 seconds
    return;
  }
  Serial.println();
  Serial.println("start");
  //request.hostname = "192.168.1.2";   //works but could be bad formatting
  //request.ip = {192,168,1.2};         //doesn't compile--error: no match for 'operator=' (operand types are 'IPAddress' and '<brace-enclosed initializer list>')
  request.ip = IPAddress(192,168,1,2);
  request.port = 80;                    //home based server port
  sprintf(buff, "/GrabData/New/?MCID=%s&Amps1=%.1f&Amps2=%.1f&Amps3=%.1f&Amps4=%.1f&Amps5=%.1f&Amps2=6=%.1f&Amps7=%.1f&Amps8=%.1f&Amps9=%.1f&Amps10=%.1f\n",myID.c_str(),Amps1,Amps2,Amps3,Amps4,Amps5,Amps6,Amps7,Amps8,Amps9,Amps10);
  request.path = buff;
  
  http.get(request, response, headers);

  digitalWrite(7, HIGH);
  Particle.process();

  Serial.println("response.body:");      //I CAN SEE THE BODY RETURN IN SERIAL
  Serial.println(response.body);         //I CAN SEE THE BODY RETURN IN SERIAL


  if (http.client.connected())           //I never see this loop run
  {
    Serial.print("beginning of loop and milliseconds is ");
    Serial.println(millis());

    Serial.print("response.status: ");
    Serial.println(response.status);
  }

  //if(response.status == 200)             //I never see this loop run
  //{
    Serial.println("response.status");
    Serial.println(response.status);
  //}

  digitalWrite(7, LOW);
  nextTime = millis() + 10000;
  Serial.println("end");
}

The reason why this doesn't compile is the decimal point (.) where you should have a comma (,).

And the reason why this

builds without error is that hostname expects a string which you do provide, but the compiler does not look at the contents of the string, since it couldn't judge if it's a valid string for your intended use or not anyway.

Just as if you wrote String anEnglishWord = "igvuzkhtfghj"; // it builds but is not valid for the intended use.

For this

  if (http.client.connected())           //I never see this loop run <-- not a loop
  {
    ...
  }

after your finished GET request the client will most likely be closed already, hence the conditional or if block will not be entered, so no surprise that you don't see the printouts.

Looking at your response.body (which I overlooked before :blush:) I'd say it's truncated (I'd guess 512 byte) and hence the status is not OK.
Could you try to cut down the length on your host to see if it then finishes OK?

1 Like

@jaysettle, as usual, @ScruffR’s advice is on the money. If you look at the HTTPClient.cpp code, you will see that after each request, the code calls Client.stop(), closing the server connection, thus supporting @ScruffR’s comments.

You will also notice in HTTPClient.h that a default response buffer of 1024 bytes is defined. You could make this larger if a larger response payload is expected. :smile:

@peekay123, right on I’m looking at the .cpp code now. I see what you’re saying.

@ScruffR, I made an html page containing nothing and called it from the Photon.

sprintf(buff, "/GradData/EmptyPage");

“response.status” does return a 200 after all.

Thanks again.

1 Like

Hmm, I'm a bit confused about the wording :confused:

When reading "after all" I get the feeling that the issue persists, but "does return a 200" suggests the opposite.
So does it work this way or not?

Yes it works great.

1 Like