I mean no need for 2, esp one for server and one for client.
Only one esp8266-f acts as server, and then i will connect to it by its url using my mobile to check the run time of each led
when did anyone suggest that?
I need help to add web page to check total time for each led in run state during one month.
I google it but i can not found something like this situation.
a)
before you can display the total time you have to calculate it.
you could introduce two new variables for each led:
the startTime: to remember the millis when you switch on the LED
the totalTime: to accumulate the time when the LED was on
when you switch off the LED you add the passed Time since startTime to totalTime
b)
once you have the totalTime - you can print it on the page of your ESP8266WebServer.h
c)
consider that you will lose the totalTime when the board gets resetted. You could store the values to the filesystem/LittleFS on your ESP. There is a 3rd party library preferences.h which gives a nice API to read/write values to the LittleFS.
d)
To get the the change of the month you could use NTP.
doable but a very ambiguous project for one just started to switch on / off some LEDs.
You have not reacted on my proposal in #27. Have you checked it?
If you are fine with that as base - we can work out the next step.
This code is now working as i want
I think akk your steps are logical so we can start
I do not know what is OOP ??
I tried to implement a counter for the total runtime. The given result is in seconds.
To see how it is working I added a simple showInfo function.
it will just print out the accumulated runtime for each of the 3 outputs. The resolution is in seconds.
In my humble opinion it works.
/*
Arduino Forum
Topics: Multi Button Programming
Link: https://forum.arduino.cc/t/multi-button-programming/1094488
Variant: keep track of runtime for each Output
Sketch: sketch.ino
Created: 2023-03-2
delete: 2023-05
Author: noiasca
*/
const uint8_t b1 {A2}; // Button
const uint8_t b2 {A1}; // Button
const uint8_t b3 {A0}; // Button
const uint8_t r1 {12}; // Output relay
const uint8_t r2 {11}; // Output relay
const uint8_t r3 {10}; // Output relay
const uint8_t commonStatePin {9}; // Output relay
// a class for one LED one button
class Indicator {
const uint8_t buttonPin; // the input GPIO, active LOW
const uint8_t relayPin; // the output GPIO, active HIGH
uint8_t state = 0; // switched off or on
uint32_t runtimeMillis = 0; // timestamp of last update of counterTotal
uint32_t runtimeTotal = 0; // current total running time
public:
static constexpr uint8_t noPin = 255; // dummy value for "no button is pressed"
Indicator(uint8_t buttonPin, uint8_t relayPin) : buttonPin{buttonPin}, relayPin{relayPin}
{}
void begin() {
pinMode(buttonPin, INPUT_PULLUP);
pinMode(relayPin, OUTPUT);
}
// if running, add the current open time to the totalTime
void addTime() {
uint32_t currentMillis = millis();
if (state == 1) {
runtimeTotal = runtimeTotal + (currentMillis - runtimeMillis)/1000; // add passed time till now
runtimeMillis = currentMillis;
}
}
uint32_t getRuntimeTotal() {
addTime();
return runtimeTotal;
}
uint8_t update(uint32_t currentMillis = millis()) {
uint8_t lastActive = noPin;
uint8_t buttonState = digitalRead(buttonPin);
if (state == 0) {
if (buttonState == LOW) {
state = 1;
digitalWrite(relayPin, HIGH);
runtimeMillis = currentMillis; // start the runtime counter
lastActive = buttonPin;
}
}
else {
if (buttonState == HIGH) {
state = 0;
addTime(); // call before a switch off
digitalWrite(relayPin, LOW);
}
else
lastActive = buttonPin;
}
return lastActive; // returns the button GPIO if it is pressed
}
};
//create 3 indicators (each with one button and one relay/LED)
Indicator indicator[] {
{b1, r1},
{b2, r2},
{b3, r3},
};
// print the runtimes to Serial Monitor (just for debugging)
void showInfo(uint32_t currentMillis = millis()) {
static uint32_t previousMillis = 0;
if (currentMillis - previousMillis > 1000) {
previousMillis = currentMillis;
for (auto &i : indicator) {
Serial.print(i.getRuntimeTotal());
Serial.print("\t");
}
Serial.println();
}
}
void setup() {
Serial.begin(115200);
for (auto &i : indicator) i.begin();
pinMode(commonStatePin, OUTPUT);
}
void loop() {
bool commonState = HIGH;
for (auto &i : indicator) if (i.update() != Indicator::noPin) commonState = LOW; // if one button reports active, common Relay has to be switched off
digitalWrite(commonStatePin, commonState);
showInfo();
}
I think you had 20h now to google for OOP and read about object oriented programming in the context of Arduino and C++.
unfortunately
There was a problem with my esp8266 so I moved to esp32 and modify the code to
/*
Arduino Forum
Topics: Multi Button Programming
Category: Programming Questions
Link: https://forum.arduino.cc/t/multi-button-programming/1094488
*/
/*
Sketch: sketch.ino
Created: 25-Feb-2023
to be deleted: 2023-04
*/
/*
Author: noiasca
*/
const uint8_t b1 {4}; // Button
const uint8_t b2 {2}; // Button
const uint8_t b3 {15}; // Button
const uint8_t r1 {21}; // Output relay
const uint8_t r2 {19}; // Output relay
const uint8_t r3 {18}; // Output relay
const uint8_t commonStatePin {5}; // Output relay
// a class for one LED one button
class Indicator {
const uint8_t buttonPin; // the input GPIO, active LOW
const uint8_t relayPin; // the output GPIO, active HIGH
public:
static uint8_t lastActive; // the last pressed button
static constexpr uint8_t noPin = 255; // dummy value for "no button is pressed"
Indicator(uint8_t buttonPin, uint8_t relayPin) : buttonPin{buttonPin}, relayPin{relayPin}
{}
void begin() {
pinMode(buttonPin, INPUT_PULLUP);
pinMode(relayPin, OUTPUT);
}
int update(){
uint8_t buttonState = digitalRead(buttonPin);
if (buttonState == LOW && lastActive == noPin) {
digitalWrite(relayPin, HIGH);
lastActive = buttonPin;
}
else if (buttonState == HIGH && lastActive == buttonPin) {
digitalWrite(relayPin, LOW);
lastActive = noPin;
}
return lastActive; // returns the button GPIO if it is pressed
}
};
uint8_t Indicator::lastActive = Indicator::noPin; // initialize a static class member
//create 3 indicators (each with one button and one relay/LED)
Indicator indicator[] {
{b1, r1},
{b2, r2},
{b3, r3},
};
void setup() {
for (auto &i : indicator) i.begin();
pinMode(commonStatePin, OUTPUT);
}
void loop() {
bool commonState = HIGH;
for (auto &i : indicator) if (i.update() != Indicator::noPin) commonState = LOW; // if one button reports active, common Relay has to be switched off
digitalWrite(commonStatePin, commonState);
}
And connect buttons to GND but it is not working I do not know what is the problem as led on gpio 19 high all the time and no effect with any button pressed.
Any Help ??
I showed you a full working example on Wokwi.
You changed the pins and write "it is not working".
What do you think can I or anyone else check with your information now?
May be it's worth you put some efforts into a ESP32 wiring diagram on wokwi and share the link for example?
Ok I draw a new circuit on wokwi and test, it is working fine
this is the link
I will double check my circuit as it is not working like wokwi
Hi,
Please put you schematics in your posts;
Where are your current limit resistors for each LED?
// this code works fine and calculate total time of each led on
const uint8_t b1 {4}; // Button
const uint8_t b2 {2}; // Button
const uint8_t b3 {15}; // Button
const uint8_t r1 {21}; // Output relay
const uint8_t r2 {19}; // Output relay
const uint8_t r3 {18}; // Output relay
const uint8_t commonStatePin {5}; // Output relay
// a class for one LED one button
class Indicator {
const uint8_t buttonPin; // the input GPIO, active LOW
const uint8_t relayPin; // the output GPIO, active HIGH
unsigned long onTime; // the time the LED was turned on
unsigned long totalTime; // the total time the LED was on
public:
static uint8_t lastActive; // the last pressed button
static constexpr uint8_t noPin = 255; // dummy value for "no button is pressed"
Indicator(uint8_t buttonPin, uint8_t relayPin) : buttonPin{buttonPin}, relayPin{relayPin}, onTime{0}, totalTime{0}
{}
void begin() {
pinMode(buttonPin, INPUT_PULLUP);
pinMode(relayPin, OUTPUT);
}
void update(){
uint8_t buttonState = digitalRead(buttonPin);
if (buttonState == LOW && lastActive == noPin) {
digitalWrite(relayPin, HIGH);
lastActive = buttonPin;
onTime = millis(); // record the time the LED was turned on
}
else if (buttonState == HIGH && lastActive == buttonPin) {
digitalWrite(relayPin, LOW);
lastActive = noPin;
totalTime += millis() - onTime; // add the time the LED was on to the total time
Serial.print("LED ");
Serial.print(relayPin);
Serial.print(" was on for ");
Serial.print(totalTime / 1000.0); // convert milliseconds to seconds
Serial.println(" seconds");
}
}
};
uint8_t Indicator::lastActive = Indicator::noPin; // initialize a static class member
//create 3 indicators (each with one button and one relay/LED)
Indicator indicator[] {
{b1, r1},
{b2, r2},
{b3, r3},
};
void setup() {
Serial.begin(9600);
while (!Serial); // wait for the serial monitor to open
for (auto &i : indicator) i.begin();
pinMode(commonStatePin, OUTPUT);
}
void loop() {
bool commonState = HIGH;
for (auto &i : indicator) {
i.update();
if (i.lastActive != Indicator::noPin) commonState = LOW; // if one button reports active, common Relay has to be switched off
}
digitalWrite(commonStatePin, commonState);
delay(2000);
}
Have you got a DMM to check that your buttons are working into the controller?
Make a simple sample code and check your hardware.
Tom..
![]()
I do not have current limit resistors as the esp32 working on 3,3v so the output is suitable to 3v LED
I will test buttons by DMM and try simple code for testing
Can you please post link to data/spec of the LEDs?
What colour are they?
If it is a Green LED.

Thanks.. Tom....
![]()
The leds color is white
Hi,
You have got the LEDs around the right way to conduct?
Thanks.. Tom..
![]()
Sorry what are you mean by right way to conduct ??
Note i was working on esp8266 with same chematic and it was working that way
LEDs only work connected to a current source in a particular direction.
Tom...
![]()
There is no problem with direct leds connectoon to the output pins of esp32.
I try simple that make led flashing, and it works fine and i try pin 4 as button, and it works.
But pins d2 and d15 are not working as buttons
I will try to investgae the problem
Now this code is works for me and gives time on serial monitor
#include <WiFi.h>
#include <WebServer.h>
const char* ssid = "AMGAD60"; // Enter your Wi-Fi network name
const char* password = "Amgad#60"; // Enter your Wi-Fi network password
// this code works fine and calculate total time of each led on
const uint8_t b1 {4}; // Button
const uint8_t b2 {22}; // Button
const uint8_t b3 {15}; // Button
const uint8_t r1 {21}; // Output relay
const uint8_t r2 {19}; // Output relay
const uint8_t r3 {18}; // Output relay
const uint8_t commonStatePin {5}; // Output relay
// a class for one LED one button
class Indicator {
const uint8_t buttonPin; // the input GPIO, active LOW
const uint8_t relayPin; // the output GPIO, active HIGH
unsigned long onTime; // the time the LED was turned on
unsigned long totalTime; // the total time the LED was on
public:
static uint8_t lastActive; // the last pressed button
static constexpr uint8_t noPin = 255; // dummy value for "no button is pressed"
Indicator(uint8_t buttonPin, uint8_t relayPin) : buttonPin{buttonPin}, relayPin{relayPin}, onTime{0}, totalTime{0}
{}
void begin() {
pinMode(buttonPin, INPUT_PULLUP);
pinMode(relayPin, OUTPUT);
}
void update(){
uint8_t buttonState = digitalRead(buttonPin);
if (buttonState == LOW && lastActive == noPin) {
digitalWrite(relayPin, HIGH);
lastActive = buttonPin;
onTime = millis(); // record the time the LED was turned on
}
else if (buttonState == HIGH && lastActive == buttonPin) {
digitalWrite(relayPin, LOW);
lastActive = noPin;
totalTime += millis() - onTime; // add the time the LED was on to the total time
Serial.print("LED ");
Serial.print(relayPin);
Serial.print(" was on for ");
Serial.print(totalTime / 1000.0); // convert milliseconds to seconds
Serial.println(" seconds");
}
}
};
uint8_t Indicator::lastActive = Indicator::noPin; // initialize a static class member
//create 3 indicators (each with one button and one relay/LED)
Indicator indicator[] {
{b1, r1},
{b2, r2},
{b3, r3},
};
void setup() {
Serial.begin(115200);
delay(100);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println();
Serial.print("Connecting to ");
Serial.print(ssid);
Serial.println("...");
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
while (!Serial); // wait for the serial monitor to open
for (auto &i : indicator) i.begin();
pinMode(commonStatePin, OUTPUT);
}
void loop() {
bool commonState = HIGH;
for (auto &i : indicator) {
i.update();
if (i.lastActive != Indicator::noPin) commonState = LOW; // if one button reports active, common Relay has to be switched off
}
digitalWrite(commonStatePin, commonState);
delay(2000);
}
I need to add a web server to code to show 4 led status as 4 squares in one line so that off led displays in red color and on led in green color Also display total on time for each led under it in bold big black font
I try my best to add a web server here is the code
#include <WiFi.h>
#include <WebServer.h>
const char* ssid = "AMGAD60"; // Enter your Wi-Fi network name
const char* password = "Amgad#60"; // Enter your Wi-Fi network password
// this code works fine and calculate total time of each led on
const uint8_t b1 {4}; // Button
const uint8_t b2 {22}; // Button
const uint8_t b3 {15}; // Button
const uint8_t r1 {21}; // Output relay
const uint8_t r2 {19}; // Output relay
const uint8_t r3 {18}; // Output relay
const uint8_t commonStatePin {5}; // Output relay
WebServer server(80);
// a class for one LED one button
class Indicator {
const uint8_t buttonPin; // the input GPIO, active LOW
const uint8_t relayPin; // the output GPIO, active HIGH
unsigned long onTime; // the time the LED was turned on
unsigned long totalTime; // the total time the LED was on
public:
static uint8_t lastActive; // the last pressed button
static constexpr uint8_t noPin = 255; // dummy value for "no button is pressed"
Indicator(uint8_t buttonPin, uint8_t relayPin) : buttonPin{buttonPin}, relayPin{relayPin}, onTime{0}, totalTime{0}
{}
void begin() {
pinMode(buttonPin, INPUT_PULLUP);
pinMode(relayPin, OUTPUT);
}
void update(){
uint8_t buttonState = digitalRead(buttonPin);
if (buttonState == LOW && lastActive == noPin) {
digitalWrite(relayPin, HIGH);
lastActive = buttonPin;
onTime = millis(); // record the time the LED was turned on
}
else if (buttonState == HIGH && lastActive == buttonPin) {
digitalWrite(relayPin, LOW);
lastActive = noPin;
totalTime += millis() - onTime; // add the time the LED was on to the total time
Serial.print("LED ");
Serial.print(relayPin);
Serial.print(" was on for ");
Serial.print(totalTime / 1000.0); // convert milliseconds to seconds
Serial.println(" seconds");
}
}
};
uint8_t Indicator::lastActive = Indicator::noPin; // initialize a static class member
//create 3 indicators (each with one button and one relay/LED)
Indicator indicator[] {
{b1, r1},
{b2, r2},
{b3, r3},
};
void handleRoot() {
String html = "<html><head><title>Relay Status</title></head><body>";
for (int i = 0; i < 3; i++) {
Indicator &ind = indicator[i];
String color = ind.lastActive != Indicator::noPin ? "green" : "red";
html += "<div style='display:inline-block;margin:10px;width:100px;height:100px;border:1px solid black;background-color:" + color + ";'><p style='text-align:center;font-size:30px;font-weight:bold;color:black;'>" + String(ind.totalTime / 1000.0) + "s</p></div>";
}
html += "</body></html>";
server.send(200, "text/html", html);
}
void setup() {
Serial.begin(115200);
delay(100);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println();
Serial.print("Connecting to ");
Serial.print(ssid);
Serial.println("...");
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
while (!Serial); // wait for the serial monitor to open
for (auto &i : indicator) i.begin();
// start the server
server.on("/", handleRoot);
server.begin();
Serial.println("Server started");
pinMode(commonStatePin, OUTPUT);
}
void webServer() {
// handle root URL request
server.on("/", []() {
String html = "<html><head><title>Relay Status</title><style> .off { background-color: red; } .on { background-color: green; } .time { font-size: xx-large; font-weight: bold; color: black; } </style></head><body>";
html += "<h1>Relay Status</h1>";
for (auto &i : indicator) {
html += "<div class=\"";
if (digitalRead(i.relayPin) == LOW) {
html += "off";
} else {
html += "on";
}
html += "\" style=\"display: inline-block; width: 100px; height: 100px; margin-right: 10px; margin-bottom: 10px; text-align: center;\">";
html += "<h3>Relay " + String(i.relayPin) + "</h3>";
html += "<div class=\"time\">" + String(i.totalTime / 1000.0) + " seconds</div>";
html += "</div>";
}
html += "</body></html>";
server.send(200, "text/html", html);
});
}
void loop() {
bool commonState = HIGH;
for (auto &i : indicator) {
i.update();
if (i.lastActive != Indicator::noPin) commonState = LOW; // if one button reports active, common Relay has to be switched off
}
digitalWrite(commonStatePin, commonState);
server.handleClient(); // loop to handle incoming client requests
delay(2000);
}
But it is not working there is a lot of errors and I need help
