Cambio de estado de un pulsador

¿cuantas veces nos ha pasado que nuestro proyecto necesita de uno o varios pulsadores? no hay problema, los pulsadores son sencillos de implementar y para leer su estado solo hay que hacer un digitalRead()…

…pero luego resulta que nuestro Arduino UNO o Leonardo hace cosas raras: si la acción a disparar por la pulsación es corta puede que nos la haga miles de veces por segundo o si es larga puede que no suceda nada cuando accionamos otros pulsadores porque Arduino está ocupado en otras cosas y no puede mirar el estado del pin al que hayamos conectado el pulsador.

A mi me pasó que tenía que medir las revoluciones por minuto de un anemómetro y no podía estar todo el tiempo esperando a que se activara el pin y cuando la velocidad de giro de aquel anemómetro era muy lenta el contador se volvía loco cada vez que se cerraba el contacto.

Solución: programar un pequeño código que detecte cuando un pin cambia de estado, bien sea de bajo a alto o viceversa, y además que lleve un contador dentro… y ha resultado ser uno de los códigos que más veces saco de mi “caja de herramientas”.

Mirad que sencillo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int estadoAnterior = 0;
int estadoActual;
int contador = 0;
int pin; // aquí el pin digital que se quiere leer

void setup()
{
  pinMode(pin, INPUT);
}

void loop()
{
  estadoActual = digitalRead(pin);
  if (estadoAnterior != estadoActual)  // ha habido un cambio de estado
  {
    contador++;                          // cuenta los cambios de estado
    int validarPar = contador % 2;       // solo queremos los cambios pares
    if (validarPar != 1)                 // si el cambio es par
    {
      //ponga aqui su codigo
    }
    estadoAnterior = estadoActual;
  }
}

Utilizamos 3 variables: estadoActual, estadoAnterior y contador. El código se limita a mirar en cada loop si las variables estadoActual y estadoAnterior son diferentes, si ello sucede es que el estado del pin ha cambiado desde la última vez que lo miró, incrementa el contador y a partir de aquí es donde se hace la magia: si el resto de la división entre el contador y 2 es diferente de 1 es que el cambio de estado se ha producido de “pulsado” a “no pulsado” y pasará a ejecutar lo que pongamos debajo de “ponga aqui su codigo”.
Si queremos que la acción se desarrolle cuando el puslador es accionado solo hay que cambiar la condición de la línea 18 y poner esta otra “if (validarPar == 1)”.

Además tenemos un contador que cuenta todos los cambios de estado con lo que podemos utilizar este código en encoders u otros dispositivos similares.

Podemos utilizarlo dentro de una función con las variables como locales y el código actuando dentro de una parte muy específica del proyecto, como por ejemplo, en el menú hecho con una LCD y unos botones.

Además podemos hacer que funcione también con pines analógicos, pero eso será en otro tutorial.

6 Comments

  1. Hola que tal, disculpa, a que frecuencia maxima puedo leer los cambios de estado?, lo que pasa que me interesaria leer un enconder con tu codigo,,. saludos…

  2. Supongo que es recomendable usar un delay despues de la lectura. Me ha pasado que el error en la lectura viene por el lado de la estructura del boton mismo, los pulsadores tienen un “rebote” al ser presionados (cambian de estado varias veces antes de quedarse en uno por completo), al parecer has manejado eso controlando que el cambio sea par, pero mi duda es què delay recomienda al hacer la lectura para evitar este rebote?. Saludos y gracias por compartir.

    • El problema de usar un delay es que la placa se paraliza completamente durante el tiempo que le pongas al delay() y eso te puede dar muchos problemas.

  3. Hola.
    gracias por el tutorial, me ha servido para depurar mis botones.
    Podrías dar alguna indicación sobre como hacer algo parecido para los sensores analógicos? me estoy volviendo loco intentándolo y no hay manera…

  4. Hola que tal, solo para agradecer tu aportación de gran utilidad, me encuentro haciendo un anemómetro con un encoder y me ha sido de gran utilidad… gracias =)

Deja un comentario

Required fields are marked *.