¿Por qué me sale error al compilar la función de interrupción?

Buenas a todos, quería saber por qué no compila la funcion de interrupcion? Os dejo el código

Muchas gracias de antemano

int x=0;

void setup(){
attachInterrupt(digitalPinToInterrupt(2), velocidadMenos,RISING);
}

void loop(){
void velocidadMenos()
{
x++;
}
}

Porque has metido la función velocidadMenos() dentro de la función loop().

Tienes puesto:

void loop() {
void velocidadMenos()
{
  x++;
}

}

Has de "mover" } del final a justo después del inicio del loop():

void loop() {
}

void velocidadMenos()
{
  x++;
}

Muchísimas gracias, no sabia que las funciones iban fuera del void loop

Al solucionare la duda me ha surgido otra respecto a la funcion de interrupcion, mi pregunta es la siguiente:
La funcion de interrupcion solo se puede ejecutar una vez? es que resulta que he creado un programa muy basico en el que si pulso un punsador a una variable le suma 1, y un led se enciende solo si la variable vale 1, si vale 0 o mas de 1 deberia de estar apagado, pero una vez que se ha encendido no se vuelve a apagar cuando la variable ya no vale 1. Adjunto el programa

int boton=0;
void setup(){
attachInterrupt(digitalPinToInterrupt(2), pulsador, RISING);
pinMode(3,OUTPUT);//salida del led
pinMode(2,INPUT);//Pulsador
}

void loop(){

while(boton==1)
{
digitalWrite(3,HIGH);
}

}

void pulsador()
{
boton++;
}

La salida digital se mantiene en el último estado que se le diga. Tu ejemplo nunca la pone a nivel bajo. Sólo la pone a nivel alto. Has la prueba de la interrupción con el siguiente loop(), sin el while:

void loop() {
  digitalWrite(3, boton % 2);
}

Corrigo el código, por despiste puse % 1 cuando lo correcto es % 2

Lo que has puesto de "boton % 2" que quiero decir? es que nunca he visto eso dentro de un digital write, solo he visto lo de high o low pero lo que has puesto no.

El segundo parámetro que espera el digitalWrite() es de tipo boolean, eso quere decir que espera un valor "verdadero" o "falso". Si es verdadero pondrá la salida a nivel alto y si es falso lo pondrá a nivel bajo. El quid de la cuestión está en qué considera el C/C++ como "verdadero" o "falso". Aparte de los consabidos true y false, es considerado como "falso" aquello que su valor es cero, y como "verdadero" lo que su valor sea distinto de cero (por ejemplo: -3 sería considerado como "verdadero").

El operador % da como resultado el resto de la división entera. Si calculamos el resto que nos da el dividir un número entero ente 2, para todo entero que sea par nos dará como resto un cero (que se considera como un "falso") y si no es par nos dará un valor diferente de cero (que se considera como un "verdadero") así que la instrucción digitalWrite(3, boton % 2); pondrá a nivel bajo el pin 3 cuando bonton tenga un valor par y la pondrá a nivel alto cuando tenga un valor impar.

Por último, las constantes HIGH y LOW están definidas con el valor 1 y 0 respectivamente. Es aconsejable utilizar, siempre que se pueda, constantes en el código ya que lo hace más fácilmente comprensible. En este caso puse directamente la operación porque iba con prisas y no tenía ganas de escribir mucho. Es más código, pero sería más legible, si hubiera puesto:

  if ((boton % 2) != 0) {  // Verifica si el valor de boton es impar
    digitalWrite(3, HIGH); // boton es impar, encendemos el LED
  }
  else {
    digitalWrite(3, LOW); // boton es par, apagamos el LED
  }

Nota: lee las normas del foro y sobre todo la parte que explica cómo formatear el código en el post. Es más cómodo, si el código y los comentarios no excede cierto límite, poner el código directamente en el post (con el formato adecuado) y no capturas de pantalla. Y si pones imágenes es aconsejable hacer que se vean en el post sin necesidad de tener que descargarlas. Todo se explica en las normas que suelen ser la primera publicación de cada sección.

Porque abres dos hilos del mismo tema y además en lugar de postear un código pones una imágen del mismo?
Llego tarde porque IgnoranteAbsoluto te respondió pero presta atención porque no es la primera vez que lo haces.
Edita tu post inicial y coloca el código. Con la imagen no importa si se visualiza o no si colocas el código debidamente.

Queria disculparme por no haber posteado correctamente, es la primera vez que entro en un foro,ya me he leido las normas, hay alguna manera de editar el post para ponerlo correctamente?

Respecto a lo que me has comentado de mi duda, lo he entendido lo que me has dicho y me lo he apuntado dado que desconocía eso. La verdad que el supuesto circuito que he comentado no es lo que quería hacer, lo he dicho para enteder como funcionaba la funcion de interrupcion. El programa real que quiero hacer es que cada vez que pulso el pulsador ejecute un comando diferente, he hecho la prueba con el encendido de leds, cuando pulso una vez se encienda un led, cuado lo pulso por segunda vez se encienda otro y se apague el anterio, y asi sucesivamente con varios leds y esto que he comentado es lo que debería de pasar pero no me funciona.

int boton=0;

void setup() {
pinMode(2,INPUT);
pinMode(7,OUTPUT);
pinMode(6,OUTPUT);
pinMode(5,OUTPUT);
attachInterrupt(digitalPinToInterrupt(2), pulsador, RISING);
}

void loop() {
  while(boton==1)
{
  digitalWrite(5,HIGH);
}
  while(boton==2)
{
  digitalWrite(6,HIGH);
}

while(boton==3)
{
  digitalWrite(7,HIGH);
}

digitalWrite(7,LOW);
digitalWrite(6,LOW);
digitalWrite(5,LOW);

}



void pulsador()
{
 boton++;
}

Tengo la impresión de que estás tratando de matar moscas a cañonazos. Cuando ni tan siquiera saber utilizar un matamoscas.

Este tipo de interrupciones se utilizan para atender cambios de estado de los pines lo más pronto posible, sin dilaciones. Porque podría ser que si tardas una milésima en atender el cambio del pin ya fuera demasiado tarde. No sé a dónde quieres llegar, pero creo que este no es el camino.

Hay una cosa que creo que no has tenido en cuenta, y es el “rebote” de los pulsadores. Cuando un botón mecánico se pulsa, o se suelta, la conexión o desconexión no tiene porqué hacerse “limpiamente” y se puede generar una “ráfaga” de pulsos antes de que el valor se estabilice. Si utilizas las interrupciones para la lectura del pin se puede captar cada pulso independientemente y tener el efecto de que se ha pulsado y soltado varias veces el botón cuando en realidad no es eso lo que quieres. Y aún teniendo pulsaciones “limpias de rebotes” sigo pensando que las interrupciones no son lo que necesitas… Te lo digo sin tener claro qué es “lo que buscas”.

Supongamos que tienes “pulsaciones limpias”. Con la primera pulsación se cumplirá el primer while, se encenderá el primer LED y permanecerá en ese bucle hasta que realices la segunda pulsación. Esa segunda pulsación hará que se salga del primer while y entre inmediatamente en el segundo, se encienda el segundo LED, y permanecerá en ese segundo bucle hasta que se vuelva a pulsar. En ese momento tendrás los dos primeros LED encendidos. Una nueva pulsación hará que se salga del segundo while y entre acto seguido en el tercero, encendiendo el tercer LED y permaneciendo en ese bucle hasta que se vuelva a pulsar. Mientras no se vuelva a pulsas tendrás ahora los tres LED encendidos. En cuanto pulses una cuarta vez se saldrá del bucle y se apagan los tres LED hasta que vuelvas a pulsar unas 65532 veces más, que se habrá desbordado la variable boton y volverá a valer 1. Porque para cualquier valor que no sean 1, 2 o 3 no vas a encender ningún LED.

Eso si no hay rebotes. Si hay rebotes lo más probable es que se te encienda más de un LED a la vez con una sola pulsación o incluso que se te enciendan todos y se apaguen de una única pulsación porque una pulsación puede tener "rebotes" y a efectos práctico es como si hubieras pulsado varias veces. Basta que la primera pulsación genere tres o más rebotes a parte de la pulsación, para que el Arduino interprete has pulsado cuatro veces o más. Así que se encenderán los tres LED se apagarán inmediatamente. Y permanecerán apagados hasta que se desborde la variable.

Hay librerías para “combatir” los rebotes (debounce, en inglés, es lo que deberías de buscar en Google si estás interesado en ellas). Pero estas librerías no están pensadas para trabajar con interrupciones.

Mi consejo es que te olvides de las interrupciones y que busques documentación sobre millis() y máquinas de estados (podrás encontrar algo en este mismo foro Indice de temas Tutoriales - Documentación - Arduino Forum) y orientes tus programas a ello. Eso es lo básico en Arduino… Bueno, lo realmente básico es saber programar en C o C++.

Buenos días, te quería comentar que soy consciente de para que sirven las interrupciones y quiero que la tenga el programa, el problema por el cual el programa no funciona bien es por lo que me has dicho de los "rebotes" que no tenía ni idea de eso. Una de las cosas que has dicho es que se puede eliminar los "rebotes" con una librería pero que ésta no sirve si el programa tiene interrupciones, en este caso cómo soluciono los rebotes?

Pues entonces cambio un poco mi consejo: usa las interrupciones, máquinas de estados y millis().

Si explicas con más detalle lo que quieres hacer te podríamos orientar mejor.

Hace poco he propuesto en este mismo foro esto: Contador-restador - #3 by IgnoranteAbsoluto - Software - Arduino Forum

En ese programa sólo hago uso de las interrupciones y una máquina de estados. No uso millis() porque no tiene rebotes ni controla ningún tipo de tiempo. Imagino que no tiene nada que ver con lo que tienes en mente, pero tal vez te de alguna idea.

Una cosa que has de tener en cuenta es que las interrupciones se han de ejecutar rápidamente. Cuanto menos tiempo "esté interrumpido" el micro mejor. "Lo pesado" se ha de hacer "fuera de las interrupciones".

Esto resume todo

Si explicas con más detalle lo que quieres hacer te podríamos orientar mejor.

Y como no has leído las normas o no las has comprendido es que estas conversando sobre interrupciones sin explicar para que las necesitas.
Si resulta que luego solo quieres usar interrupciones porque usas delay() y quieres ver cuando se presiona un interruptor como ultimamente todo el mundo pregunta resulta ser que es un verdadero contrasentido.

Te dejo para tu consideración el punto 11 de las normas

  1. Tips para obtener mejores respuestas

• Menciona que Arduino tienes. ¿Es un UNO? ¿Leonardo? ¿Due? ¿Mini? ¿Mega? El problema podría ser específico de cualquiera de estos modelos.
Describe tu problema en detalle.
• Si es relacionado a una pieza electrónica (chip o modulo), menciona el modelo exacto y preferentemente un link al data sheet.
• Describe cómo has conectado cosas como registros. ¿Los has conectado a tierra? ¿o +5v? ¿Están con resistencias pull-up ó pull-down? Postea el circuito si tienes dudas.
• Agrega el Sketch (código) ¡completo! Si no lo haces harás perder el tiempo a las personas que te pidan hacerlo. Sin embargo, con problemas de código, si es posible postear un sketch mínimo que reproduzca el problema - sin cientos de líneas de código. Si el problema se desvanece en el sketch reducido, el error no estaba donde pensabas que estaba.

Y hay mas cosas para explicar/detallar pero pongo éstas como relevantes.

La medición de RPM es muy simple.
Usas una ventana de tiempo de X mseg y cuentas los pulsos dentro de dicho intervalo. Si la frecuencia de dichos pulsos es baja requieres una ventana mayor y si es alta con una menor será suficiente. En general todo lo que se mide por debajo de 1Khz es preferible medirlo de otra forma.
En lugar de contar pulsos se mide el tiempo de un ciclo de estos pulsos. Al ser lento, y medir su periódo (inversa de la frecuencia) lo haces con menor error que midiendo la frecuencia y de modo mas rápido.

Entonces.... habilita interrupciones durante 1000 mseg por ejemplo, cuentas pulsos, y cuando termina la ventana, deshabilitas interrupcones, lees el valor de los pulsos contados y lo presentas o haces el cálculo de las RPM. Re habilitas Interrupciones y de repites todo una y otra vez.

Teneis razón, el problema es que no he explicado el programa. Para empezar, lo que estoy haciendo es una figura que dentro lleva varios leds, un minialtavoz y un pulsador. Mi idea es que con el mismo pulsador tenga 3 modos de funcionamiento:
1ºNo pulso el pulsador todo está apagado
2ºPulso una vez, se encienden y apagan unos leds amarillos
3ºPulso por segunda vez, ocurre lo mismo que en el modo 2 pero empieza a sonar una musica
4º Pulso por tercera vez, se encienden los leds de antes y otros de color azul y suena otra musica

Si pulso una cuarta vez volvería al estado 1, es decir, todo apagado. El reproductor de musica es el “DFPlayer_mini”.
El problema sigue siendo el mismo, que al pulsar una vez es como si hubiera presionado varias veces. También he detectado otro error y es que una vez está ejecutando uno de los modos cuando pulso no pasa a otro modo, sigue ejecutando el mismo modo.

Ahora veréis que el programa es mucho más complejo de lo que os habia preguntado.

/*Pines:
 Azul Inferior 7
 Amarillo Inferior 5(PWM)
 Ojos 12
 Azul Superior 4
 Amarillo Superior 3 (PWM)
 Boton 2
 */




#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;




//Variables Luces
int ojos=12, AmaSup=3, UVSup=4, AmaInf=5, UVInf=7, boton=0;//Todo son salidas del arduino que encienden leds, excepto "boton" que es una entrada para el pulsador

//Variables auxiliares y otras de los case
int aux1,ama;//Case 1
int aux2;//Case 2



void setup()
{
//Configuracion pines
pinMode(ojos,OUTPUT);
pinMode(AmaSup,OUTPUT);
pinMode(UVSup,OUTPUT);
pinMode(AmaInf,OUTPUT);
pinMode(UVInf,OUTPUT);
pinMode(2,INPUT);

//Interrupcion para el boton
attachInterrupt(digitalPinToInterrupt(2), pulsador, RISING);

 
  
  
  
  
  //¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡No tocar lo que viene a continuacion, es del DFPlayer(Reproductor de música) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  mySoftwareSerial.begin(9600);
  Serial.begin(115200);
  if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
   }
  myDFPlayer.volume(20);  //Configuracion del volumen, valores de 0 a 30!!!!!!!!!!!!!!!!
   
}








void loop()
{

switch(boton){//Acontinuacion los diferentes modos de funcionamiento


  
  case 0://Todo apagado
  digitalWrite(UVSup,LOW);
  digitalWrite(UVInf,LOW);
  digitalWrite(ojos,LOW);
  analogWrite(AmaSup,0);
  analogWrite(AmaInf,0);
  break;



  case 1://Solo luz amarilla
  while(aux1==0)//Le pongo el while para que el primer "for" solo se ejecute una vez 
{
   for(ama=0;ama<=100;ama++)//Este solo para cuando se inicie por primera vez
  {
   delay(50);
    analogWrite(AmaSup,ama);
    analogWrite(AmaInf,ama);
  }
  aux1++;
}
  
  for(ama=100;ama<=255;ama++)
  {
   delay(20);
    analogWrite(AmaSup,ama);
    analogWrite(AmaInf,ama);
  }
delay(1000);//Tiempo de duracion con la luz máxima
   for(ama=255;ama>=50;ama--)
  {
   delay(20);
    analogWrite(AmaSup,ama);
    analogWrite(AmaInf,ama);
  }
  for(ama=50;ama<=100;ama++)
  {
   delay(20);
    analogWrite(AmaSup,ama);
    analogWrite(AmaInf,ama);
  }

  break;



  
  case 2://Luz amarilla y musica
  while(aux2==0)////Le pongo el while para que el primer "for" solo se ejecute una vez 
{
  myDFPlayer.play(1); //Comando para que empiece a sonar la primera cancion
   for(ama=0;ama<=100;ama++)//Este solo para cuando se inicie por primera vez
  {
   delay(50);
    analogWrite(AmaSup,ama);
    analogWrite(AmaInf,ama);
  }
  aux2++;
}
  
  for(ama=100;ama<=255;ama++)
  {
   delay(20);
    analogWrite(AmaSup,ama);
    analogWrite(AmaInf,ama);
  }
delay(1000);//Tiempo de duracion con la luz máxima
   for(ama=255;ama>=50;ama--)
  {
   delay(20);
    analogWrite(AmaSup,ama);
    analogWrite(AmaInf,ama);
  }
  for(ama=50;ama<=100;ama++)
  {
   delay(20);
    analogWrite(AmaSup,ama);
    analogWrite(AmaInf,ama);
  }
  break;

  

  case 3://Todos los efectos(todas las luces y la musica)
//Falta 
  break;
}




 

 

 
}

//Funcion para el pulsador
void pulsador()
{
 boton++;
 delay(700);
 if(boton==4)//He supuesto que a la cuarta pulsacion vuelva al estado inicial
 {
  boton=0;
 }
}

surbyte:
Si resulta que luego solo quieres usar interrupciones porque usas delay() y quieres ver cuando se presiona un interruptor como últimamente todo el mundo pregunta resulta…

Pues al final surbyte tenía razón. Usas delay() y lo tienes todo “secuencial”. Hasta que no termina de hacer una cosa no da la posibilidad de ponerse con la siguiente.

Y siento decirte que, aunque resuelvas lo de los rebotes con las interrupciones, no te va a funcionar tan bien como esperabas. Mira este fragmento de tu código:

      for(ama=100;ama<=255;ama++)
      {
        delay(20);
        analogWrite(AmaSup,ama);
        analogWrite(AmaInf,ama);
      }
      delay(1000);//Tiempo de duracion con la luz máxima
      for(ama=255;ama>=50;ama--)
      {
        delay(20);
        analogWrite(AmaSup,ama);
        analogWrite(AmaInf,ama);
      }
      for(ama=50;ama<=100;ama++)
      {
        delay(20);
        analogWrite(AmaSup,ama);
        analogWrite(AmaInf,ama);
      }

El primer bucle ejecuta 156 delay(20), eso supone 3120 milisegundos. Luego una pausa de 1000 milisegundos gracias al delay(1000). Continúa con otro bucle que realiza otros 206 delay(20), eso supone otos 4120 milisegundos más. Y por último un bucle de 51 delay(20), que son 1020 milisegundos más. Todos hacen un total de 9260 milisegundos. Digamos que son 9 segundos. Nueve segundos que no hace otra cosa más que “jugar con las lucecitas” y atender a las interrupciones. Pero durante esos nueve segundos no se comprueba el valor que tiene la variable boton para cambiar de efecto. Con lo que no importa si lo has pulsado nada más empezar el juego de luces o cuando lleve cinco segundos, sólo le hará caso al cambio de valor de boton cada nueve segundos. ¿Sabes lo largo que se te pueden hacer nueve segundos? Le das al botón y no pasa nada… bueno, a no ser que esperes lo suficiente, entre cero y nueve segundos, dependiendo de cuánto tiempo lleve ejecutándose esa parte del programa. ¿Entiendes cuál es el problema?

Si no te importa que funcione así entonces no necesitas usar los millis() para controlar los rebotes cuando se ejecute la interrupción. Ya tienes un “estupendo” anti rebotes que te garantiza que no saltará de una secuencia a otra instantáneamente, has de esperar unos cuantos segundos entre una y otra ya que sólo pasa a la siguiente una vez termine el ciclo.

Así que, si no te importa tener que esperar a que termine un efecto para que comience el otro, lo único que has de hacer es que la interrupción “marque” que se ha pulsado el botón al menos una vez (no importa si se pulsa varias veces ya que no va a hacerle caso hasta que se llegue al final de la secuencia actual, aunque puede que si lo pillas al final de la secuencia lo lea también en la siguiente y sólo la haga una vez y pase a la próxima). Simplemente, cuando las secuencias terminan y antes de que se vuelva a repetir, verifica si se la interrupción ha “marcado” que se pulsó el botón. Si es así entonces pasas a la siguiente secuencia, “quitas la marca” y a esperar. Listo, así de fácil.

Si lo que quieres es que nada más pulsar el botón cambie de secuencia, entonces la solución es mucho más compleja de lo que te imaginas. Primero hay que hacer desaparecer todos los delay() con la ayuda de los millis(). Deberás de crear unas cuantas máquinas de estado. Una para controlar las pulsaciones del botón y qué secuencia se ha de ejecutar y unas cuantas para el control de las secuencias. No es tan trivial como poner un for detrás de otro y los delay() marcando el ritmo. Es más, no solo han de desaparecer los delay() que has puesto, también han de desaparecer todos los for.

Yo lo haría sin delay() y sin for, y por su puesto sin interrupciones. No es fácil, pero puede quedar muy bien.

En esta consulta del foro puedes hacerte una idea de por dónde va la cosa de cambiar los for por un loop() que "termina" rápido y por millis(): usar millis() junto con for() [SOLUCIONADO]

Aquí tienes tu código modificado para usar la interrupción. No lo he probado, ni tan siquiera lo he compilado.

Recuerda que no va a funcionar “fluido” y que una vez pulsado el botón se ha de esperar a que termine el ciclo del efecto “actual” (los nueve segundos).

/*Pines:
 Azul Inferior 7
 Amarillo Inferior 5(PWM)
 Ojos 12
 Azul Superior 4
 Amarillo Superior 3 (PWM)
 Boton 2
 */




#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;

volatile boolean seHaPulsadoElBoton = false; // Si es verdadero es que se ha pulsado el botón


//Variables Luces
int ojos=12, AmaSup=3, UVSup=4, AmaInf=5, UVInf=7, boton=0;//Todo son salidas del arduino que encienden leds, excepto "boton" que es una entrada para el pulsador

//Variables auxiliares y otras de los case
int aux1,ama;//Case 1
int aux2;//Case 2



void setup()
{
  //Configuracion pines
  pinMode(ojos,OUTPUT);
  pinMode(AmaSup,OUTPUT);
  pinMode(UVSup,OUTPUT);
  pinMode(AmaInf,OUTPUT);
  pinMode(UVInf,OUTPUT);
  pinMode(2,INPUT);

  //Interrupcion para el boton
  attachInterrupt(digitalPinToInterrupt(2), pulsador, RISING);






  //¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡No tocar lo que viene a continuacion, es del DFPlayer(Reproductor de música) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  mySoftwareSerial.begin(9600);
  Serial.begin(115200);
  if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
  }
  myDFPlayer.volume(20);  //Configuracion del volumen, valores de 0 a 30!!!!!!!!!!!!!!!!

}








void loop()
{
  if (seHaPulsadoElBoton) {
    // Si se ha pulsado el botón pasamos al siguiente valor de la variable
    boton = (boton + 1) % 3;    // El "% 3" es para hacer que al valor de boton sea entre 0 y 2 (cuando se implente el "efecto 3" se ha de poner "% 4")
    delay(40);                  // Ya puesto a usar delay() lo usamos para evitar el efecto rebote si justo nos pilla en esta parte del código
    seHaPulsadoElBoton = false; // Una vez asegurado que han transcurrido el "tiempo antirebote" borramos el flag que nos indica que se ha pulsado
  }

  switch(boton){//Acontinuacion los diferentes modos de funcionamiento
    case 0://Todo apagado
      digitalWrite(UVSup,LOW);
      digitalWrite(UVInf,LOW);
      digitalWrite(ojos,LOW);
      analogWrite(AmaSup,0);
      analogWrite(AmaInf,0);
      break;



    case 1://Solo luz amarilla
      while(aux1==0)//Le pongo el while para que el primer "for" solo se ejecute una vez 
      {
        for(ama=0;ama<=100;ama++)//Este solo para cuando se inicie por primera vez
        {
          delay(50);
          analogWrite(AmaSup,ama);
          analogWrite(AmaInf,ama);
        }
        aux1++;
      }

      for(ama=100;ama<=255;ama++)
      {
        delay(20);
        analogWrite(AmaSup,ama);
        analogWrite(AmaInf,ama);
      }
      delay(1000);//Tiempo de duracion con la luz máxima
      for(ama=255;ama>=50;ama--)
      {
        delay(20);
        analogWrite(AmaSup,ama);
        analogWrite(AmaInf,ama);
      }
      for(ama=50;ama<=100;ama++)
      {
        delay(20);
        analogWrite(AmaSup,ama);
        analogWrite(AmaInf,ama);
      }

      break;




    case 2://Luz amarilla y musica
      while(aux2==0)////Le pongo el while para que el primer "for" solo se ejecute una vez 
      {
        myDFPlayer.play(1); //Comando para que empiece a sonar la primera cancion
        for(ama=0;ama<=100;ama++)//Este solo para cuando se inicie por primera vez
        {
          delay(50);
          analogWrite(AmaSup,ama);
          analogWrite(AmaInf,ama);
        }
        aux2++;
      }

      for(ama=100;ama<=255;ama++)
      {
        delay(20);
        analogWrite(AmaSup,ama);
        analogWrite(AmaInf,ama);
      }
      delay(1000);//Tiempo de duracion con la luz máxima
      for(ama=255;ama>=50;ama--)
      {
        delay(20);
        analogWrite(AmaSup,ama);
        analogWrite(AmaInf,ama);
      }
      for(ama=50;ama<=100;ama++)
      {
        delay(20);
        analogWrite(AmaSup,ama);
        analogWrite(AmaInf,ama);
      }
      break;



    case 3://Todos los efectos(todas las luces y la musica)
      //Falta 
      break;
  }




}

//Funcion para el pulsador
void pulsador()
{
  seHaPulsadoElBoton = true; // Marcamos que se ha pulsado el botón
}

Fíjate que sólo he hecho tres cosas. Definir la variable seHaPulsadoElBoton:

volatile boolean seHaPulsadoElBoton = false; // Si es verdadero es que se ha pulsado el botón

Modificar la interrupción para que “marque” cuando se pulsa el botón:

//Funcion para el pulsador
void pulsador()
{
  seHaPulsadoElBoton = true; // Marcamos que se ha pulsado el botón
}

Y añadir el lugar donde se actualiza la variable boton si se ha pulsado, justo antes de evaluar el switch(boton):

  if (seHaPulsadoElBoton) {
    // Si se ha pulsado el botón pasamos al siguiente valor de la variable
    boton = (boton + 1) % 3;    // El "% 3" es para hacer que al valor de boton sea entre 0 y 2 (cuando se implente el "efecto 3" se ha de poner "% 4")
    delay(40);                  // Ya puesto a usar delay() lo usamos para evitar el efecto rebote si justo nos pilla en esta parte del código
    seHaPulsadoElBoton = false; // Una vez asegurado que han transcurrido el "tiempo antirebote" borramos el flag que nos indica que se ha pulsado
  }

Nota: el % 3 es para que la variable boton pase de valer 2 a valer 0. El valor 3 no lo permito porque no has implementado aún el efecto 3. Si implementas el efecto 3 no olvides cambiarlo por % 4.

Aquí te dejo un primer paso para hacer lo que quieres sin delay(), sin for, y sin interrupciones. A base de millis() y máquinas de estado. Espera a que pulses el botón para poner en marcha el efecto de luces. Y si lo vuelves a pulsar apaga el efecto de luces de forma gradual. Si vuelves a pulsar lo vuelve a encender, etc.

// https://github.com/thomasfredericks/Bounce2
#include <Bounce2.h>                    // La libreriá antirebote

const bool VALOR_BOTON_PULSADO = HIGH;  // En mi caso la entrada se pone a nivel alto se se pulsa el botón si fuera al revés cambiar HIGH por LOW
const int PIN_BOTON = 2;                // Pin al que está conectado el botón

Bounce boton = Bounce();                // Lectura del botón utilizando la librería antirebote

enum estado_luz_t {                     // Definción de los estado de la máquina de estados que controla el brillo de la luz
  ESTADO_LUZ_APAGADO,                   // La luz ha de estar apagada (no se apaga instantáneamente, sino gradualmente)
  ESTADO_LUZ_0_100,                     // La luz se está encendiendo poco a poco de 0 a 100
  ESTADO_LUZ_100_255,                   // La luz se está encendiendo poco a poco de 100 a 255
  ESTADO_LUZ_255_255,                   // La luz ha de permanecer a la máxima intensidad (255)
  ESTADO_LUZ_255_50                     // La luz se ha de atenuar hasta 50
} estadoLuz = ESTADO_LUZ_APAGADO;       // Variable que controla el estado de la máquina de estado de la luz

int intensidadLuz = 0;                  // Intensidad actual de la luz
unsigned long delayLuz = 50UL;          // Tiempo que ha de esperarse para pasar al siguiente nivel de brillo de la luz (simula un delay())
unsigned long instanteAnteriorLuz = 0;  // Para saber cuánto tiempo ha pasado desde el anterior cambio de brillo

bool valorBotonAnterior = !VALOR_BOTON_PULSADO;    // Para poder detectar los flancos de subida o bajada del pulsador

//Variables Luces
int ojos=12, AmaSup=3, UVSup=4, AmaInf=5, UVInf=7; // Todo son salidas del arduino que encienden leds

void setup() {
  //Configuracion pines
  pinMode(ojos, OUTPUT);
  pinMode(AmaSup, OUTPUT);
  pinMode(UVSup, OUTPUT);
  pinMode(AmaInf, OUTPUT);
  pinMode(UVInf, OUTPUT);
  pinMode(2, INPUT);
  boton.attach(PIN_BOTON);    // Le indicamos a la librería Bounce2.h cual es el pin del botón
  boton.interval(5);          // Tiempo que ha de transcurrir para asegurarse que no hay rebote (si detecta algún rebote se ha de incrementar el valor)
}

void loop() {
  boton.update();                             // Esto le da "ciclos de CPU" a la librería Bounce2.h para calcular el valor del botón y filtrar los rebotes
  bool valorBoton = boton.read();             // Obtiene el estado del botón
  if (valorBotonAnterior != valorBoton) {     // Si ha cambiado de estado (se acaba de pulsar o de liberar)
    valorBotonAnterior = valorBoton;          // Recordamos el estado actual
    if (valorBoton == VALOR_BOTON_PULSADO) {  // Si se encuentra pulsado...
      if (estadoLuz == ESTADO_LUZ_APAGADO) {  // Si la luz está apagada...
        estadoLuz = ESTADO_LUZ_0_100;         // Se pasa al estado de inicio de encendido de la luz
        delayLuz = 50UL;                      // Cada 50 milisegundos se ha de incrementar la intensidad en una unidad (canbiando este valor se encenderá más rápido o más lento)
      }
      else {                                  // Si la luz no está apagada es que está encendida...
        estadoLuz = ESTADO_LUZ_APAGADO;       // Así que pasamos la máquina de estado al estado "apagado"
        delayLuz = 4UL;                       // Cada 4 milisegundos decrementará la intensidad de la luz en una unidad hasta que sea cero (cambiando este valor se apagará más rápido o más lento)
      }
    }
  }
  unsigned long instanteActual = millis();                  // Obtenemos el instante de tiempo actual
  if ((instanteActual - instanteAnteriorLuz) >= delayLuz) { // Si ha transcurrido el tiempo deseado (esto es el equivalente del delay())
    instanteAnteriorLuz = instanteActual;                   // Recordamos este instante para poder calcular en el futuro cuánto tiempo ha pasado
    int anteriorIntensidadLuz = intensidadLuz;              // Recordamos la intensidad actual para saber si cambia
    switch (estadoLuz) {                                    // Determinamos en que estado está la máquina de estados de la luz
      case ESTADO_LUZ_APAGADO :                             // La luz ha de estar apagada
        if (intensidadLuz > 0) {                            // Si todavía está encendida...
          intensidadLuz--;                                  // Decrementamos un punto la intensidad de la luz. El tiempo que ha esperar para seguir decrementando se debe de haber estipulado anteriormente (cuando se hizo "estadoLuz = ESTADO_LUZ_APAGADO;")
        }
        break;
      case ESTADO_LUZ_0_100 :                               // Si la luz ha de encenderse hata 100...
        intensidadLuz++;                                    // Incredmentamos la intensidad de la luz
        if (intensidadLuz >= 100) {                         // Si la intensidad ya ha alcanzado el valor deseado...
          estadoLuz = ESTADO_LUZ_100_255;                   // Pasamos a incrementar la intensidad hasta 255
          delayLuz = 20UL;                                  // A intervalos de 20 milisegundos
        }
        break;
      case ESTADO_LUZ_100_255 :                             // Si estamos incrementando hasta 200...
        intensidadLuz++;                                    // Incredmentamos la intensidad de la luz
        if (intensidadLuz >= 255) {                         // Si la intensidad ya ha alcanzado el valor deseado...
          estadoLuz = ESTADO_LUZ_255_255;                   // Pasamos al estado que espera con el valor valor máximo
          intensidadLuz = 255;                              // Nos aseguramos que tiene el valor 255
          delayLuz = 1000UL;                                // El intervalo ha de ser de 1 segundo
        }
        break;
      case ESTADO_LUZ_255_255 :                             // Está con la máxima intensidad
        estadoLuz = ESTADO_LUZ_255_50;                      // Ya debe de haber pasado el tiempo deseado a máxima intensidad, así que ahora se bajará hasta 50
        delayLuz = 20UL;                                    // El decremento se hará en intervalos de 20 milisegundos
        break;
      case ESTADO_LUZ_255_50 :                              // Está decrementando hasta 50
        intensidadLuz--;                                    // Decrementa la intensidad
        if (intensidadLuz <= 50) {                          // Si la intensidad ha llegado a su mínimo...
          estadoLuz = ESTADO_LUZ_100_255;                   // Ha de incrementarse hasta 255 (no importa que tenga un valor inferior a 100)
        }
        break;
    }
    if (anteriorIntensidadLuz != intensidadLuz) {           // Si la inensidad de la luz ha cambiado...
      analogWrite(AmaSup, intensidadLuz);                   // Actualizamos las salidas
      analogWrite(AmaInf, intensidadLuz);
    }
  }
}

Sólo está el paso uno, faltarían el paso dos y tres. Pero es que lo he hecho un poco deprisa y corriendo para que te hagas una idea.

Si ves que el Arduino empieza encendiendo las luces sin pulsar el botón, es que hay que cambiar el valor de la constante VALOR_BOTON_PULSADO. Deberías de definirla con el valor LOW en lugar de HIGH.

Utiliza la librería Bounce2 que te la puedes descargar aquí: https://github.com/thomasfredericks/Bounce-Arduino-Wiring/archive/master.zip