ESP32/ESP8266 Web Server: Control Outputs with Momentary Switch

This tutorial shows how to create a web server with a button that acts as momentary switch to remotely control ESP32 or ESP8266 outputs. The output state is HIGH as long as you keep holding the button in your web page. Once you release it, it changes to LOW. As an example, we’ll control an LED, but you can control any other output.

ESP32 ESP8266 Web Server Control Outputs with Momentary Switch Arduino IDE

The ESP32/ESP8266 boards will be programmed using Arduino IDE. So make sure you have these boards installed:

Project Overview

The following diagram shows a simple overview of the project we’ll build.

Momentary switch web server esp32 esp8266 project overview
  • The ESP32 or ESP8266 hosts a web server that you can access to control an output;
  • The output’s default state is LOW, but you can change it depending on your project application;
  • There’s a button that acts like a momentary switch:
    • if you press the button, the output changes its state to HIGH as long as you keep holding the button;
    • once the button is released, the output state goes back to LOW.

Installing Libraries – Async Web Server

To build the web server you need to install the following libraries:

These libraries aren’t available to install through the Arduino Library Manager, so you need to copy the library files to the Arduino Installation Libraries folder. Alternatively, in your Arduino IDE, you can go to Sketch Include Library > Add .zip Library and select the libraries you’ve just downloaded.

Code

Copy the following code to your Arduino IDE.

/*********
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-esp8266-web-server-outputs-momentary-switch/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*********/

#ifdef ESP32
  #include <WiFi.h>
  #include <AsyncTCP.h>
#else
  #include <ESP8266WiFi.h>
  #include <ESPAsyncTCP.h>
#endif
#include <ESPAsyncWebServer.h>

// REPLACE WITH YOUR NETWORK CREDENTIALS
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

const int output = 2;

// HTML web page
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
  <head>
    <title>ESP Pushbutton Web Server</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
      body { font-family: Arial; text-align: center; margin:0px auto; padding-top: 30px;}
      .button {
        padding: 10px 20px;
        font-size: 24px;
        text-align: center;
        outline: none;
        color: #fff;
        background-color: #2f4468;
        border: none;
        border-radius: 5px;
        box-shadow: 0 6px #999;
        cursor: pointer;
        -webkit-touch-callout: none;
        -webkit-user-select: none;
        -khtml-user-select: none;
        -moz-user-select: none;
        -ms-user-select: none;
        user-select: none;
        -webkit-tap-highlight-color: rgba(0,0,0,0);
      }  
      .button:hover {background-color: #1f2e45}
      .button:active {
        background-color: #1f2e45;
        box-shadow: 0 4px #666;
        transform: translateY(2px);
      }
    </style>
  </head>
  <body>
    <h1>ESP Pushbutton Web Server</h1>
    <button class="button" onmousedown="toggleCheckbox('on');" ontouchstart="toggleCheckbox('on');" onmouseup="toggleCheckbox('off');" ontouchend="toggleCheckbox('off');">LED PUSHBUTTON</button>
   <script>
   function toggleCheckbox(x) {
     var xhr = new XMLHttpRequest();
     xhr.open("GET", "/" + x, true);
     xhr.send();
   }
  </script>
  </body>
</html>)rawliteral";

void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Not found");
}

AsyncWebServer server(80);

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("WiFi Failed!");
    return;
  }
  Serial.println();
  Serial.print("ESP IP Address: http://");
  Serial.println(WiFi.localIP());
  
  pinMode(output, OUTPUT);
  digitalWrite(output, LOW);
  
  // Send web page to client
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html);
  });

  // Receive an HTTP GET request
  server.on("/on", HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(output, HIGH);
    request->send(200, "text/plain", "ok");
  });

  // Receive an HTTP GET request
  server.on("/off", HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(output, LOW);
    request->send(200, "text/plain", "ok");
  });
  
  server.onNotFound(notFound);
  server.begin();
}

void loop() {
 
}

View raw code

You just need to enter your network credentials (SSID and password) and the web server will work straight away. The code is compatible with both the ESP32 and ESP8266 boards and controls the on-board LED GPIO 2 – you can change the code to control any other GPIO.

How the Code Works

We’ve already explained in great details how web servers like this work in previous tutorials (DHT Temperature Web Server), so we’ll just take a look at the relevant parts for this project.

Network Credentials

As said previously, you need to insert your network credentials in the following lines:

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Momentary Switch Button (web server)

The following line creates the momentary switch button.

<button class="button" onmousedown="toggleCheckbox('on');" ontouchstart="toggleCheckbox('on');" onmouseup="toggleCheckbox('off');" ontouchend="toggleCheckbox('off');">LED PUSHBUTTON</button>

Let’s break this down into small parts.

In HTML, to create a button, use the <button></button> tags. In between you write the button text. For example:

<button>LED PUSHBUTTON</button>

The button can have several attributes. In HTML, the attributes provide additional information about HTML elements, in this case, about the button.

Here, we have the following attributes:

class: provides a class name for the button. This way, it can be used by CSS or JavaScript to perform certain tasks for the button. In this case, it is used to format the button using CSS. The class attribute has the name “button”, but you could have called it any other name.

<button class="button">LED PUSHBUTTON</button>

onmousedown: this is an event attribute. It executes a JavaScript function when you press the button. In this case it calls toggleCheckbox(‘on’). This function makes a request to the ESP32/ESP8266 on a specific URL, so that it knows it needs to change the output state to HIGH.

ontouchstart: this is an event attribute similar to the previous one, but it works for devices with a touch screen like a smartphone or table. It calls the same JavaScript function to change the output state to HIGH.

onmouseup: this is an event attribute that executes a JavaScript function when you release the mouse over the button. In this case, it calls toggleCheckbox(‘off’). This function makes a request to the ESP32/ESP8266 on a specific URL, so that it knows it needs to change the output state to LOW.

ontouchend: similar to the previous attribute but for devices with touchscreen.

So, in the end, our button looks like this:

<button class="button" onmousedown="toggleCheckbox('on');" ontouchstart="toggleCheckbox('on');" onmouseup="toggleCheckbox('off');" ontouchend="toggleCheckbox('off');">LED PUSHBUTTON</button>

HTTP GET Request to Change Button State (JavaScript)

We’ve seen previously, that when you press or release the button, the toggleCheckbox() function is called. You either pass the “on” or “off” arguments, depending on the state you want.

That function, makes an HTTP request to the ESP32 either on the /on or /off URLs:

function toggleCheckbox(x) {
  var xhr = new XMLHttpRequest();
  xhr.open("GET", "/" + x, true);
  xhr.send();
}

Handle Requests

Then, we need to handle what happens when the ESP32 or ESP8266 receives requests on those URLs.

When a request is received on the /on URL, we turn the GPIO on (HIGH) as shown below:

server.on("/on", HTTP_GET, [] (AsyncWebServerRequest *request) {
  digitalWrite(output, HIGH);
  request->send(200, "text/plain", "ok");
});

When a request is received on the /off URL, we turn the GPIO off (LOW):

server.on("/off", HTTP_GET, [] (AsyncWebServerRequest *request) {
  digitalWrite(output, LOW);
  request->send(200, "text/plain", "ok");
});

Demonstration

Upload the code to your ESP32 or ESP8266 board.

Then, open the Serial Monitor at a baud rate of 115200. Press the on-board EN/RST button to get is IP address.

ESP32 ESP8266 Web Server Demonstration IP Address Arduino IDE Serial Monitor

Open a browser on your local network, and type the ESP IP address. You should have access to the web server as shown below.

Momentary Switch Web Server ESP32 and ESP8266 Arduino IDE Demonstration

The on-board LED stays on as long as you keep holding down the button on the web page.

Note: it works the other way around for the ESP8266 because the on-board LED works with inverted logic.

ESP32 board Built in LED turned on HIGH

When you release the button, the LED goes back to its default state (LOW).

ESP32 board Built in LED turned off LOW

Watch the next quick video for a live demonstration:


Wrapping Up

In this tutorial you’ve learned how to add event attributes to the buttons on your web server to make them act as momentary switches. This allows you to change the default’s output state as long as you’re pressing the button.

Other projects you may like:

Learn more about the ESP32 and ESP8266 with our resources:

Thanks for reading.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Enjoyed this project? Stay updated by subscribing our newsletter!

65 thoughts on “ESP32/ESP8266 Web Server: Control Outputs with Momentary Switch”

  1. I have tried the ESP32 project first with interest without any adaptation to the script. I noticed that the LED often stays on after a short press of the button and although the button was released. I was planning to use it as a pulse relay but it doesn’t work as expected. Maybe there is another solution for a pulse relay?

    Reply
    • Hi all, how arw you?. As an addition to this post, I had the same problem when using the web page from a cellphone, for me and after try several options and searching the web, the option was to remove the touchevents from the button properties. That was enough for having the control working well from cellphones and computers. Right now I didn’t try it maybe the problem could be that the button is sending both the touch events and mouse events when used form a tactile interface while in a not tactile interface it sends only the mouse events.

      Reply
  2. Sorry to bother but you have a small mistake in the code.
    The logical values applied to the LED pin should be inverted due to internal pullup!

    Thank you

    Reply
    • Hi, I made my project work thanks to you and I totally forgot I had made this comment in the beginning of its development. I was just scrolling around to show your website to a colleague and realized that it came out totally wrong! I meant to make a question and not at all doubt your work. In conclusion, nevermind my poor comment.

      Thanks a lot for your help and keep up your excelent work!

      Reply
    • Hello Edo. That’s the normal behavior and if you see that message your code has been uploaded successfully. Just restart your board to run the newly uploaded code!

      Reply
  3. I have to short tap the button on the web page to get the blue on board light to come back on. When I press and hold the button it will stay off, but flickers & wont come back on when I release, unless I give it a short tap, then it comes on (Im using an ESP8266). Is there a modification to make it more reliable/stable ?
    Thanks

    Reply
  4. I tried a PC web page and it works fine. Its just not detecting when I release the button on my touch screen iphone. I can see the graphical button lifting up though when I take my finger off the button. Something about the touch interface

    Reply
    • Hi Stephen.
      Yes, it must be a problem with the touch interface. However, I don’t know what might be the problem.
      Can you try adding the ontouchcancel event to the button element like this:
      ontouchcancel = “toggleCheckbox(‘off’);”
      ?
      REgards,
      Sara

      Reply
      • Hi
        Just tried this project. It works great on PC and android but not on iphone. The led on the esp8266 does’nt turn on and off like it should on iphone. I tried the ontouchcancel = “toggleCheckbox(‘off’);” but it was the same.

        Reply
  5. Hello,
    Can someone help me with the coding
    since I have the example above (which was very useful)
    i would like to put more buttons and GPIO Pins how would I be able to do it i would highly appreciate your help,
    FYI: I am new so learning.

    Reply
  6. Hello,
    I used this example to operate my garage door, perfect it’s operational. Using a sensor (example GPIO35 from ESP32), I would like to know the state of the door and display “door open” and “door closed” under the button “LEDPUSHBUTTON”. Someone could help me because I don’t understand HTML well.
    Thank you.

    Reply
    • Hello,
      Automation of a garage door only becomes interesting if it can be operated and observed outside the local network. This requires internet access which makes things more complex. Usually a cloud server (e.g. Blynk) is used to make the bridge: the door is operated with a pulse relay and the status (reed contact open / close) is reported back in the app. Further automation is then optional such as automatic closing after a certain time interval or time in the evening. All this can be programmed on an ESP microcontroller (Arduino IDE). Unfortunately, different modules have to be cobbled together in the program or searched for ready-made .ino files for ESP8266 or ESP32.
      Hopefully one day RNT will offer an integrated solution for the “garage door” as this is one of the most requested home automation solutions by starting DIYers.

      Regards

      Reply
  7. How can i use same time both momentary and switch relays , like 2 relay momentary and 2 relays switch.
    Or all relays the same .. when hold button down 3 sec then its switch and when pushed momentary like 1 sec then its momentary relay.

    Reply
  8. Hello 🙂 i love to read your tutorials but i dont understand to mix 3 setups together 🙁
    i need for my esp32:
    -static ip adress
    -1x momentary switch with relay output
    -1x normal switch with relay output
    can you help me? i break my head for this Projekt 🙂
    Gruess Axel

    Reply
  9. Hello guys , nice site and best tutorials ever .
    I have found all the thing i need here .
    I am new to Arduino and esp
    But i have a question:
    How to assign other gpio pin?
    This will do the trick?


    // Set to true to define Relay as Normally Open (NO)
    #define RELAY_NO true

    // Set number of relays
    #define NUM_RELAYS 1

    // Assign each GPIO to a relay
    int relayGPIOs[NUM_RELAYS] = {3};

    This is also from your code, from other tutorial , as i see it for 1 relay.
    This will set 1 relay NO at Gpio 3?

    Reply
  10. great tutorial.
    is any possibilities to make 4 buttons in different position like gamepad buttons
    each button placed on top left right and bottom
    thanks

    Reply
  11. Hi,

    I modified the code, so I can arrange position the buttons.
    on global variable I declared GPIO
    const int up= 2; //Up
    const int down= 3; //Down
    const int left= 4; //LEFT
    const int right= 5; //RIGHT

    on setup function added
    server.on(“/”, HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, “text/html”, index_html);
    });

    // Receive an HTTP GET request
    server.on(“/on”, HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(up, HIGH);
    request->send(200, “text/plain”, “ok”);
    });

    // Receive an HTTP GET request
    server.on(“/off”, HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(up, LOW);
    request->send(200, “text/plain”, “ok”);
    });

    // Receive an HTTP GET request
    server.on(“/on”, HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(down, HIGH);
    request->send(200, “text/plain”, “ok”);
    });

    // Receive an HTTP GET request
    server.on(“/off”, HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(down, LOW);
    request->send(200, “text/plain”, “ok”);
    });

    // Receive an HTTP GET request
    server.on(“/on”, HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(left, HIGH);
    request->send(200, “text/plain”, “ok”);
    });

    // Receive an HTTP GET request
    server.on(“/off”, HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(right, LOW);
    request->send(200, “text/plain”, “ok”);
    });

    but the GPIO 3, 4 and 5 state doesn’t change from HIGH to LOW vice versa

    do you have any suggestions how to make GPIO 3, 4 and 5 work the same as GPIO 2 when the button is pressed and released…..
    really appreciate if someone can help me

    thanks

    Reply
  12. What do I need to change to replace “digitalWrite(output, HIGH);” with sequence of servo moves?
    Changing 1:1 only executes 1st servo move, than stops

    server.on(“/on”, HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(output, HIGH);
    request->send(200, “text/plain”, “ok”);
    });

    Reply
  13. Hi,
    Thanks for this tutorial. Can you please help me to create two momentary pushbutton for two led in a web interface using nodemcu?
    Thanks Again!

    Reply
  14. Hi,
    Thanks for this tutorial. I modifed this project. I added more three buttons with same function, also ather fixed state buttons. But know I need to add pin status in web html page. For this tutorial for exemple I need to add in the web digitalRead(2). How to do that?

    Reply
  15. Cannot seem to install ESP8266WiFi. I installed the library, however when compiling, I receive an error that ESP8266WiFi.h cannot be found.
    What do I need to do. I even went into Arduino docs and enetered the infro for additional boards, no good.

    Reply
    • Hi.
      That library is part of the ESP8266 core by default. You don’t need to install it.
      Just make sure you’ve selected ann ESP8266 board in Tools > Board.

      Regards,
      Sara

      Reply
  16. Great Website!
    I installed the code for the project “ESP8266 Webserver with control outputs with momentary switch”. Works well. Question, I want to add two more buttons. But the Get statement does not have a variable attached as far as I see. In the past I’ve seen “if currentline.endswith(“Get/H”))
    and it is easy to add “Get/L” or “Get/U” and so on, to add buttons
    How do I add another button in this sketch?
    Thanks
    Mike

    Reply
  17. Thank you for the tutorial. very detailed and clear explanation.

    I have tried to use %placeholder% to update the color of the push button relative to the state of a bit in the arduino program but i couldn’t get it to work.

    Appreciate if you could guide me.
    thanks,

    Reply
    • Hi.
      You need to provide more details.
      How did you do that? Did you get any errors?
      What is not working exactly?
      Regards,
      Sara

      Reply
      • Hello sara…great article. I have tried and it works perfectly. can you help me to get this working using mqtt? so I can control it from anywhere. Thank you for your help and success always

        Reply
  18. Hello sara…great article. I have tried and it works perfectly. can you help me to get this working using mqtt? so I can control it from anywhere. Thank you for your help and success always

    Reply
  19. Thank You verymuch for your’s project.. It work fine on dektop browser but bouncing on Android and Iphone… Any solution for this? thankyou

    Reply
  20. just what I was looking for, great work as usual
    I read a lot of requests here for ading buttons
    well after about an hour I think I have it
    One button controls led 2 the second controls led16 and the third controls both
    Have no smart phone so I removed the touch commands
    thanks for your tutoials, Bob

    /*********
    Rui Santos
    Complete project details at https://RandomNerdTutorials.com/esp32-esp8266-web-server-outputs-momentary-switch/

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files.

    The above copyright notice and this permission notice shall be included in all
    copies or substantial portions of the Software.
    *********/
    #ifdef ESP32
    #include <WiFi.h>
    #include <AsyncTCP.h>
    #else
    #include <ESP8266WiFi.h>
    #include <ESPAsyncTCP.h>
    #endif
    #include <ESPAsyncWebServer.h>

    // REPLACE WITH YOUR NETWORK CREDENTIALS
    const char* ssid = “ssid”;
    const char* password = “password”;
    const int output = 2;
    const int output2 = 16;

    // HTML web page
    const char index_html[] PROGMEM = R”rawliteral(

    ESP Pushbutton Web Server

    body { font-family: Arial; text-align: center; margin:0px auto; padding-top: 30px;}
    .button {
    padding: 10px 20px;
    font-size: 24px;
    text-align: center;
    outline: none;
    color: #fff;
    background-color: #2f4468;
    border: none;
    border-radius: 5px;
    box-shadow: 0 6px #999;
    cursor: pointer;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    -webkit-tap-highlight-color: rgba(0,0,0,0);
    }
    .button:hover {background-color: #1f2e45}
    .button:active {
    background-color: #1f2e45;
    box-shadow: 0 4px #666;
    transform: translateY(2px);
    }
    .button2 {
    padding: 10px 20px;
    font-size: 24px;
    text-align: center;
    outline: none;
    color: #fff;
    background-color: #2f4468;
    border: none;
    border-radius: 5px;
    box-shadow: 0 6px #999;
    cursor: pointer;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    -webkit-tap-highlight-color: rgba(0,0,0,0);
    }
    .button2:hover {background-color: #1f2e45}
    .button2:active {
    background-color: #1f2e45;
    box-shadow: 0 4px #666;
    transform: translateY(2px);
    }
    .button3 {
    padding: 10px 20px;
    font-size: 24px;
    text-align: center;
    outline: none;
    color: #fff;
    background-color: #2f4468;
    border: none;
    border-radius: 5px;
    box-shadow: 0 6px #999;
    cursor: pointer;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    -webkit-tap-highlight-color: rgba(0,0,0,0);
    }
    .button3:hover {background-color: #1f2e45}
    .button3:active {
    background-color: #1f2e45;
    box-shadow: 0 4px #666;
    transform: translateY(2px);
    }

    ESP Pushbutton Web Server
    LED2 PUSHBUTTON
    LED16 PUSHBUTTON
    EXTRA PUSHBUTTON

    function toggleCheckbox(x) {
    var xhr = new XMLHttpRequest();
    xhr.open(“GET”, “/” + x, true);
    xhr.send();
    }

    )rawliteral”;

    void notFound(AsyncWebServerRequest *request) {
    request->send(404, “text/plain”, “Not found”);
    }

    AsyncWebServer server(80);

    void setup() {
    Serial.begin(115200);
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
    if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println(“WiFi Failed!”);
    return;
    }
    Serial.print(“ESP IP Address: http://“);
    Serial.println(WiFi.localIP());

    pinMode(output, OUTPUT);
    digitalWrite(output, HIGH);
    pinMode(output2, OUTPUT);
    digitalWrite(output2, HIGH);

    // Send web page to client
    server.on(“/”, HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, “text/html”, index_html);
    });

    // Receive BTN HTTP GET request
    server.on(“/on”, HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(output, LOW);
    request->send(200, “text/plain”, “ok”);
    });
    // Receive BTN HTTP GET request
    server.on(“/off”, HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(output, HIGH);
    request->send(200, “text/plain”, “ok”);
    });

    // Receive BTN2 HTTP GET request
    server.on(“/on2”, HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(output2, LOW);
    request->send(200, “text/plain”, “ok”);
    });
    // Receive BTN2 HTTP GET request
    server.on(“/off2”, HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(output2, HIGH);
    request->send(200, “text/plain”, “ok”);
    });

    // Receive BTN3 HTTP GET request
    server.on(“/on3”, HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(output2, LOW);
    digitalWrite(output, LOW);
    request->send(200, “text/plain”, “ok”);
    });
    // Receive BTN3 HTTP GET request
    server.on(“/off3”, HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(output2, HIGH);
    digitalWrite(output, HIGH);
    request->send(200, “text/plain”, “ok”);
    });

    server.onNotFound(notFound);
    server.begin();
    }

    void loop() {
    chk_pump_led_status();
    chk_solar_led_status();
    }

    void chk_pump_led_status()
    {
    if (digitalRead(2) == HIGH ) { //led status pushes rx_data
    Serial.print(“led2 = 0 “);
    }
    else {
    Serial.print(“led2 = 1 “);
    }
    }

    void chk_solar_led_status()
    {
    if (digitalRead(16) == HIGH ) { //led status pushes rx_data
    Serial.println(“led16 = 0”);
    }
    else {
    Serial.println(“led16 = 1”);
    }
    }

    Reply
    • I was really hoping the code you posted would compile, as I am also trying to get two buttons to work like the one in the example.
      The compiler chokes on line 27:
      const char index_html[] PROGMEM = R”rawliteral(
      and I can’t understand the html differences thereafter. Is there a missing punctuation mark or something in the code you posted?
      I have been at this for hours and the html code is just beyond me.

      Reply
      • Update: i had some help with the compiler error messages, and it turns out there are 2 different sets of ” in the text of the code above. Selecting the first instance of an open quotation mark and replacing all with one typed in, then doing the same for the closed one allowed the code to compile.
        Next problem: The webpage created on the ESP8266 just shows the html text when displayed on a mobile phone screen; no formatting, no buttons. Another dead end.

        Reply
        • hey Gary there seems to be some kind of cut and paste error with my my code
          it was cut N pasted directly from the arduino listing
          here (and I hope it comes in as I copied it) is what the webpage code is
          you will see the difference after the first line:
          // HTML web page
          const char index_html[] PROGMEM = R”rawliteral(

          ESP Pushbutton Web Server

          body { font-family: Arial; text-align: center; margin:0px auto; padding-top: 30px;}
          .button {
          padding: 10px 20px;
          font-size: 24px;
          text-align: center;
          outline: none;
          color: #fff;
          background-color: #2f4468;
          border: none;
          border-radius: 5px;
          box-shadow: 0 6px #999;
          cursor: pointer;
          -webkit-touch-callout: none;
          -webkit-user-select: none;
          -khtml-user-select: none;
          -moz-user-select: none;
          -ms-user-select: none;
          user-select: none;
          -webkit-tap-highlight-color: rgba(0,0,0,0);
          }
          .button:hover {background-color: #1f2e45}
          .button:active {
          background-color: #1f2e45;
          box-shadow: 0 4px #666;
          transform: translateY(2px);
          }
          .button2 {
          padding: 10px 20px;
          font-size: 24px;
          text-align: center;
          outline: none;
          color: #fff;
          background-color: #2f4468;
          border: none;
          border-radius: 5px;
          box-shadow: 0 6px #999;
          cursor: pointer;
          -webkit-touch-callout: none;
          -webkit-user-select: none;
          -khtml-user-select: none;
          -moz-user-select: none;
          -ms-user-select: none;
          user-select: none;
          -webkit-tap-highlight-color: rgba(0,0,0,0);
          }
          .button2:hover {background-color: #1f2e45}
          .button2:active {
          background-color: #1f2e45;
          box-shadow: 0 4px #666;
          transform: translateY(2px);
          }
          .button3 {
          padding: 10px 20px;
          font-size: 24px;
          text-align: center;
          outline: none;
          color: #fff;
          background-color: #2f4468;
          border: none;
          border-radius: 5px;
          box-shadow: 0 6px #999;
          cursor: pointer;
          -webkit-touch-callout: none;
          -webkit-user-select: none;
          -khtml-user-select: none;
          -moz-user-select: none;
          -ms-user-select: none;
          user-select: none;
          -webkit-tap-highlight-color: rgba(0,0,0,0);
          }
          .button3:hover {background-color: #1f2e45}
          .button3:active {
          background-color: #1f2e45;
          box-shadow: 0 4px #666;
          transform: translateY(2px);
          }

          ESP Pushbutton Web Server
          LED2 PB
          LED16 PB
          EXTRA PB

          function toggleCheckbox(x) {
          var xhr = new XMLHttpRequest();
          xhr.open(“GET”, “/” + x, true);
          xhr.send();
          }

          )rawliteral”;

          void notFound(AsyncWebServerRequest *request) {
          request->send(404, “text/plain”, “Not found”);
          }

          I dont know why the original was missing code

          hope this works and here are my versions of libraries I’m using
          Used: C:\Users\User\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WiFi
          Not used: C:\Users\User\Documents\Arduino\libraries\ESP8266WiFi
          Using library ESP8266WiFi at version 1.0 in folder: C:\Users\User\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WiFi
          Using library ESPAsyncTCP-master at version 1.2.2 in folder: C:\Users\User\Documents\Arduino\libraries\ESPAsyncTCP-master
          Using library ESPAsyncWebServer at version 1.2.3 in folder: C:\Users\User\Documents\Arduino\libraries\ESPAsyncWebServer

          Reply
  21. muy buenos los tutoriales, en esta ocasión, tengo un problema: cuando ejecuto un codigo en el void loop… ya no puedo acceder al la pagina del servidor web. Tendré que duplicar algun codigo para que se ejecute tambien en el loop. Gracias

    Reply
  22. Hello thank you and congratulations on your great work. I am a fan.

    I’m using this code to make my kettle “smart”. I already wired everything and the server works great, except that. When I power the ESP for the first time the GPIO states is HIGH for as long as it takes to connect to the wifi so my only solution is to connect my kettle button only after the board finished initializing. Do you know a workaround for this issue? Or this is something I might live with? I’m controlling the kettle with a MOSFET, and I modified the code so it brefiely closes the circuit of the button simulating a real push. But if the power goes off (or if I intend to power the ESP with the voltage on the kettle, it might turn on accidentally and I don’t want that to happen.

    Any ideas?

    Reply
  23. Hello! Thanks for sharing such a wonderful article. This is working well when I provide internet connection to ESP32 using my mobile phone’s hotspot and accessing ip address by opening browser in mobile phone. But it is not working when I am trying to access through a browser in my laptop with is connected to my home wifi. Web page is showing ‘unable to reach this page’. Please help to control my ESP32 from any device.

    Reply
  24. Would you please tell me how the entire code can reside in the setup(). What I thought is that the setup() code runs only once. If I were right, then ESP32 should not be responding to all those button presses again and again.

    Reply

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.