Search code examples
ajaxhttparduinoesp8266temperature

ESP8266 request multiple HTTP GET simultaneously


I started my first project with the ESP8266.

It's a Temperature Monitor which shows the data on a webserver.

Since I don't want to refresh the page manually to get the new data, I'm using HTTP requests to display it.

I'm sending 3 different requests, one for the current temperature, one for the highest and one for the lowest.

The problem i'm facing is, that the data won't refresh simultaneously, though I am sending all of those at the same time.

That's the code that's sending the requests:

<script>
    function getCurrent() {
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        document.getElementById("current").innerHTML =
        this.responseText;
      }
    };
    xhttp.open("GET", "readCurrent", true);
    xhttp.send();
    }

    function getHigh() {
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        document.getElementById("high").innerHTML =
        this.responseText;
      }
    };
    xhttp.open("GET", "readHigh", true);
    xhttp.send();
    }

    function getLow() {
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        document.getElementById("low").innerHTML =
        this.responseText;
      }
    };
    xhttp.open("GET", "readLow", true);
    xhttp.send();
    }

    setInterval(function() {
      getHigh();
      getLow();
      getCurrent();
    }, 2000);
</script>

And that's the code handling them:

float temp;
float hoechst;
float tiefst;

void handleRoot() {
 String s = MAIN_page; //Read HTML contents
 server.send(200, "text/html", s); //Send web page
}

void handleCurrent() {
  float t = temp;
  server.send(200, "text/plane", String(t));
}

void handleHigh() {
  float high = hoechst;
  server.send(200, "text/plane", String(high));
}

void handleLow() {
  float low = tiefst;
  server.send(200, "text/plane", String(low));
}

void setup() {
  [...]
  server.on("/", handleRoot);
  server.on("/readCurrent", handleCurrent);
  server.on("/readHigh", handleHigh);
  server.on("/readLow", handleLow);
  [...]
}

The Loop is just updating the Temperatures with this function:

void updateTemperatures() {
  sensor.requestTemperatures();
  yield();
  float low = tiefst;
  float high = hoechst;
  float t = sensor.getTempCByIndex(0);
   if(t < low) {
    low = t;
    } else if(t > high) {
      high = t;
      }
   yield();
   temp = t;
   tiefst = low;
   hoechst = high;
  }

And handling the clients (server.handleClient())

So my Question: How can I update the data simultaneously, or is that even possible with the ESP8266?


Solution

  • You update the data simultaneously by returning all three values in one request.

    That would be the way to do it with any web server, let alone one running on an extremely limited processor like the ESP8266.

    You can return all three values at once with code that looks something like this:

    void handleAll() {
      String results_json = "{ \"temperature\": " + String(temp) + ",", +
                               "\"high\": " + String(hoechst) + "," +
                               "\"low\": " + String(tiefst) + " }";
    
      server.send(200, "application/json", results_json);
    }
    

    This composes a JSON object with all three values in it. JSON is "JavaScript Object Notation" and is very easy for Javascript to put together and take apart.

    You'd also need to update your ESP8266 web server code to add

    server.on("/readAll", handleAll);
    

    With this change you can eliminate the other three /read handlers.

    And you'd need to update your Javascript. You'd just need to do one call in Javascript, convert the returned text to a Javascript object and read each of the three values from it to set the elements in the DOM. This is something jQuery can so trivially for you.

    And, it's 'text/plain', not 'text/plane'.

    You might also check out jQuery - it will greatly simplify your Javascript code.