D1 mini esp8266 web server control 2or more pins ?

(sorry for my english, I use a translator)
Hello everyone. I have a question about the code because I have the web server code shown below and I don't know how to change the code to control 2 or 3 pins with one button?
Previously I used BLYNK and I changed the code so that I could turn on 3 pins with one button:

BLYNK_WRITE(V0){
  int value = param.asInt();
  value ? digitalWrite(D1, HIGH) : digitalWrite(D1, LOW);
  value ? digitalWrite(D0, HIGH) : digitalWrite(D0, LOW); //zwykla
  value ? digitalWrite(D5, HIGH) : digitalWrite(D5, LOW); //zwykla
  }

However, in this case I don't know how to do it because honestly I have no idea about it.
I tried copying and pasting some lines after the comma, but it ended with an error in the code. Maybe you write such codes with your eyes closed, but unfortunately I can't...
with control via several pins, I need LEDs because I can't connect e.g. 5-7 LEDs because they don't have that much power. so I have to split it into several pins. Therefore, I need to change the code so that when the button is turned on, it will turn on 2 or 3 (or maybe more) pins:
and this is the code we wanted to modify:

//192.168.4.1
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <EEPROM.h>

/* Put your SSID & Password */
const char* ssid = "Name";  // Enter SSID here
const char* password = "Password";  //Enter Password here

ESP8266WebServer server(80);

uint8_t Relay1 = D0;
uint8_t Relay2 = D1;
uint8_t Relay3 = D2;
uint8_t Relay4 = D3;

int load1, load2, load3, load4;

void setup() {
  Serial.begin(115200);
  Serial.println();

  pinMode(Relay1, OUTPUT);
  pinMode(Relay2, OUTPUT);
  pinMode(Relay3, OUTPUT);
  pinMode(Relay4, OUTPUT);

  EEPROM.begin(512);
 
  load1 = EEPROM.read(1);
  load2 = EEPROM.read(2);
  load3 = EEPROM.read(3);
  load4 = EEPROM.read(4);

  Serial.print(load1); Serial.print(" ");
  Serial.print(load2); Serial.print(" ");
  Serial.print(load3); Serial.print(" ");
  Serial.println(load4);

  digitalWrite(Relay1, load1);
  digitalWrite(Relay2, load2);
  digitalWrite(Relay3, load3);
  digitalWrite(Relay4, load4);

  WiFi.softAP(ssid, password);
  IPAddress apip = WiFi.softAPIP();
  Serial.print("visit: \n");
  Serial.println(apip);
   
  delay(100);
 
  server.on("/", handle_OnConnect);
  server.on("/L1on",  handle_L1on);
  server.on("/L1off", handle_L1off);
  server.on("/L2on",  handle_L2on);
  server.on("/L2off", handle_L2off);
  server.on("/L3on",  handle_L3on);
  server.on("/L3off", handle_L3off);
  server.on("/L4on",  handle_L4on);
  server.on("/L4off", handle_L4off);
  server.onNotFound(handle_NotFound);
 
  server.begin();
  Serial.println("HTTP server started");
}
void loop() {
  server.handleClient();

  digitalWrite(Relay1, load1);
  digitalWrite(Relay2, load2);
  digitalWrite(Relay3, load3);
  digitalWrite(Relay4, load4);

}

void handle_OnConnect() {
  server.send(200, "text/html", SendHTML(load1,load2,load3,load4));
}

void handle_L1on()  {load1=0;data();}
void handle_L1off() {load1=1;data();}

void handle_L2on()  {load2=0;data();}
void handle_L2off() {load2=1;data();}

void handle_L3on()  {load3=0;data();}
void handle_L3off() {load3=1;data();}

void handle_L4on()  {load4=0;data();}
void handle_L4off() {load4=1;data();}


void data(){
EEPROM.write(1, load1);
EEPROM.write(2, load2);
EEPROM.write(3, load3);
EEPROM.write(4, load4); 
EEPROM.commit();
 
server.send(200, "text/html", SendHTML(load1,load2,load3,load4));  
}


void handle_NotFound(){
  server.send(404, "text/plain", "Not found");
}

String SendHTML(uint8_t l1stat,uint8_t l2stat,uint8_t l3stat,uint8_t l4stat){
  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>4Load Control</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;} h3 {color: #444444;margin-bottom: 50px;}\n";
  ptr +=".button {display: block;width: 80px;background-color: #1abc9c;border: none;color: white;padding: 13px 30px;text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";
  ptr +=".button-on {background-color: #1abc9c;}\n";
  ptr +=".button-on:active {background-color: #16a085;}\n";
  ptr +=".button-off {background-color: #34495e;}\n";
  ptr +=".button-off:active {background-color: #2c3e50;}\n";
  ptr +="p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";
  ptr +="</style>\n";
  ptr +="</head>\n";
  ptr +="<body>\n";
  ptr +="<h2>Wifi based Home Appliance Control</h2>\n";
 
   if(l1stat==0)
  {ptr +="<p>Load1 Status: ON</p><a class=\"button button-off\" href=\"/L1off\">OFF</a>\n";}
  else
  {ptr +="<p>Load1 Status: OFF</p><a class=\"button button-on\" href=\"/L1on\">ON</a>\n";}

  if(l2stat==0)
  {ptr +="<p>Load2 Status: ON</p><a class=\"button button-off\" href=\"/L2off\">OFF</a>\n";}
  else
  {ptr +="<p>Load2 Status: OFF</p><a class=\"button button-on\" href=\"/L2on\">ON</a>\n";}

  if(l3stat==0)
  {ptr +="<p>Load3 Status: ON</p><a class=\"button button-off\" href=\"/L3off\">OFF</a>\n";}
  else
  {ptr +="<p>Load3 Status: OFF</p><a class=\"button button-on\" href=\"/L3on\">ON</a>\n";}

  if(l4stat==0)
  {ptr +="<p>Load4 Status: ON</p><a class=\"button button-off\" href=\"/L4off\">OFF</a>\n";}
  else
  {ptr +="<p>Load4 Status: OFF</p><a class=\"button button-on\" href=\"/L4on\">ON</a>\n";}

  ptr +="</body>\n";
  ptr +="</html>\n";
  return ptr;
}

May be I don't understand you correctly, but if you want to change two pins with one button, you can adopt the callback functions to change several pins:

void handle_L1on()  {
  load1 = 0;
  load2 = 0;
  data();
}
void handle_L1off() {
  load1 = 1;
  load2 = 1;
  data();
}

Maybe this is what I mean, but I'll have to check it because sometimes I can make such a mess in the code that I don't know which function is causing the error... and generally I mean something like in the video:

https://www.youtube.com/watch?v=piF2zMNQtRM

So I checked the code and it works ;). So thank you very much Mr. Noiasca.
I still have to solve the problem of where to paste the delay options so that, for example, on pin D3 (or D4 or D5) the LED blinks... I know that the delay blocks the entire mechanism and it would be better to use a timer... but I have no idea about it, so I'll limit myself to use a delay which will flash the LED 3 or 4 or 5 times (if I turn on the button).

take the example
Blink Without Delay

make it working on your D1.

Study it as long as you need to write the code by heart.

When you can write that code from memory - you have all the tools you need to write code
without delays.

I noticed one thing. when I clicked buttons on my phone, sometimes one button opened a new page and when I clicked that one button, it returned to the previous page with several buttons. It's a bit strange. Well, I can come to terms with that

Sorry, does anyone know how to connect the delay functions to one LED? in this code
so that, for example, D1 or D2 flashes 2 or 5 times?
in other sketches it looks something like this:

digitalWrite(PinD2, LOW);
delay(500);
digitalWrite(PinD2, HIGH);
delay(500);
digitalWrite(PinD2, LOW);
delay(500);
digitalWrite(PinD2, HIGH);
delay(500);
digitalWrite(PinD2, LOW);

And in this code everything looks different and when I look at it, it's like I was looking at Egyptian hieroglyphs.
I just have no idea where and how to insert delay options.
so if anyone could help me I would be grateful.

Hi @euzebi

welcome to the Arduino-Forum.
well done to post your code as a code-section.

You are asking again and again for other people to modify your code to add functionality.

This is not how this forum works. You should start learning programming yourself.

explaining non-blocking timing
I want to comment on the basic blink_without_delay example-code.

The basic basic blink_without_delay example-code makes understanding non-blocking timing
harder than it must be for multiple reasons:

There is a pretty high danger that a totally wrong picture of how non-blocking timing works is created by just reading this example.
Without emphasizing on the total different nature of non-blocking timing a wrong picture of

replace delay() with millis() and you are done.
is likely to build up in a newcomers head.

non-blocking timing requires more than a simple replacing.

  1. the blink without delay-example does NOT mention that there is a fundamental difference
    between delay() and non-blocking timing
    Without explicitly explaining this difference newcomers are in danger to see a delay()-similar-Thing
    And trying to see a delay()-similar thing will cause extra confusion because there is NO similarity!

  2. a part of the variable-names is badly chosen.

  3. the demo-code distributes the variables to mutliple places

The variable-distribution makes it harder to understand the basic principle.

I suggest that you watch this video as the introduction to non-blocking timing
It will guide you on the right track and explain it step by step

You should describe your wanted functionality in smaller steps and write about each detail

example:
I tap on my smartphone on the button one
and then
Io-pin D3 shall blink 5 times
1 second on 0,5 seconds off
and then
stay IO-pin D3 shall be switched "on"

I know I should learn, but it's best to learn from previously made examples shown on YouTube.
Unfortunately, there are simple examples on YouTube on how to flash the LED (without a phone) or turn the LED on and off on the phone... but there are few more advanced examples.
Besides, if I was 18-20 years old, I could try to learn C++ (Arduino), but I'm 49 years old and it may turn out that I won't have enough life to learn everything. and in general I need a code thanks to which I will be able to control the LEDs in my 1:24 scale cars... something like this guy.
https://www.youtube.com/watch?v=5SdEWSNHqQE
Unfortunately, he doesn't I want to share the code so I'm looking for help somewhere else (in this case here) :slight_smile:

(I'm sorry for my English if what I wrote doesn't make sense, but I use Google translate )

The translation is understandable.
Today I made a comparising between google-translate and deepL.
result: google-translate is far beyond the quality of deepL

Surely not everything. What a big generalising word.

Well me personal I am 56 and started learning to play drums 8 months ago.
Now after 8 months I have found the ideal way of learning for me and it pays off very well. All the different patterns start to fit together and I am automating the movements.

Programming is somehow similar. Programming is like a set of Lego-bricks of different shapes. You can build up very very different objects with a limited number of different shaped bricks.

Your complete functionality of webserver, and switching on/off or blink leds can be divided in parts. Where each part does one thing.

It may take 20 hours to learn the most important basics.
After learning these basics you will still have questions but you will be able to post a code-modification that you wrote on your own and then ask specific questions.

There is a basic concept for doing things like this.

It is called non-blocking timing.

especcially non-blocking timing follows a different concept
delay means:
execute
freeze microcontroller = blocking code
execute
freeze microcontroller = blocking code
execute
....

non-blocking timing means

always loop with function loop

void loop() {
  check on every-loop-iteration: how much time has passed by since last action?
}

Perhaps, but only if you absorb the knowledge quickly. But if you are a hard-thinking person (e.g. like me), it may take me not 20 hours but 20 years :D.
secondly, there is also a language barrier. I live in Poland and my English is very poor (which is obvious because I use a translator) and adding mathematical phrases to this is quite abstract for me.
that's why I watch all these tutorials and try to use the codes that people sometimes share with others and I try to make small modifications, but writing the entire code myself is too much for me. and then there is the problem of understanding how a given option works, because you also need to know in which part of the code to enter it in order for it to fulfill its purpose, because if I enter it in the wrong place, it simply will not work and will generate an error. and of course I won't know why and will spend the next hours or days looking for a solution. and I would prefer to avoid that. :wink:

that is where the forum comes in to help.
You post the code with the modification = the complete sketch that has the error and asking for help.

In this way you save a lot of hours of try and error. And it will be easy to answer this specific question why a certain error is there and how to correct it to make it work.

You want to have multiple blinking leds. They shall blink a different number of times and at different frequencies.

This is possible to do. It requires a programming technique that is called non-blocking.

Two steps

  1. learn the basic principle
  2. learn how to code it

The basic principle is to have

void loop()  

running down thousands of times each second.
taking timestamps and compare the time-stamps with actual time to check

how much time has passed by
Please watch the video linked above to understand this basic principle

If you want some actions to happen only after tapping a button on your phone
that switches this action on

you use boolean variables that are set to eitherto "true" or to "false"

here is a tutorial that takes maybe 2 or 3 hours to read through

Arduino Programming Course

It is easy to understand and has a good mixture between explaining important concepts and example-codes to get you going. So give it a try and report your opinion about this tutorial.

Is there such a guide in Polish?
probably not :wink:

and I have one more question because I had several codes as examples from YouTube to turn the LED on and off. and I noticed that some of them did not work because after pressing reset, dots appeared on my monitor instead of the IP address... and only recently I found out that there are codes that connect to my network. and there are codes that create a server on esp8266 and I can enter my own name and password... (STA and AP Mode).
and the question is, is it difficult to change the code to create a server on the esp8266 module? Is it enough to change the top type options (example below) or do I have to interfere with the entire program code?

this is probably STA mode:

// Load Wi-Fi library
#include <ESP8266WiFi.h>

// Replace with your network credentials
const char* ssid     = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// Set web server port number to 80
WiFiServer server(80);

and this is probably AP Mode (Access Point)

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

/* Put your SSID & Password */
const char* ssid = "NodeMCU";  // Enter SSID here
const char* password = "12345678";  //Enter Password here

/* Put IP Address details */
IPAddress local_ip(192,168,1,1);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);

ESP8266WebServer server(80);

the decision if the ESP is using an existing WiFi or spans its own WiFi in AP mode is done later in the code in setup().

See the example WifiAccessPoint in the IDE.

  /* You can remove the password parameter if you want the AP to be open. */
  WiFi.softAP(ssid, password);

  IPAddress myIP = WiFi.softAPIP();

but you can use deepL for translation to polish
deepl translating chapter 1

1 Like

You should write down a detailed description of your wanted functionality in normal words.

I beg you use normal words.
It shall be really detailed and contain all options that you want to have regardless how many options these are.

This will help to decide what code will be taken as the base

Mr. StefanL38 and Mr. noiasca

you know what ?
I could paste another code here that may be simpler for 2 LEDs. which of course works and I tried to add another diode to it and tried to modify the code according to my way of thinking. but I'm afraid I'll throw you off balance :smiley: I don't know whether to risk it.
(of course, my code generates errors)

Surely post the complete sketch.
By posting your complete sketch the explanation how to modify it and what the general comcepts are can be adpated to your thinking

Ok. so this is the original code which obviously works:

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

/* Put your SSID & Password */
const char* ssid = "NodeMCU";  // Enter SSID here
const char* password = "12345678";  //Enter Password here

/* Put IP Address details */
IPAddress local_ip(192,168,1,1);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);

ESP8266WebServer server(80);

uint8_t LED1pin = D7;
bool LED1status = LOW;

uint8_t LED2pin = D6;
bool LED2status = LOW;

void setup() {
  Serial.begin(115200);
  pinMode(LED1pin, OUTPUT);
  pinMode(LED2pin, OUTPUT);

  WiFi.softAP(ssid, password);
  WiFi.softAPConfig(local_ip, gateway, subnet);
  delay(100);
  
  server.on("/", handle_OnConnect);
  server.on("/led1on", handle_led1on);
  server.on("/led1off", handle_led1off);
  server.on("/led2on", handle_led2on);
  server.on("/led2off", handle_led2off);
  server.onNotFound(handle_NotFound);
  
  server.begin();
  Serial.println("HTTP server started");
}
void loop() {
  server.handleClient();
  if(LED1status)
  {digitalWrite(LED1pin, HIGH);}
  else
  {digitalWrite(LED1pin, LOW);}
  
  if(LED2status)
  {digitalWrite(LED2pin, HIGH);}
  else
  {digitalWrite(LED2pin, LOW);}
}

void handle_OnConnect() {
  LED1status = LOW;
  LED2status = LOW;
  Serial.println("GPIO7 Status: OFF | GPIO6 Status: OFF");
  server.send(200, "text/html", SendHTML(LED1status,LED2status)); 
}

void handle_led1on() {
  LED1status = HIGH;
  Serial.println("GPIO7 Status: ON");
  server.send(200, "text/html", SendHTML(true,LED2status)); 
}

void handle_led1off() {
  LED1status = LOW;
  Serial.println("GPIO7 Status: OFF");
  server.send(200, "text/html", SendHTML(false,LED2status)); 
}

void handle_led2on() {
  LED2status = HIGH;
  Serial.println("GPIO6 Status: ON");
  server.send(200, "text/html", SendHTML(LED1status,true)); 
}

void handle_led2off() {
  LED2status = LOW;
  Serial.println("GPIO6 Status: OFF");
  server.send(200, "text/html", SendHTML(LED1status,false)); 
}

void handle_NotFound(){
  server.send(404, "text/plain", "Not found");
}

String SendHTML(uint8_t led1stat,uint8_t led2stat){
  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>LED Control</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;} h3 {color: #444444;margin-bottom: 50px;}\n";
  ptr +=".button {display: block;width: 80px;background-color: #1abc9c;border: none;color: white;padding: 13px 30px;text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";
  ptr +=".button-on {background-color: #1abc9c;}\n";
  ptr +=".button-on:active {background-color: #16a085;}\n";
  ptr +=".button-off {background-color: #34495e;}\n";
  ptr +=".button-off:active {background-color: #2c3e50;}\n";
  ptr +="p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";
  ptr +="</style>\n";
  ptr +="</head>\n";
  ptr +="<body>\n";
  ptr +="<h1>ESP8266 Web Server</h1>\n";
  ptr +="<h3>Using Access Point(AP) Mode</h3>\n";
  
   if(led1stat)
  {ptr +="<p>LED1 Status: ON</p><a class=\"button button-off\" href=\"/led1off\">OFF</a>\n";}
  else
  {ptr +="<p>LED1 Status: OFF</p><a class=\"button button-on\" href=\"/led1on\">ON</a>\n";}

  if(led2stat)
  {ptr +="<p>LED2 Status: ON</p><a class=\"button button-off\" href=\"/led2off\">OFF</a>\n";}
  else
  {ptr +="<p>LED2 Status: OFF</p><a class=\"button button-on\" href=\"/led2on\">ON</a>\n";}

  ptr +="</body>\n";
  ptr +="</html>\n";
  return ptr;
}

and here is the code that I wanted to modify and added a third LED with a button. and now it turns out that it works strangely because one button turns the diode on and off. while the 2nd button turns on the diode, but the 3rd button turns off automatically. and now the 2nd button does not respond to turning off. and I have to click the 3rd button and ON appears, but the 2nd one turns off automatically (even though the LED is on) and now when I click the 2nd button, the LED turns off. and in general, the 3rd diode does not light up at all from pin D5.
In short, turning on the LEDs is like a puzzle:

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

/* Put your SSID & Password */
const char* ssid = "NodeMCU";  // Enter SSID here
const char* password = "12345678";  //Enter Password here

/* Put IP Address details */
IPAddress local_ip(192,168,1,1);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);

ESP8266WebServer server(80);

uint8_t LED1pin = D7;
bool LED1status = LOW;

uint8_t LED2pin = D6;
bool LED2status = LOW;

uint8_t LED3pin = D5;
bool LED3status = LOW;

void setup() {
  Serial.begin(115200);
  pinMode(LED1pin, OUTPUT);
  pinMode(LED2pin, OUTPUT);
  pinMode(LED3pin, OUTPUT);

  WiFi.softAP(ssid, password);
  WiFi.softAPConfig(local_ip, gateway, subnet);
  delay(100);
  
  server.on("/", handle_OnConnect);
  server.on("/led1on", handle_led1on);
  server.on("/led1off", handle_led1off);
  server.on("/led2on", handle_led2on);
  server.on("/led2off", handle_led2off);
  server.on("/led3on", handle_led1on);
  server.on("/led3off", handle_led1off);
  server.onNotFound(handle_NotFound);
  
  server.begin();
  Serial.println("HTTP server started");
}
void loop() {
  server.handleClient();
  if(LED1status)
  {digitalWrite(LED1pin, HIGH);}
  else
  {digitalWrite(LED1pin, LOW);}
  
  if(LED2status)
  {digitalWrite(LED2pin, HIGH);}
  else
  {digitalWrite(LED2pin, LOW);}

  if(LED3status)
  {digitalWrite(LED3pin, HIGH);}
  else
  {digitalWrite(LED3pin, LOW);}
}

void handle_OnConnect() {
  LED1status = LOW;
  LED2status = LOW;
  LED3status = LOW;
  Serial.println("GPIO7 Status: OFF | GPIO6 Status: OFF | GPIO5 Status: OFF");
  server.send(200, "text/html", SendHTML(LED1status,LED2status,LED3status)); 
}

void handle_led1on() {
  LED1status = HIGH;
  Serial.println("GPIO7 Status: ON");
  server.send(200, "text/html", SendHTML(true,LED2status,LED3status)); 
}

void handle_led1off() {
  LED1status = LOW;
  Serial.println("GPIO7 Status: OFF");
  server.send(200, "text/html", SendHTML(false,LED2status,LED3status)); 
}

void handle_led2on() {
  LED2status = HIGH;
  Serial.println("GPIO6 Status: ON");
  server.send(200, "text/html", SendHTML(LED1status,LED3status,true)); 
}

void handle_led2off() {
  LED2status = LOW;
  Serial.println("GPIO6 Status: OFF");
  server.send(200, "text/html", SendHTML(LED1status,LED3status,false)); 
}

void handle_led3on() {
  LED3status = HIGH;
  Serial.println("GPIO5 Status: ON");
  server.send(200, "text/html", SendHTML(LED1status,LED2status,true)); 
}

void handle_led3off() {
  LED3status = LOW;
  Serial.println("GPIO5 Status: OFF");
  server.send(200, "text/html", SendHTML(LED1status,LED2status,false)); 
}

void handle_NotFound(){
  server.send(404, "text/plain", "Not found");
}

String SendHTML(uint8_t led1stat,uint8_t led2stat,uint8_t led3stat){
  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>LED Control</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;} h3 {color: #444444;margin-bottom: 50px;}\n";
  ptr +=".button {display: block;width: 80px;background-color: #1abc9c;border: none;color: white;padding: 13px 30px;text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";
  ptr +=".button-on {background-color: #1abc9c;}\n";
  ptr +=".button-on:active {background-color: #16a085;}\n";
  ptr +=".button-off {background-color: #34495e;}\n";
  ptr +=".button-off:active {background-color: #2c3e50;}\n";
  ptr +="p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";
  ptr +="</style>\n";
  ptr +="</head>\n";
  ptr +="<body>\n";
  ptr +="<h1>ESP8266 Web Server</h1>\n";
  ptr +="<h3>Using Access Point(AP) Mode</h3>\n";
  
   if(led1stat)
  {ptr +="<p>LED1 Status: ON</p><a class=\"button button-off\" href=\"/led1off\">OFF</a>\n";}
  else
  {ptr +="<p>LED1 Status: OFF</p><a class=\"button button-on\" href=\"/led1on\">ON</a>\n";}

  if(led2stat)
  {ptr +="<p>LED2 Status: ON</p><a class=\"button button-off\" href=\"/led2off\">OFF</a>\n";}
  else
  {ptr +="<p>LED2 Status: OFF</p><a class=\"button button-on\" href=\"/led2on\">ON</a>\n";}

  if(led3stat)
  {ptr +="<p>LED3 Status: ON</p><a class=\"button button-off\" href=\"/led3off\">OFF</a>\n";}
  else
  {ptr +="<p>LED3 Status: OFF</p><a class=\"button button-on\" href=\"/led3on\">ON</a>\n";}

  ptr +="</body>\n";
  ptr +="</html>\n";
  return ptr;
}

I probably made a mess here:

void handle_OnConnect() {
  LED1status = LOW;
  LED2status = LOW;
  LED3status = LOW;
  Serial.println("GPIO7 Status: OFF | GPIO6 Status: OFF | GPIO5 Status: OFF");
  server.send(200, "text/html", SendHTML(LED1status,LED2status,LED3status)); 
}

void handle_led1on() {
  LED1status = HIGH;
  Serial.println("GPIO7 Status: ON");
  server.send(200, "text/html", SendHTML(true,LED2status,LED3status)); 
}

void handle_led1off() {
  LED1status = LOW;
  Serial.println("GPIO7 Status: OFF");
  server.send(200, "text/html", SendHTML(false,LED2status,LED3status)); 
}

void handle_led2on() {
  LED2status = HIGH;
  Serial.println("GPIO6 Status: ON");
  server.send(200, "text/html", SendHTML(LED1status,LED3status,true)); 
}

void handle_led2off() {
  LED2status = LOW;
  Serial.println("GPIO6 Status: OFF");
  server.send(200, "text/html", SendHTML(LED1status,LED3status,false)); 
}

void handle_led3on() {
  LED3status = HIGH;
  Serial.println("GPIO5 Status: ON");
  server.send(200, "text/html", SendHTML(LED1status,LED2status,true)); 
}

void handle_led3off() {
  LED3status = LOW;
  Serial.println("GPIO5 Status: OFF");
  server.send(200, "text/html", SendHTML(LED1status,LED2status,false)); 
}

Ok here we go:

Most things seem to be correct but this here is wrong

  server.on("/led3on", handle_led1on);
  server.on("/led3off", handle_led1off);

.
compare with how it looks like for led1 / led2

  server.on("/led1on", handle_led1on);
  server.on("/led1off", handle_led1off);
  server.on("/led2on", handle_led2on);
  server.on("/led2off", handle_led2off);

Your description of the behavior you see is not precise enough.

which button turns on/off what? you should use consequently in each single naming the words
"button1" "LED1"
"button2" "LED2"
"button3" "LED3"

Only in case that you use these words consequently in each and every case there is no room left for interpretation and things are really clear.

Additionally what gets printed to the serial monitor if you tap on your new button 3?