domingo, 9 de agosto de 2020

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 leido un botón y hemos eliminado el debounce por software, ahorrandonos 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. Generalemente 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

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 boton con antirebote 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 leido, 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 sa 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 boton vale "1" estará suelto,
  // "0" y el botón estará apretado. Si pasa de "1" a "0" es que lo estamos aprentando
  // 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 mirais el arduino, no está haciendo nada que veamos; pero cuando pulsamos el botón: plas! se enciende el led y envia un mensaje. Si lo mantenéis pulsado el led sigue encendido, pero no hace nada mas. Cuando lo sueltas, el led se apaga! y envia un mensaje.

Vamos a jugar un poco más pero, uff.. que perreria... escribir tanto... venga hagamos una pequeña libreria para leer botones y ahorrarnos código.

No hay comentarios:

Publicar un comentario