2020-08-08
Como NO leer un botón y como SI debemos hacerlo. (2)
Este tutorial es un extracto del tutorial que cree para el foro de Arduino, si quieres ver el tutorial completo, ver los comentario y/o los añadidos al tutorial visita Como NO leer un botón y como SI debemos hacerlo.
Ya hemos leído un botón y hemos eliminado el debounce por software, ahorrándonos un condensador. Pero vamos a complicar la cosa.
Un botón puede estar en cuatro estados:
- Suelto que es cuando no lo tocas y solo lo miras. En este estado tendrá un valor, en nuestro caso estará a HIGH tal y como lo enchufamos. Generalmente es el estado que menos nos interesa ya que no haremos nada en él.
- Apretándolo. Justo ese momento en el que el botón pasa de estar suelto a apretado, en nuestro ejemplo pasa del estado HIGH a LOW. Este si es útil, como hemos visto en el apartado anterior.
- Apretado. Aquí ya lo mantenemos pulsado y su valor será LOW. En este estado podemos hacer cosas, pero ya sabes, el loop es rápido y se ejecutará muchas veces cuando lo mantengas pulsado.
- Soltándolo. Justo ese momento en el botón pasa de estar apretado a estar suelto. En nuestro caso es cuando se pasa de LOW a HIGH. También es útil para hacer cosas, dependiendo de lo que queramos hacer. Cuando sale de este estado, se queda de nuevo en suelto.
Recordar: estamos usando una configuración pull-up. Si usamos otro tipo de configuración los valores HIGH/LOW podrán interpretarse de otra manera.
Así que sabiendo esto se lo podemos añadir a nuestro código para determinar en que estado está el botón:
/* * 5. Leyendo un botón con anti rebote por software y determinando su estado. * * * NOTA: en el ejemplo "anterior" estado guardaba el valor de la variable, como * ahora vamos a tener un estado de verdad cambiamos ese nombre de variable a * valor para hora usar un estado como estado propiamente dicho. */ #define APRETADO 0 #define SUELTO 1 #define APRETANDOLO 2 #define SOLTANDOLO 3 const int boton = 2; // Botón asignado en el pin 2. int anterior; // guardamos el estado anterior. int valor; // valor actual del botón. int estado; unsigned long temporizador; unsigned long tiemporebote = 50; void setup() { Serial.begin(9600); pinMode(boton,INPUT_PULLUP); pinMode(13,OUTPUT); // Vamos a usar el led de la placa como señalización. valor = HIGH; anterior = HIGH; } void loop() { // Si el estado es igual a lo leído, la entrada no ha cambiado lo que // significa que no hemos apretado el botón (ni lo hemos soltado); asi que // tenemos que parar el temporizador. if ( valor==digitalRead(2) ) { temporizador = 0; } // Si el valor distinto significa que hemos pulsado/soltado el botón. Ahora // tendremos que comprobar el estado del temporizador, si vale 0, significa que // no hemos guardado el tiempo en el que se ha producido el cambio, así que // hemos de guardarlo. else if ( temporizador == 0 ) { // El temporizador no está iniciado, así que hay que guardar // el valor de millis en él. temporizador = millis(); } else // El temporizador está iniciado, hemos de comprobar si el // el tiempo que deseamos de rebote ha pasado. if ( millis()-temporizador > tiemporebote ) { // Si el tiempo ha pasado significa que el estado es lo contrario // de lo que había, asi pues, lo cambiamos. valor = !valor; } // Ahora comprobamos el estado. Recordad que si el botón vale "1" estará suelto, // "0" y el botón estará apretado. Si pasa de "1" a "0" es que lo estamos apretando // y si es al contrario es que lo estamos soltando. if ( anterior==LOW && valor==LOW ) estado = APRETADO; if ( anterior==LOW && valor==HIGH ) estado = SOLTANDOLO; if ( anterior==HIGH && valor==LOW ) estado = APRETANDOLO; if ( anterior==HIGH && valor==HIGH ) estado = SUELTO; // Recuerda que hay que guardar el estado anterior. anterior = valor; // Ahora vamos a ver que podemos hacer con el estado. switch ( estado ) { case SUELTO: digitalWrite(13,LOW); break; // Apagamos el led. case APRETANDOLO: Serial.write("Has apretado el botón"); break; // Mandamos un mensaje. case APRETADO: digitalWrite(13,HIGH); break; // Encendemos el led. case SOLTANDOLO: Serial.write("Has soltado el botón"); break; // Mandamos un mensaje. default: break; } }
Podéis jugar un poco ahora con el Arduino. Si miráis el Arduino, no está haciendo nada que veamos; pero cuando pulsamos el botón: plas! se enciende el led y envía un mensaje. Si lo mantenéis pulsado el led sigue encendido, pero no hace nada mas. Cuando lo sueltas, el led se apaga! y envía un mensaje.
Vamos a jugar un poco más pero, uff.. que perrería... escribir tanto... venga hagamos una pequeña librería para leer botones y ahorrarnos código.