Lanzallamas se queda bloqueado (Solucionado)

Buenos días a tod@s.
Verán he hecho un lanzallamas con un servo y un relay, el tema es que necesito que se encienda el relay, pasen 3 seg. se accione el servo, pasen 2 seg. y se apague el relay, pero que esto se pueda interrumpir en cualquier momento (siga leyendo el código para ver el valor de un botón). He estado leyendo a cerca de millis() pero no consigo entenderlo para adaptarlo a mi código:

#include <Servo.h> 

Servo myservo;

const int buttonPin = 2;
int buttonState = 0;
const int relay = 9;

void setup() 
{ 
  myservo.attach(5);
  pinMode(buttonPin, INPUT);       
  pinMode(relay, OUTPUT);
} 

void loop() 
{ 
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) {     
    digitalWrite(relay, HIGH);
    delay(3000);
    myservo.write(90);
    delay(2000);
    digitalWrite(relay, LOW);
  } 
  else {
    myservo.write(0);
    digitalWrite(relay, LOW);
  }
  delay(15);
}

Cualquier ayuda es bienvenida.

Hola, voy a intentar echarte una mano, la idea es que el lanzallamas se active la secuencia de segundos al hacer un "click" o mientras mantienes pulsado el "gatillo"?

Ve a documentación ¿=> indice de temas tutoriales => millis() y máquinas de estados.

Necesitas de ambos tutoriales para resolver tu problema.
Leelo y luego que lo hagas y confirmes te respondo.

Luck_:
Hola, voy a intentar echarte una mano, la idea es que el lanzallamas se active la secuencia de segundos al hacer un "click" o mientras mantienes pulsado el "gatillo"?

Solo debería funcionar cuando se pulsa el "gatillo"

Buenas! A ver.. Soy muy nobel en programación, pero vamos, por lo que me dice sy por lo que leo, el código está bien... Si el objetivo es que cuando este pulsado el botón, haga todo eso, esta OK, y se parará cuando dejes de pulsarlo, no veo necesidad de interrupción, ya que entiendo que es cuando levantas el dedo..

Entonces donde esta el problema, o donde no te estoy entendiendo con exactitud?

Pero yo usaría el "! digitalRead" que ese símbolo significa "negación" o "lo contrario de"
Y metes lo que tienes en el "if" dentro del "else" y lo que hay dentro del "else" en el "if"

En plan, cuando no esté pulsado que haga esto... Y si se pulsa (else) que haga lo que yo quiera..

Pero insisto en que soy nobel.. Igual he dicho algo que este bien.. Pero vamos, que seguro que lo consigues!!

Suerte!

El problema es que sí o sí tiene que tragar el delay antes de volver a checkear el botón

PedroPC:
El problema es que sí o sí tiene que tragar el delay antes de volver a checkear el botón

No si usas millis().

Ahhhh, es verdad, maldito delay!! Es un problema... Entonces coincido (inevitablemente) :smiley: con los compañeros, si el programa quieres hacer funcionar, Millis tendras que usar!

Un saludete!

Que tal así?
pruebalo esto debe funcionar

#include <Servo.h> 

Servo myservo;

const byte buttonPin = 2;
bool buttonState, anterior;
const byte relay = 9;
unsigned long t1;
byte estado;

void setup() 
{ 
  myservo.attach(5);
  pinMode(buttonPin, INPUT);       
  pinMode(relay, OUTPUT);
} 

void loop() 
{ 
  buttonState = digitalRead(buttonPin);
  
  if (buttonState) {      
      if(!anterior)
        estado=1;
      }

  else 
    estado=0;     
anterior=buttonState;
      
        switch (estado) {
            case 1:
             digitalWrite(relay, HIGH);
             t1=millis();
             estado=2; 
              break;

            case 2:
            if(millis()-t1 >= 3000UL){
               myservo.write(90);
               estado=3; 
               t1=millis();
               }
              break;

             case 3:
              if(millis()-t1>= 2000UL){
              digitalWrite(relay, LOW);
               }
             break;

            default:
            myservo.write(0);
            digitalWrite(relay, LOW);
        }
}