Interruptor con Pull Down y condensador para rebotes

Hola a todos!!

Os voy a contar mi problema:

Quiero montar una alarma para una puerta, a la cual le he colocado un interruptor de imán con una resistencia Pull Down para evitar problemas.

Cuando la puerta se abre el interruptor pasa de Low a high y activa una interrupción por "RISING" ejecutando la función puerta, la cual de momento únicamente hace un conteo de las veces que se abre la puerta.

attachInterrupt(digitalPinToInterrupt(pin_puerta), puerta, RISING);

void puerta()
{
** contador = contador +1;**
** Serial.println(contador);**
}

Funciona casi todo bien, cuando la puerta se abre cuenta y cuando se cierra no cuenta ya que pasa de High a Low. El único problema es que al abrir la puerta en lugar de sumar +1 suma varios, debido a los rebotes del interruptor, así que como solución he puesto un condensador de 100 nf en paralelo a la resistencia Pull Down y así he conseguido que cuente de 1 en 1 cada vez que la puerta se abre.

PERO..... ahora tengo el problema que cuando la puerta se cierra se activa la interrupción y no debería, ya que se está pasando de High a Low y ademas por los rebotes, cuenta de varios en varios.

Resumiendo:

  • Sin condensador al abrir la puerta cuenta de varios en varios (eso es lógico por los rebotes) y al cerrar no cuenta (eso esta bien por que esta pasando de High a low y la interrupción es mediante RISING).
  • Con condensador al abrir suma de 1 en 1 y al cerrar cuenta de varios en varios, y no entiendo por me hace esto último ya está pasando de High a Low y sobre todo como solucionarlo.

Os muestro un esquema de como he conectado la resistencia y en condensador.

Gracias

Porque no usas millis() y miras el estado del sensor de puerta y observas si hay o no rebotes?

Siempre postea todo tu código porque desde el momento que consultas es porque no sabes donde esta el error y que nosotros veamos todo ayuda.

En una interrupción no puedes poner Serial.print() es otro contrasentido y otro gran error.
Las interrupciones deben ser rápidas. Solo activas desactivan flags, cambian contadores, cambian puertos, etc etc. pero jamás cosas lentas como un Serial.print.

t=RC = 10K * 100nF = 1 mili segundo quisas sea muy poco para tu tipo de interruptor.

Aumenta R o C.

Kike_GL:
t=RC = 10K * 100nF = 1 mili segundo quisas sea muy poco para tu tipo de interruptor.

Aumenta R o C.

El tiempo es suficiente, porque cuando la puerta se abre con el condensador no hay ningún rebote y sin el hay mas o menos 15 rebotes

Gracias

surbyte:
Porque no usas millis() y miras el estado del sensor de puerta y observas si hay o no rebotes?

Siempre postea todo tu código porque desde el momento que consultas es porque no sabes donde esta el error y que nosotros veamos todo ayuda.

En una interrupción no puedes poner Serial.print() es otro contrasentido y otro gran error.
Las interrupciones deben ser rápidas. Solo activas desactivan flags, cambian contadores, cambian puertos, etc etc. pero jamás cosas lentas como un Serial.print.

Probaré a sacar el serial.print fuera de la función de la interrupción y lo comprobare.

No posteo todo el código porque es muy amplio ya que también hay conexiones mqtt y es muy extenso, únicamente he puesto la parte que se ejecuta con la interrupción. Pero si veo que no lo consigo hare un sketch únicamente con el interruptor de la puerta.

De todas formas sigo sin entender el porque ejecuta la interrupción al pasar de High a Low (cerrar la puerta) si esta en RISING

Gracias!!

Con un debounce usando Bounce2 y lo fijas en 10 mseg no necesitas interrupción, ni capacitor.

Hi,
Para que el condesador te filtre los ruidos del contacto del switch tienes que cambiar la posicion del condesador con la resistencia. Adjunto un dibujo de como hacerlo para que te trabaje. En esta forma el condesador va a estar cargado a 5 voltios y cuando aprietas el switch vas a descargar el condesador y al abril el switch el condesador se va cargar eliminando el ruido. Debes de tratar con diferentes condensadores para ver cual de ellos te trabaja mejor. Creo de 1 uf a 5uf te debe de trabajar.

switch-cap-noise-filter.pdf (14.5 KB)

1 Like

Gracias Tauro por el aporte, pero con tu circuito no sé cómo adaptarlo a mi proyecto, necesito un pull down y en tu esquema no veo Gnd y que cuando se cierre en interruptor la salida se ponga a high.

Gracias

Hi,
No se si usas el positivo del switche para otro cosa en tu projecto pero lo unico que tiens que hacer es cambiar la intruccion que si la entrada es zero entonces incrementa el contador que cuenta las veces que la puerta se abre. Despues cambia la instruccion del interrupt de RAISING a FallING. Para que trabaje el condesador necesita este estar en paralelo con el switche. Tratalo entonces conectando el condesador en paralelo al switche en vez de la resistencia.

Insisto @Standby82 usa Bounce2, olvida la interrupción a menos que tu código no use delay() va a funcionar, pero si los usa no te dije nada y olvida mi sugerencia.

Con Bounce2 le puedes decir que no prestas atención al switch por los milisegundos que gustes.. y nada de capacitores arriba o abajo o constantes de tiempo.

Incluso Bounce2 tiene una función que el mismo usa el tiempo de debounce ajustable cuando detecta que no hay mas rebotes.

No puedo usar bounce2 porque quisiera el el arduino seguiría haciendo sus cosas y solo cuando se abra la puerta sea cuando se compruebe el estado de la alarma (activada o desactivada) y salte o no una sirena.

Por eso lo quería hacer con una interrupción, o creéis que es mejor de otra forma??

En este enlace tienes un ejemplo para evitar los rebotes en una interrupción, porque eso es lo que creo que te esta sucediendo.

Creo que no estamos yendo del tema principal.

Los rebotes los tengo solucionados con el R C y funciona genial, pero tengo el problema de que cuando cierro la puerta se me activa de nuevo la inteerupcion y no deberia activarse porque pasa de High a Low y yo tengo la interrupcion asi:

attachInterrupt(digitalPinToInterrupt(pin_puerta), puerta, RISING);

Si quito en condensador no se activa la interrupción al cerrar la puerta, pero al abrirla se activa muchas veces por los rebotes que hace al quitar en condensador.

Yo creo que se activa la interrupción al cerrar la puerta porque hay algún rebote, pero porque no ocurre lo mismo si quito en condensador???

Y como solucionarlo??, no quiero que se me active la interrupción al cerrar la puerta

Gracias a todos por vuestro tiempo!!

Cuando dices que el tema de los rebotes lo tienes solucionado y funciona genial, no es cierto.
No te funciona, y como yo no me estoy yendo de tema, por mi sigue solo, genio.

Hi,
En el hilo 8 te aconseje que pusieras el condensador en paralelo a los contactos del switche. Para que le pones un condesador a la resistencia que piensas que vas a protejer. La resistencia no produce ruidos pero si el contacto del switche. Otra cosa que es posiblemente que estes usando un switche de mala calidad.

Gracias Tauro, estoy esperando a que me llegen por correo condensadores para probar a ponerlo en paralelo con el interruptor.

De todas formas leí en algún lado que esa solución no era muy buena porque podías dañar a la larga en interruptor, pero bueno, lo probaré.

En respuesta a tu pregunta de porque pongo un condensador a la resistencia, es porque: la resistencia es un amor resistencia pull down y en condensador está puesto para eliminar los rebotes, es un circuito que he visto en varias páginas para eliminar los rebotes junto con resistencias pull down.

Visto lo visto funciona en parte, ya que al abrir la puerta siempre me cuenta de 1 en 1 pero al cerrarla tengo el problema que también cuenta y no debería hacerlo ya que la interrupción está en RISER y es aquí mi duda, ¿veis que este mal planteado el circuito? ¿ como lo solucionaríais?

Gracias

He puesto un condensador de 6uf (que es lo que tenia por casa) en paralelo al interruptor, y por supuesto he quitado mi circuito RC y así consigo que al abrir la puerta cuente de 2 en 2 y al cerrarla cuenta de 1000 en 1000 aprox.

Lo que quiero es intentar que no cuente al cerrar la puerta.

Hola,

  1. Con las interrupciones no se deben utilizar las instrucciones "serial"
  2. Activa un temporizador en la ISR y no hagas nada en las (eventuales) sucesivas interrupciones hasta que no transcurra ese tiempo. Una variable de estado "abierto" ayudaría.
    Saludos.

(Espero no haberme desviado "del tema principal")

Hi,
El problema es que normalmente cuando usas switches como sensor se usan proveyendo el ground. Ya has probado la mayorias de las sugerencias y no te trabaja, Ya yo te mencione que posiblemante es el switche que no es el indicado para tu aplicacion. Yo uso switches para cambiar los setting del programa pero los usos provenyendo el ground y nunca he esperimentado el problema que tu tienes.

Lo que te aconsejo ya que se usan para alarmas de casas para las ventanas y puertas es el uso de reed switch. Adjunto un link que te indica de lo que estoy hablando. Estos son los que usan en alarmas. Puedes buscar haciendo un google pues los hay de diferentes precios. El que demuestro es solamente paraq que tengas una idea de lo que estoy sugeriendo.

Y que crees tauro que puede ser el sensor magnético que esta usando, justamente un Reed switch de otro modo no será magnético.