Integrar tiempo pulsado botón

Bueno, no sabía como poner el titulo, el tema es que tengo un código, donde mezclé un código de encender y apagar un led desde el mismo pulsador, con otro de hacerlo por web, el tema es que ahora quiero hacer que sólo se encienda cuando el botón está pulsado durante un segundo, he intentado modificar el código con un ejemplo que vi en este foro, pero no me funciona, a ver si entre los expertos de aquí me podéis orientar, gracias.

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
WiFiEventHandler gotIpEventHandler, disconnectedEventHandler;

#define UnoOn "1On"
#define UnoOff "1Off"
#define Puerto 80 
#define PROJECT_NAME "Luz"

const char* ssid = "*******";
const char* password = "*******";
IPAddress ip(192,168,1,200);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);
const int ledPin1 = 13; 
const int boton1 = 3; 
int val1 = 0; 
int state1 = 0; 
int old_val1 = 0; 
unsigned long tiempo;
unsigned long tiempomax = 1000;


WiFiServer server(Puerto);

void setup() {
 
 
 Serial.begin(115200);
 delay(10);
 pinMode(boton1, INPUT);
 pinMode(ledPin1, OUTPUT);
 digitalWrite(ledPin1, LOW);
 digitalWrite(boton1, HIGH);

 gotIpEventHandler = WiFi.onStationModeGotIP([](const WiFiEventStationModeGotIP& event)
  {
  Serial.print("Conectado, IP: ");
  Serial.println(WiFi.localIP());
  });
  disconnectedEventHandler = WiFi.onStationModeDisconnected([](const WiFiEventStationModeDisconnected& event)
  {
    Serial.println("Desconectado");
  });
  Serial.printf("Conectando a  %s ...\n", ssid);
  WiFi.begin(ssid, password);
  WiFi.config(ip, gateway, subnet);
  Serial.print("Conectado a ");
  Serial.println(ssid);
  Serial.print("IP:");
  Serial.println(ip);
  Serial.printf("MAC Address = %s\n", WiFi.softAPmacAddress().c_str());
  Serial.print(Puerto);
  ArduinoOTA.setHostname(PROJECT_NAME);
  ArduinoOTA.setPassword((const char *)"****");
   ArduinoOTA.begin();
 server.begin(); 
 }

void loop() {
ArduinoOTA.handle();
ESP.wdtDisable();


val1= digitalRead(boton1);
while((val1 == LOW) && (old_val1 == HIGH)){
  if(millis()-tiempo >= tiempomax){
state1=1-state1;
}
}

tiempo= millis();
 
old_val1 = val1;
if (state1==1){
 digitalWrite(ledPin1, HIGH);
}
else{
 digitalWrite(ledPin1,LOW);
}


 
WiFiClient client = server.available();
 if (!client) {
   return;
 }

 Serial.print("IP:");
 Serial.println(ip);
 Serial.println("new client");
 while(!client.available()){
   delay(1);
 }

 String request = client.readStringUntil('\r');
 client.flush();
 client.println("HTTP/1.1 200 OK");
 client.println("Content-Type: text/html");
 client.println("");
    int val1 = digitalRead(ledPin1);
 if (request.indexOf(UnoOn) != -1)  {
   digitalWrite(ledPin1, LOW);
   state1 = 0;
 }
 if (request.indexOf(UnoOff) != -1)  {
   digitalWrite(ledPin1, HIGH);
   state1 = 1;
 }

if (val1 == HIGH) {
 client.println(UnoOff);
    
 } 
if (val1 == LOW) {
   client.println(UnoOn);

 } 

 if (request.indexOf("/info") != -1)  {
 client.println("
");
 client.println("
");
 client.println("<b>Conectado a:   </b>");
 client.println(ssid);
 client.println("
");
 client.println("<b>IP:  </b>");
 client.println(ip);
 client.println("
");
 client.println("<b>Puerto:</b>");
 client.println(Puerto);
 client.println("
");
 client.printf("<b>Direccion MAC: </b>%s\n", WiFi.softAPmacAddress().c_str());
 client.println("
");
 client.println("<b>Ordenes:</b>");
 client.println(UnoOn);
 client.println("/");
 client.println(UnoOff);




 }

 delay(1);

}

Tienes un código o has copiado un código porque si puedes hacer algo Web lo que pides esta en un nivel mucho mas bajo.

supongo que esta es la parte que te importa.

val1= digitalRead(boton1);

while((val1 == LOW) && (old_val1 == HIGH)){
   if(millis()-tiempo >= tiempomax){
    state1=1-state1;
   }
}

tiempo= millis();
old_val1 = val1;

if (state1==1){
    digitalWrite(ledPin1, HIGH);
}
else{
 digitalWrite(ledPin1,LOW);
}

Lo primero que veo mal es el uso del while, no tiene nada que hacer el while ahi, aunque entiendo por que lo usaste.

Lo único que debes hacer es leer el flanco tal como intentas hacer. Cuando se de el flanco que te interesa inicias la cuenta y cuando superes el segundo tienes tu cambio o tu flag activo.

prueba esto, agrega la variable bool que te indico.

// agrega otro flag
bool flanco = false;

val1 = digitalRead(boton1);

if (!val1 && old_val1){ // flanco de 1 a 0
    tiempo = millis();  // inicias la cuenta      
    flanco = true;      // 
}
old_val1 = val1;        // guardo ultimo cambio

if (flanco && !val1)     // durante el tiempo que val1 esta en LOW
    if (millis()-tiempo >= tiempomax){ // se supero el segundo?
        state1 = true;
    }
    else 
        state1 = false;
else {
    flanco = false;     // si se suelta el pulsador 
    state1 = false;
}

if (state1)
    digitalWrite(ledPin1, HIGH);

else 
    digitalWrite(ledPin1,LOW);

Muchas gracias surbyte, cuando digo "tengo un código" es que he ido mezclando varios códigos que he copiado.Esta tarde lo probaré lo que has propuesto,eres un crack!!

Veamos si funciona, y nada de crack.. si vieras en que estoy trabajo te reirías.

Funciona!!!, pero he tenido que hacer una pequeña modificación, con tu permiso, porque no lo comenté, pero quería que al soltar el pulsador se quedase encendido hasta volver a pulsarlo.

val1 = digitalRead(boton1);

if (!val1 && old_val1){ // flanco de 1 a 0
    tiempo = millis();  // inicias la cuenta      
    flanco = true;      // 
}
old_val1 = val1;        // guardo ultimo cambio

if (flanco && !val1)     // durante el tiempo que val1 esta en LOW
    if (millis()-tiempo >= tiempomax){ // se supero el segundo?
        state1 = 1-state1;
        flanco = false;
    }
    else 
        state1 = state1;
else {
    flanco = false;     // si se suelta el pulsador 
   }

if (state1)
    digitalWrite(ledPin1, HIGH);

else 
    digitalWrite(ledPin1,LOW);

Y cuenta hombre, que llevo poco en el mundo del arduino pero soy muy curioso :smiley:

Es que esperaba que tuvieras que ajustarlo y me da gusto que se adapte a tu necesidad.
Interesante el modo que planteaste la idea y justamente como te dije, con INTERVALO ajustas el tiempo de respuesta al presionar ambos pulsadores.

10mseg son nada pero son suficientes para medir entre dos pulsadores. Cuenta como si fueran al mismo tiempo.
Si es posible hacerlo mas rápido pues lo bajas y listo.

En esto que querías hacer no puedes pensar que hay rebotes. Si los hay lo siento, pero delay(200) esta prohibido.

Imagina que hablo de 10 mseg y tu tenías 200 mseg para ver si rebotaba.. obviamente no puede ser.

Pues ahora me surge un problema y no se cual el la solución...

Resulta que estaba haciendo las pruebas con una placa NodeMcu V3, con el típico pulsador y un led que vienen en los "kits", pues al pasarlo a la placa donde tengo instalada una NodeMcu V1, que es con un relé y un pulsador de casa normal con su resistencia, pues me actúa que el relé se activa después del tiempo que le programo, por ejemplo, lo programo para que se active al pulsar durante 5 segundos, pues aunque de una pulsación corta, se activa a los 5 segundos de soltar el pulsador, y si lo dejo pulsado, no cuenta hasta que lo suelto.Me lleva loco...

Cuando usas un dispo de 3.3V la conexion a un rele no es la misma que para un Arduino de 5V. La razón es obvia, 5 > 3.3V

La forma de conexión ha sido explicada.
Debes separar el jumper JD-VDD y ponerlo en un solo pin o quitarlo.
Debes alimetnar el lado derecho o JD-VDD o sea la parte realmente de 5V donde esta el fototransitor y el RELE de 5V justamente con 5V.
Y donde esta el LED en el optoacomplador lo alimentas de este modo. IN0…X (entrada 0,1…etc) al pin del Nodemcu y el pin donde estaba el jumper lado izquierdo que seria VCC a 3.3V

Dime si te queda bien claro porque errores pueden producir que algo se queme.

Hay esquemas al respecto pero sinceramente ya me cansa buscarlos.

Gracias, está tarde lo probaré, pero antes me funcionaba perfecto, lleva instalado casi un año y sin problemas, lo único que he hecho ha sido cambiar esa parte del código.

Ya está solucionado, el problema era que tenía instalado el pulsador como "pulldown" y al parecer debía estar como "pullup".