[HELP] try to controll lamp with button and web, but button not working at start

The push button not working when the device boot up,
After I open the link (http://ipadress:80/lamp?=ON), the push button work perfectly.

here is my code :

#include <ESP8266WiFi.h>
 
const char* ssid = "ssid";
const char* password = "pass";

#define button3_pin D3
#define lamp_pin D4

int lamp = LOW;
 
WiFiServer server(80);
 
void setup() {
  Serial.begin(115200);
  pinMode(button3_pin, INPUT_PULLUP);
  pinMode(lamp_pin, OUTPUT);
  digitalWrite(lamp_pin, HIGH);
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  
  Serial.println("");
  Serial.println("WiFi connected");
 
  // Start the server
  server.begin();
  Serial.println("Server started");
 
  // Print the IP address
  Serial.print("Use this URL to connect: ");
  Serial.print("http://");
  Serial.print(WiFi.localIP());
  Serial.println("/");
 
}
 
void loop() {
  WiFiClient client = server.available();
  if (!client) {
    return;
  }

  // Wait until the client sends some data
  Serial.println("new client");
  while(!client.available()){
    delay(1);
    
    if (button3_pin == LOW) { 
    lamp = !lamp;
    digitalWrite(lamp_pin, lamp);
  }
    
  }
 
  // Read the first line of the request
  String request = client.readStringUntil('\r');
  Serial.println(request);
  client.flush();
 
  // Match the request
 
  if (request.indexOf("/lamp=OFF") != -1)  {
    lamp = HIGH;
  }
  if (request.indexOf("/lamp=ON") != -1)  {
    lamp = LOW;
  }

  digitalWrite(lamp_pin, lamp);  
  
  // Return the response
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println(""); //  do not forget this one
  client.println("<!DOCTYPE HTML>");
  client.println("<html>");
 
  client.print("LAMP: ");
 
  if(lamp == HIGH) {
    client.print("OFF");
  } else {
    client.print("ON");
  }
  client.println("<br><br>");
  client.println("<a href=\"/lamp=ON\"\"><button>ON </button></a>");
  client.println("<a href=\"/lamp=OFF\"\"><button>OFF </button></a><br />");  
  client.println("<br><br>");

  client.println("</html>");
 
  delay(1);
  Serial.println("Client disonnected");
  Serial.println("");
}

this code based on (NodeMcu-Esp8266-Homebridge-Switch/NODEMCU_CODE.ino at master · EshamAaqib/NodeMcu-Esp8266-Homebridge-Switch · GitHub). I try to add the push button, and I realize there is "while" command, I try to put the push button code on any line, but it still don't work at start. I need help, how to fix it?

#define button3_pin 0

Pin 0 is used for Serial communication... pick another pin.

button3_pin is the pin #. the state of the pin must be read using digitalRead (button3_pin). that state must then be checked for some event -- the state has changed and the button is pressed, LOW. also debounce (i.e. delay(10))

the other problem is the logic is only conditionally executed while the client is not available ???? checking the button press should be independent of the client and server. not sure about that logic

okay, I'll change to another pin, thanks

#define button3_pin 0
#define lamp_pin 2

What type of esp8266 board are you using?

What are the labels next to the pins that the button and led are connected to? For example is the led connected to the pin labeled "2" or "D2" ?

noted, thanks for suggestions. I'll implement the code from ESP32/ESP8266 Control Outputs with Web Server and Push Button (microcontrollerslab.com)

int data = digitalRead(button3_pin);
  if (data != lastbutton_state) {
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (data != button_state) {
      button_state = data;
      if (button_state == HIGH) {
        lamp = !lamp;
      }
    }
  }

  digitalWrite(lamp_pin, lamp);
  lastbutton_state = data;

I put the button below

while(!client.available())

because this is the last try to make the button work, previously I put (the button code) in the first line and last line in void loop but it doesn't work. I assume the code were loop in that line, so I put it there.

Its Wemos D1 mini
GPIO0 is D3
GPIO2 is D4

The built-in led is on pin D4 , and it is inverted. if I'm pulling D4 LOW anywhere in my sketch the led will be on.

button code can be simpler

const byte button3_pin = A1;
const byte lamp_pin    = 13;

byte button_state;
byte lamp;

void
setup (void)
{
    pinMode (lamp_pin,    OUTPUT);
    pinMode (button3_pin, INPUT_PULLUP);
    button_state = digitalRead (button3_pin);
}

void
loop (void)
{
    int data = digitalRead(button3_pin);
    if (data != button_state) {
        button_state = data;
        delay (10);             // debounce

        if (button_state == LOW)
            lamp = ! lamp;
    }

    digitalWrite(lamp_pin, lamp);
}

Thank you so much, I really apreciate it

In that case, it would be better to use

#define button3_pin D3
#define lamp_pin D4

This is less confusing for everyone, and no-one will think you connected the button to the RX pin (on Uno, pin 0 is the RX pin).

Okay, I never try the Arduino Uno, so I don't know about it. Sorry :sweat_smile:

I found the solution,

Place the button code

 if (!client) {
    //BUTTON CODE HERE
    return;
  }

and

  while(!client.available()){
   //BUTTON CODE HERE
  }

don't see why the button code should be conditional on client.
the client code should toggle the lamp flag as needed.

independent of both the button code and the client, the lamp pin is set depending on the state of the lamp flag which can be toggled by either the client or button