Diferencia entre revisiones de «Rebote»

De ArduWiki
Saltar a: navegación, buscar
(Solucion 4)
(Vea también)
 
(No se muestran 35 ediciones intermedias del mismo usuario)
Línea 6: Línea 6:
 
== Solucion 2 ==
 
== Solucion 2 ==
 
La solución por software mas simple consiste en aplicar un '''pequeño retardo''' luego de cada vez que se detecta la transicion del pulsador. Eso elimina el ruido.
 
La solución por software mas simple consiste en aplicar un '''pequeño retardo''' luego de cada vez que se detecta la transicion del pulsador. Eso elimina el ruido.
 +
 
<syntaxhighlight lang="c++">
 
<syntaxhighlight lang="c++">
const byte boton = 2;    //Pulsador
 
const byte led = 13;    //LED
 
 
 
void setup() {
 
void setup() {
   pinMode(boton, INPUT);
+
   pinMode(2, INPUT);     //Pulsador
   pinMode(led, OUTPUT);
+
   pinMode(13, OUTPUT);    //LED
   digitalWrite(led, LOW);
 
 
}
 
}
  
 
void loop() {
 
void loop() {
 
   //Lee la entrada
 
   //Lee la entrada
   if (digitalRead(boton)){
+
   if (digitalRead(2)){
       digitalWhite(led, !digitalRead(lead));
+
       digitalWhite(13, !digitalRead(13));
       delay(50);   //Retardo que elimina ruido
+
       delay(50);         //Retardo que elimina ruido
 
   }
 
   }
 
}
 
}
Línea 26: Línea 23:
  
 
== Solucion 3 ==
 
== Solucion 3 ==
Quizas los puristas que desean desterrar la funcion [[delay()]] prefieran usar esta solucion:
+
Otra solución simple que funciona la mayoría de las veces es fijarse en el estado anterior del botón asi.
 +
 
 
<syntaxhighlight lang="c++">
 
<syntaxhighlight lang="c++">
const byte boton = 2;   //Pulsador
+
bool estado,anterior;
const byte led = 13;     //LED
+
void setup() {
unsigned long tiempo = 0
+
  pinMode(2, INPUT_PULLUP); //Pulsador
 +
  pinMode(13, OUTPUT);       //LED
 +
}
 +
 
 +
void loop() {
 +
  estado = digitalRead(2);
 +
  if (!estado && anterior) {
 +
      digitalWrite(13, !digitalRead(13));
 +
  }
 +
  anterior = estado;
 +
}
 +
</syntaxhighlight>
 +
 
 +
== Solución 4 ==
 +
Quizás los puristas que desean desterrar la función [[delay()]] prefieran usar esta solución:
 +
 
 +
<syntaxhighlight lang="c++">
 +
unsigned long tiempo;
  
 
void setup() {
 
void setup() {
   pinMode(boton, INPUT);
+
   pinMode(2, INPUT);     //Pulsador
   pinMode(led, OUTPUT);
+
   pinMode(13, OUTPUT);   //LED
  digitalWrite(led, LOW);
 
 
}
 
}
  
 
void loop() {
 
void loop() {
 
   //Lee la entrada
 
   //Lee la entrada
   if (digitalRead(boton)){
+
   if (digitalRead(2)){
 
       if (millis() > tiempo + 50){
 
       if (millis() > tiempo + 50){
         digitalWhite(led, !digitalRead(lead));
+
         digitalWhite(13, !digitalRead(13));
 
         tiempo = millis();
 
         tiempo = millis();
 
       }
 
       }
Línea 49: Línea 63:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
== Solución 4 ==
+
== Solución 5 ==
 +
Una solución que funciona muchas veces se trata simplemente de comparar el estado del pulsador con su estado anterior y solo actuar si su estado es HIGH y su anterior LOW.
 +
 
 +
<syntaxhighlight lang="c++">
 +
const byte boton = 2;
 +
bool estado,anterior;
 +
 
 +
void setup(){
 +
  pinMode(LED_BUILTIN, OUTPUT);
 +
}
 +
 
 +
void loop() {
 +
  estado = digitalRead(boton);
 +
  if (estado && !anterior){
 +
      digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
 +
  }
 +
  anterior = estado;
 +
}
 +
</syntaxhighlight>
 +
 
 +
{{Tip|Este es mi preferido por lo simple.}}
 +
 
 +
== Solución 6 ==
 
El siguiente boceto se basa en la versión de rebote de Limor Fried. En este ejemplo, el pulsador retorna HIGH cuando se presiona y LOW cuando no se presiona.
 
El siguiente boceto se basa en la versión de rebote de Limor Fried. En este ejemplo, el pulsador retorna HIGH cuando se presiona y LOW cuando no se presiona.
  
Línea 96: Línea 132:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
== Solución 5 ==
+
== Solución 7 ==
 +
<syntaxhighlight lang="c++">
 +
bool actual,anterior;
 +
unsigned long db;
 +
byte modo = 1;
 +
 
 +
void setup(){
 +
  Serial.begin(9600);
 +
  pinMode(2, INPUT_PULLUP);
 +
}
 +
 
 +
void loop(){
 +
  actual = digitalRead(2);
 +
  if (!actual && anterior && millis()-db >= 150UL){
 +
      modo++;
 +
      if (modo > 5){
 +
        modo = 1;
 +
      }
 +
      Serial.println(modo);
 +
      db = millis();         
 +
  }
 +
  anterior = actual;
 +
}
 +
 
 +
</syntaxhighlight>
 +
 
 +
== Solución 8 ==
 
Eliminación del rebote mediante [http://playground.arduino.cc/code/debounce libreria Debounce]
 
Eliminación del rebote mediante [http://playground.arduino.cc/code/debounce libreria Debounce]
  
 
<syntaxhighlight lang="c++">
 
<syntaxhighlight lang="c++">
 
#include <Debounce.h>
 
#include <Debounce.h>
#define pulsador 5
+
Debounce rebote = Debounce(20, 2);  //Asigna 20 ms de retardo en pulsador
#define LED 13
+
 
Debounce rebote = Debounce(20, pulsador);  //Asigna 20 ms de retardo en pulsador
+
void setup() {
 +
  pinMode(2, INPUT);        //Pulsador
 +
  pinMode(13, OUTPUT);      //LED
 +
}
 +
 
 +
void loop() {
 +
  rebote.update();                  //Actualizar instancia de clase
 +
  digitalWrite(13, rebote.read());  //Obtener pulso
 +
}
 +
</syntaxhighlight>
 +
 
 +
== Solución 9 ==
 +
Eliminación del rebote mediante [https://github.com/thomasfredericks/Bounce2/wiki libreria Bounce2]
 +
 
 +
{| class="wikitable"
 +
|-
 +
! Método !! Descripción
 +
|-
 +
| .read() || Lee el estado del pin actualizado.
 +
|-
 +
| .fell() || Devuelve verdadero si el pin pasa de HIGH a LOW. (falling)
 +
|-
 +
| .rose() || Devuelve verdadero si el pin pasa de LOW a HIGH. (rising)
 +
|}
 +
 
 +
<syntaxhighlight lang="c++">
 +
#include <Bounce2.h>
 +
Bounce rebote = Bounce(2, 50);    //Instancia de la clase con retardo de 50 ms
  
 
void setup() {
 
void setup() {
   pinMode(pulsador, INPUT);
+
   pinMode(2, INPUT_PULLUP);     //Pulsador
   pinMode(LED, OUTPUT);
+
   pinMode(13, OUTPUT);           //LED
 
}
 
}
  
 
void loop() {
 
void loop() {
   rebote.update();                   //Actualizar instancia de clase
+
   rebote.update();                       //Actualiza instancia de clase
   digitalWrite(LED, rebote.read()); //Obtener pulso
+
   if (rebote.rose()){;                   //Lee pulsador cuando se suelta
 +
      digitalWrite(13, !digitalRead(13);  //Conmuta LED
 +
  }
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 
== Vea también ==
 
== Vea también ==
* [[digitalRead()]]
+
<categorytree mode=all>Funciones pines</categorytree>
* [[digitalWrite()]]
 
* [[analogRead()]]
 
* [[analogWrite()]]
 
* [[Programacion avanzada]]
 
  
 
== Referencias ==
 
== Referencias ==
 
* [http://playground.arduino.cc/code/debounce Playground]
 
* [http://playground.arduino.cc/code/debounce Playground]
* [https://www.luisllamas.es/debounce-interrupciones-arduino/ Luis Llamas]
+
* [https://www.luisllamas.es/debounce-interrupciones-arduino/ Debounce] - Luis Llamas
* [https://aprendiendoarduino.wordpress.com/2017/06/19/ejemplos-practicos-arduino/ Enrique Crespo]
+
* [https://aprendiendoarduino.wordpress.com/2017/06/19/ejemplos-practicos-arduino/ Ejemplos prácticos Arduino] - Enrique Crespo
* [https://manueldelgadocrespo.blogspot.com/p/digitalread.html Manuel Delgado]
+
* [https://manueldelgadocrespo.blogspot.com/p/digitalread.html DigitalRead] - Manuel Delgado
 +
* [https://programarfacil.com/blog/utilizar-pulsadores-en-arduino/ Utilizar un pulsador sin saber nada de electrónica] - Luis Del Valle
 +
* [https://core-electronics.com.au/tutorials/switch-debouncing-with-arduino.html Interruptores, Debouncing y el Arduino] - Core Electronics
 +
* [https://manualarduinos52.wordpress.com/2013/12/06/practica-6/ Funcion antirebote] - Manual de practicas Arduino
  
[[Category:Estructura]]
+
[[Category:Librerias]]

Revisión actual del 22:01 7 oct 2019

El rebote es un efecto muy comun en los contactos electricos del tipo pulsadores, interruptores, contactos de rele, etc. Debido a problemas fisicos y mecanicos se produce un chisporroteo, que al ser leido por Arduino se convierte en muchos pulsos de un corto periodo, de forma que el pulsar el boton una sola vez puede causar resultados impredesibles.

Solucion 1

La mejor solucion es por hardware poniendo un condensador de 1 uF en paralelo con el pulsador.

Solucion 2

La solución por software mas simple consiste en aplicar un pequeño retardo luego de cada vez que se detecta la transicion del pulsador. Eso elimina el ruido.

void setup() {
   pinMode(2, INPUT);      //Pulsador
   pinMode(13, OUTPUT);    //LED
}

void loop() {
   //Lee la entrada
   if (digitalRead(2)){
      digitalWhite(13, !digitalRead(13));
      delay(50);          //Retardo que elimina ruido
   }
}

Solucion 3

Otra solución simple que funciona la mayoría de las veces es fijarse en el estado anterior del botón asi.

bool estado,anterior;
void setup() {
   pinMode(2, INPUT_PULLUP);  //Pulsador
   pinMode(13, OUTPUT);       //LED
}

void loop() {
   estado = digitalRead(2);
   if (!estado && anterior) {
      digitalWrite(13, !digitalRead(13));
   }
   anterior = estado;
}

Solución 4

Quizás los puristas que desean desterrar la función delay() prefieran usar esta solución:

unsigned long tiempo;

void setup() {
   pinMode(2, INPUT);     //Pulsador
   pinMode(13, OUTPUT);   //LED
}

void loop() {
   //Lee la entrada
   if (digitalRead(2)){
      if (millis() > tiempo + 50){
         digitalWhite(13, !digitalRead(13));
         tiempo = millis();
      }
   }
}

Solución 5

Una solución que funciona muchas veces se trata simplemente de comparar el estado del pulsador con su estado anterior y solo actuar si su estado es HIGH y su anterior LOW.

const byte boton = 2;
bool estado,anterior;

void setup(){
   pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
   estado = digitalRead(boton);
   if (estado && !anterior){
      digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
   }
   anterior = estado;
}

Tip: Este es mi preferido por lo simple.


Solución 6

El siguiente boceto se basa en la versión de rebote de Limor Fried. En este ejemplo, el pulsador retorna HIGH cuando se presiona y LOW cuando no se presiona.

Cada vez que el pin de entrada pasa de LOW a HIGH (se pulso el botón), el pin de salida cambia de LOW a HIGH y HIGH a LOW varias veces. Para ignorar este ruino se introduce un retraso mínimo entre las conmutaciones.

const byte boton = 2;    //Pulsador
const byte led = 13;     //LED

bool ledState = HIGH;         //El estado actual del pin de salida (LED).
bool buttonState;             //El estado actual del pin de entrada (Pulsador).
bool lastButtonState = LOW;   //El estado anterior del pin de entrada (Pulsador).

unsigned long tiempo = 0;    //Ultima vez que cambio la entrada (pulsador)
unsigned long retardo = 50;  //Tiempo de retardo. Aumentar si salida parpadea

void setup() {
   pinMode(boton, INPUT);
   pinMode(led, OUTPUT);
   digitalWrite(led, ledState);
}

void loop() {
   //Lee la entrada
   bool reading = digitalRead(boton);

   //Comprueba si acaba de pulsar (LOW a HIGH)
   if (reading != lastButtonState) {
      //Reinicia temporizador
      tiempo = millis();
   }

   if ((millis() - tiempo) > retardo) {
      if (reading != buttonState) {
         buttonState = reading;

         //Solo cambia LED si es pulsado 
         if (buttonState) {
            ledState = !ledState;
         }
      }
   }
   digitalWrite(led, ledState);
   lastButtonState = reading;
}

Solución 7

bool actual,anterior;
unsigned long db;
byte modo = 1;

void setup(){
   Serial.begin(9600);
   pinMode(2, INPUT_PULLUP);
}

void loop(){
   actual = digitalRead(2);
   if (!actual && anterior && millis()-db >= 150UL){
      modo++;
      if (modo > 5){
         modo = 1;
      }
      Serial.println(modo);
      db = millis();           
   }
   anterior = actual;
}

Solución 8

Eliminación del rebote mediante libreria Debounce

#include <Debounce.h>
Debounce rebote = Debounce(20, 2);   //Asigna 20 ms de retardo en pulsador

void setup() {
   pinMode(2, INPUT);        //Pulsador
   pinMode(13, OUTPUT);      //LED
}

void loop() {
   rebote.update();                  //Actualizar instancia de clase
   digitalWrite(13, rebote.read());  //Obtener pulso
}

Solución 9

Eliminación del rebote mediante libreria Bounce2

Método Descripción
.read() Lee el estado del pin actualizado.
.fell() Devuelve verdadero si el pin pasa de HIGH a LOW. (falling)
.rose() Devuelve verdadero si el pin pasa de LOW a HIGH. (rising)
#include <Bounce2.h>
Bounce rebote = Bounce(2, 50);    //Instancia de la clase con retardo de 50 ms

void setup() {
   pinMode(2, INPUT_PULLUP);      //Pulsador
   pinMode(13, OUTPUT);           //LED
}

void loop() {
   rebote.update();                        //Actualiza instancia de clase
   if (rebote.rose()){;                    //Lee pulsador cuando se suelta
      digitalWrite(13, !digitalRead(13);   //Conmuta LED
   }
}

Vea también


Referencias