serial pulsos programacion interrupciones interrupcion funciones ejemplos contador con banderas arduino embedded debouncing

pulsos - isr arduino



Varias interrupciones Arduino en el mismo pin (2)

ISR2 nunca se ejecuta porque puede haber solo una rutina de servicio de interrupción para cualquier fuente de interrupción y usted ha reemplazado ISR2 con ISR1 como rutina de sericio para esta interrupción. Si reordenó su código y adjuntó ISR1 antes de ISR2, es posible que vea la ejecución de ISR2, pero no de ISR1.

Un microcontrolador típico tiene una tabla de vector de interrupción que asocia una rutina de servicio de interrupción con cada fuente de interrupción. Solo puede haber una rutina de servicio para cada fuente de interrupción. Si asigna una nueva rutina de servicio, entonces está reemplazando la rutina de servicio anterior. No hay rutinas de servicio separadas para los bordes ascendentes y descendentes. El flanco ascendente o descendente es un parámetro de configuración para que la fuente de interrupción determine cuándo debe activarse esa interrupción. La fuente de interrupción no se puede configurar para disparar en ambos bordes simultáneamente.

Sin embargo, es posible que pueda reconfigurar la interrupción para el otro extremo después de haber recibido la interrupción para el primer flanco y haber rechazado la transición. De esta forma, su código hará ping-pong configurando hacia atrás y hacia adelante para un ISR y luego el otro.

En el siguiente código, ¿por qué ISR2 nunca se ejecuta?

const int in = 19; const int LED = 9; int flag; void setup() { pinMode(in, INPUT_PULLUP); pinMode(LED, OUTPUT); attachInterrupt(digitalPinToInterrupt(in), ISR2, RISING); attachInterrupt(digitalPinToInterrupt(in), ISR1, FALLING); } void loop() { if (flag) {delay (100); flag = false;}// debounce } void ISR1(){ digitalWrite(LED, LOW); // Turn Off the motor, since, Limit Switch was engaged flag = true; } void ISR2(){ // Limit Switch was disengaged. digitalWrite(LED, HIGH); delay(100); // Debounce, so I do not receive spurious FALLING edges from this. }

¿El Arduino no le permite conectar dos interrupciones en el mismo pin incluso si las interrupciones están programadas para diferentes eventos?

En mi configuración, el pin 19 recibe una señal de un interruptor de límite utilizado en una configuración de control de movimiento. Cuando el interruptor de límite está activado, el pin de entrada recibe la señal LOW . Por lo tanto, primero veo un borde FALLING seguido de bordes RISING LEVADURA y bordes FALLING debido al rebote mecánico. Manejo el antirrebote correctamente en este caso.

Sin embargo, imagínese que el interruptor de límite estaba en estado de enganche por un tiempo, y luego invierte el motor causando que el interruptor de límite se desenganche, esto enviará un borde RISING seguido de bordes RISING y RISING LEVADURA. Necesito ignorar estos bordes ya que nada está en peligro. El ISR2 se escribió con el propósito de capturar el primer borde de RISING cuando el interruptor de límite se desengancha, y luego lo desprende de manera que se ignoren los siguientes bordes de FALLING . Pero ahora que nunca se llama ISR2 , ¿cómo puedo manejar esta situación?

PD: Mi microcontrolador es ATMEGA 2650, es una placa Arduino Mega.


¿Por qué dices que nunca se llama? Creo que se llama, pero no lo notas porque el led no cambia su estado (porque hay rebotes).

De todos modos, NO estás depurando correctamente. Hagamos un ejemplo: golpeas el final de carrera. ISR1 llama a ISR1 , por lo que flag es verdadero. Ok, en el siguiente ciclo el motor se detendrá. Pero ... Ahora el interruptor rebota. ISR2 llama a ISR2 y la función de delay espera 100 ms antes de salir del ISR. Resultado: retrasó la función de parada del motor en 100 ms.

Le sugiero que lea mi respuesta aquí , particularmente el segundo caso. Y le sugiero que use mi código en lugar del suyo, ya que de esta manera podrá detener el motor INMEDIATAMENTE, sin rebotes ni ningún otro tipo de problema.