Interrupcion - Evitar rebote [SOLUCIONADO]

Hola Amigos.

Tengo conectado a arduino mega una boya com esta:

Lo tengo conectado a un Arduino mega en el pin 19 y con una resistencia de 4700 ohmios.He creado la interrupcion para que se ejecute cuando pasa de LOW a HIGH. Es decir en modo RISING. Pero me ejecuta la funcion tres veces. Me da la impresion que es algun especie de rebote.

He pensado que en vez de hacer el efecto antirebote por software lo haria por hardware. He encontrado una pagina para calcular de manera sencilla el condensador. Debounce calaculator – Protological. Pero me entra la duda de que condensador necesito. descarto el electrolitico por que es polaridado.

Que deberia poner uno ceramico?

PD: si conoceis alguna web que explique el tema de como calcular esto manualmente, en castellano, genial!!

Gracias una vez mas.

Os pongo el codigo de ejemplo:

// Interrupcion Nivel Critico de agua tanque de riego.

const int pinBoyaDeposito = 19; // pin interrupcion
volatile int bombasError = LOW; // Interrupcion - Boya nivel bajo de agua. - LOW -> tanque lleno.


void setup() {

  Serial.begin(9600);// Iniciamos comunicacion serial

  //----------Interrupciones ------------------

  pinMode(pinBoyaDeposito, INPUT);
  attachInterrupt(digitalPinToInterrupt(pinBoyaDeposito), depositoVacio, RISING); // de LOW a HIGH se ejecuta.Tanque de agua sin agua
}

void loop() {
  // put your main code here, to run repeatedly:

}

void depositoVacio() {
  bombasError = !bombasError;

  if (bombasError == LOW) {

    Serial.println(F("Nivel correcto"));

  } else {
    Serial.println(F("Nivel bajo"));

  }
}

Primero, no necesitas una interrupción para detectar el cambio de una boya.
Hay programas de debounce en arduino, simplemente usa Bounce2 Library para ello.

davisss:
Pero me ejecuta la funcion tres veces. Me da la impresion que es algun especie de rebote.

Eso, y que quizá una boya no se mantenga estable mientras el nivel del líquido se mantenga cerca del umbral (causado por las "olas" que se producen por cualquier perturbación en el líquido).

davisss:
descarto el electrolitico por que es polaridado

¿Y eso por qué?. Mientras no se le exceda el voltaje máximo y el pin del lado de la franja blanca este conectado a tierra; no habrá explosión.

davisss:
Que deberia poner uno ceramico?

¿Para qué? ¿Qué tiene de malo el electrolítico?

Donde me dices "cerámico", me imagino a los del rango de nanofaradios.
A menos que el rebote sea de muy muy alta frecuencia (por el rango de los MHz), de lo contrario dudo que los cerámicos tengan efecto filtrador.

surbyte:

Me interesa la interrupcion para que pare el programa que esta ejecutando de inmediato y pare las bombas si estan en funcionamiento (). La libreria que dices es genial y muy sencilla, la uso en la botonera.

Lucario448:

Puedes tener razón con el movimiento del agua dentro del tanque. Gracias por quitarme la duda del condensador a utilizar. Habia descartado los electroliticos, porque en todos lo esquemas no ponen la polaridad.

La idea es que cuando llegue a un nivel el agua, en ese mismo momento pare las bombas. Por eso elegi la interrupcion pero se contradice un poco al poner un antirebote. POr eso imagino que surbyte me sugiere que lea el pin al que tengo conectado la boya.

¿Pensais que es una tonteria utilizar la interrupcion?

gracias nuevamente!!

davisss:
¿Pensais que es una tonteria utilizar la interrupcion?

Eso depende del tamaño y complejidad del programa principal, que sin este produzca una reacción retrasada o simplemente nunca ocurra cuando debería.
Si el programa lo único que hace manipular una bomba basado en la boya… lamento decirte que sí lo es.

Si prestas atención, el loop está vacío; lo que me hace pensar que el programa es tan simple como para requerir interrupciones.

No hay programa por mas complejo que digas que requiera una interrupción para parar una bomba!!

Solo que si haces un programa y para accionar la bomba le pones un
delay(10*3600*1000); o sea 10 hs.. se que es exagerado pero he visto cosas asi, entonces hacerse cargo de lo mal que lo has programado.

Si usas millis() ni cuenta te das.

Pero millis() requiere de prestar atención, por eso muchos le rehuyen.

Esto hace lo mismo sin interrupciones

const int pinBoyaDeposito = 19; // pin interrupcion
volatile int bombasError = LOW; // Interrupcion - Boya nivel bajo de agua. - LOW -> tanque lleno.


void setup() {

	Serial.begin(9600);// Iniciamos comunicacion serial

	//----------Interrupciones ------------------

	pinMode(pinBoyaDeposito, INPUT);
	
}

void loop() {
  // put your main code here, to run repeatedly:
  depositoVacio();
}

void depositoVacio() {
  
  bombasError = digitalRead(pinBoyaDeposito);
  if (bombasError == LOW) {
     Serial.println(F("Nivel correcto"));
  } else {
     Serial.println(F("Nivel bajo"));
  }
}

Lucario448:

El codigo que he puesto solo era el ejemplo simple del problema. El programa controla temperatura, apertura de ventanas, log en un sd, lluvia y viento. y posibilidad de conectarse con el movil para ver el estado del sistema(bueno esto es una futura ampliacion). Aunque no es complejo, complejo.

Pero viendo que surbyte dice, que aunque el programa sea complejo recomienda evitar interrupciones, voy a probar que tal funciona. Que al final los maestros sois vosotros ;).

Muchas gracias por vuestra ayuda!!!, se agradece mucho.

Solo decimos AMBOS que no hace falta una interrupción para detectar el accionamiento o no de un sensor tipo boya, o un pulsador que para el caso son lo mismo.
No olvides que el boton puede rebotar... asi que ojo con eso. Yo simplemente lo activo pero eso puede hacer que la bomba se prenda/apague seguido y eso la quemará.

No te apresures a decir que las cosas estan listas porque luego me vas a colgar de algun sitio.

Tu debes asegurarte que los cambios son lo que deben ser.
Asi que usa bounce como te sugerí y ponle un tiempo de 100mseg.

Si no sabes como, solo estudia los ejemplos. Es muy facil.

Recuerda, si luego tu código crece y usas delay, esto no va a funcionar.

No uses delay.. te lo advertimos!!

Voy a probar con bounce. Probare como se comporta y simulare olas en el tanque ;). Seria gracioso que, por evitar que las bombas trabajen en vacio para que no se quemen, las queme encendiendolas y apagandolas por la boya.

Gracias por la ayuda.

Mucha ola no tienes en un deposito, salvo cuando se llena rápidamente o sea con mucho caudal.
Solo prueba esa situación.

davisss:
Probare como se comporta y simulare olas en el tanque :wink:

Solo si está cerca del nivel que se activa/desactiva. Cuando esté totalmente sumergida o el líquido este lejos de llegar a tocar la boya, las olas no suponen un problema.

Bueno yo esperaba que siguieras con tu idea/proyecto aqui antes de abrir otro hilo, porque hablabas de un código complejo y esto no lo era.

No necesitas una interrupción para nada. programas mucho más complejos se ejecutan en 1 milisegundo.

La unica dificultad que puede tener la aplicacion es que haya un cierto nivel en que se active y se desactive erráticamente.

Pero aun así es facil que no suceda. El interruptor tiene una histéresis ( casi seguro positiva, mayor que cero), es decir se activa a un nivel más alto que el nivel al que se desactiva. Piensa en un flotador dell depósito de un inodoro ( bueno no es un buen ejemplo porque la valvula que cierra yabre es más bien analogica, deja pasar más o menos agua). Piensa en un controlador de temperatura todo nada, un termostato. Si lo regulas a 21 grados, se activa a 20.5 y se desactiva a 21.5. Si no fuese así, justo a 21 grados empezaría a conectarse y desconectarse como loco.

Con la histeresis del interruptor tendrás un controlador todo-nada, o controlador de histeresis. Si la histeresis es suficientemente grande ( y positiva como es de esperar), directamente te valdrá. Si no es suficiente y se conecta y desconecta muy a menudo cerca del punto de consigna, puedes intentar cofirmar la señal tras un tiempo y entonces desencadenar lo que quiera que sea.

En cuanto al rebote del pulsador te dara igual casi seguro. Si vas a activar un relé y lo activas y desactivas 3 veces en 60 milisegundos, la ley de lenz hará probablemente que el relé tarde un poco más de lo normal en conectarse ( 80 ms en vez de 40) y un poco más en desconectarse.
A lo mejor tienes algún rebote en el relé pero sería raro. El tiempo de conexión es del orden del tiempo de rebote de un pulsador.

Si vas a activar un transistor, este sí seguira fielmente las tres ordenes de conexion y desconexion, pero la carga alimentada actuara como un filtro paso bajo, y sentira las tres conexiones del transistor como una sola a efectos practicos ( casi seguro), si es un motor, sin ningún genero de dudas. Es una bobina, o sea un pasa bajos.

Por curiosidad, lo malo de un condensador electrolitico es la vida util. Evitalos siempre que puedas. Son un mal necesario y aquí no es necesario.
Si quisieras filtrar rebotes por hardware, deberías usar uno cerámico, y como tienen muy poca capacidad y no filtran bien, le pondrías una resistencia en serie ( incluso al electrolitico se la tendrías que poner). Tendrías que poner la más alta posible, para que te valga un condensador pequeño, pero si activas los pull-ups de entrada ( como es lógico hacer), debería ser significativamente más pequeña que la resistencia de pull-up, porque te va a formar un divisor de tension con el pull-up y para garantizar que bajas la tensión lo suficiente como para leer un cero lógico, no deberías subir de 10k (quizá un poco + o un poco -), pero te tienes que asegurar el cero lógico siempre, en cualquier situación así que alejate del límite y da un margen de seguridad. Luego le pones el ceramico más grande que tengas 100 nF o 220 nF y si no es suficiente le pones más en paralelo, o uno de poliester de 2 micros.

Pero vamos, que no te compliques la vida, hazlo sin condensador, sin filtrar rebotes y si tienes algún problema ( no lo vas a tener) filtralos por software, sin delay, como te han dicho. Para este programa si no es muy complejo, valdría un delay, lo más bajo posible si 60 ms vale, es mejor que 100. Pero tienes que aprender a programar sin delay porque las cosas se complican en seguida en cuanto añades un poco de funcionalidad a algo. Puedes usar delay para probar una idea en un momento, pero luego lo mejor es quitarlo, y si lo usas como algo definitivo, con mucho cuidado y muy pocos milisegundos, y por un motivo bien justificado, por ejemplo, que te cuesta mucho hacerlo de otra manera, y que el sacrificio que supone al funcionamiento es practicamente nulo.

Hazlo con un digitalRead sin interrupciones. Te va a ir perfecto.

Hola compañeros!!

Primero agradecer la ayuda, los consejos, muchas gracias!!

Al final actuo como si fuera un pulsador y espero unos segundos.. sino cambia el valor activo/desconecto las bombas. Con ayuda de la libreria BOUNCE2 y sin ningun condesador. Me funciona muy bien. Esa parte la doy por acabada.

Gracias!

PD: Ahora si [SOLUCIONADO] en el titulo ;).