Esp8226 external switch update to web server with

I have found several codes that explain how to have data updated to a webserver via AJAX, but I can't seem to figure out how to have an external switch that is an input_pullup update the server with its current state:

For example: I press a button. The button goes goes Low. The esp device detects that it is low and performs some action including updating the webserver of its status via AJAX.

If i put in the loop
if (digitalRead button == LOW){
What goes here? to send the status to the webserver?
}
Here is a sample code that uses: AJAX to update the status after a button click, but how do i modify it to update the status of an external button?


#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

ESP8266WebServer server;
uint8_t pin_led = 16;
char* ssid = "";
char* password = "";

char webpage[] PROGMEM = R"=====(
<html>
<head>
</head>
<body>
<p> LED Status: <span id="led-state">__</span> </p>
<button onclick="myFunction()"> TOGGLE </button>
</body>
<script>
function myFunction()
{
  console.log("button was clicked!");
  var xhr = new XMLHttpRequest();
  var url = "/ledstate";
  xhr.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("led-state").innerHTML = this.responseText;
    }
  };
  xhr.open("GET", url, true);
  xhr.send();
};
document.addEventListener('DOMContentLoaded', myFunction, false);
</script>
</html>
)=====";

void setup()
{
  pinMode(pin_led, OUTPUT);
  WiFi.begin(ssid,password);
  Serial.begin(115200);
  while(WiFi.status()!=WL_CONNECTED)
  {
    Serial.print(".");
    delay(500);
  }
  Serial.println("");
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());

  server.on("/",[](){server.send_P(200,"text/html", webpage);});
  server.on("/ledstate",getLEDState);
  server.begin();
}

void loop()
{
  server.handleClient();
}

void toggleLED()
{
  digitalWrite(pin_led,!digitalRead(pin_led));
}

void getLEDState()
{
  toggleLED();
  String led_state = digitalRead(pin_led) ? "ON" : "OFF";
  server.send(200,"text/plain", led_state);
}

Thanks!

I figured out how to have a web server updated automatically without refresh using AJAX. within the webpage script, I have a variable (timeM)

</div>
Time is: <span id="timeM">0</span>
<script>

This variable is sent from a function like this:

setInterval(function() 
{
  getData();
}, 700); 
function getData() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("timeM").innerHTML =
      this.responseText;
    }
  };
  xhttp.open("GET", "readALL", true);
  xhttp.send();
}

which gathers data from a "regular" function like this:

void handleALL() {
  timeClient.update();
  
  Second = (timeClient.getSeconds());
  Minute = (timeClient.getMinutes());
  Hour = (timeClient.getHours());
  if (Hour > 12){
    Hour = Hour - 12;  
  }
  
  String nValue = String (Hour);
  String mValue = String (Minute);
  String sValue = String (Second);
  
  String AllDev = String(Hour) + ":" + String(Minute) + "::" + String(Second);
  server.send(200, "text/plain", AllDev); //Send ADC values only to client ajax request
}

What I don't understand is the only way the page is updated is if the variable is changed from within the handleALL();

How do you make something that is read/changed within void loop() make changes to the webserver via AJAX?

Thanks!

AJAX is happening on your client, not your webserver. It is the client that sends requests and gets updated information. Pressing a button on the webserver may alter some state of the webserver but if the client doesn't ask, the webserver does not PUSH new information to the client. Your example of a timer is not the web server updating. The client sees the timer expire and issues another GET to the webserver to update.

Thanks for explaining. That does make more sense. So is there no way to have the webserver PUSH information to a client if say an external switch is triggered? Maybe this makes sense?

Thanks for the help!

Nope. PUSHING in not how HTTP server/client actions happen.

I think you have some misunderstanding about AJAX.

This is what I would do. Use php to update a database.

I don't have time to write the the whole code for it but you might be able to find a project like this online. I'll give you the basic steps for you to get an idea.

  1. Setup a web server (Use something like XAMPP).
  2. Create a MySQL database.
  3. Create a .php file that updates the MySQL database by receiving data via a GET request.
  4. Use your ESP8266 to send the GET request containing your data.

So when your ESP8266 sends data via a GET request, your .php file takes them and puts them in the database. Then you can show the data in the database on a webpage. You can also create an API and use AJAX to show it on a web page and update the data without refreshing the page.

If you have no idea about what I'm talking about, search YouTube with "Send Data From ESP8266 to MySQL Database" you will find so many projects and tutorials.

Hope this helps. Good Luck!

Thanks! It is a bit over my head, so I will be doing the google search you suggested!

I did come up with a a way to have the variables updated to a webserver with a time interval (AJAX). So I think now, I can create a String that is updated when my physical button is pressed which will in turn be updated on the webserver at the time interval in the code.....I do understand better now that it isn't pushing the information, but I am able to request it at a set time interval and then GET it with this:

String SendHTML(byte Hour,byte Minute,byte Second){
  String ptr = "<!DOCTYPE html> <html>\n";
  ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
ptr +="<title>ESP8266 Temperature Monitor</title>\n";
ptr +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
ptr +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;}\n";
ptr +="p {font-size: 24px;color: #444444;margin-bottom: 10px;}\n";
ptr +="</style>\n";

ptr +="<script>\n";
ptr +="setInterval(loadDoc,1000);\n";
ptr +="function loadDoc() {\n";
ptr +="var xhttp = new XMLHttpRequest();\n";
ptr +="xhttp.onreadystatechange = function() {\n";
ptr +="if (this.readyState == 4 && this.status == 200) {\n";
ptr +="document.body.innerHTML =this.responseText}\n";
ptr +="};\n";
ptr +="xhttp.open(\"GET\", \"/\", true);\n";
ptr +="xhttp.send();\n";
ptr +="}\n";
ptr +="</script>\n";

I have seen webpages built using ptr += and page+=.... What is the difference?

Also, If I want to add a button to click on the same website as was created in the code above how would I add the button?

Thanks all!