Autor Tema: lógica para que una interrupción pare en la totalidad un código de control  (Leído 3147 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado CompSystems

  • PIC18
  • ****
  • Mensajes: 488
    • Home Page
Hola, como sabemos muchas maquinas tienen un botón de parada, para “apagar” sistemas que puedan causar accidentes o en un proceso afectar negativamente la producción.

Si tengo un botón que realice una parada de emergencia, por ejemplo, que envíe un flanco de bajada a un pin de un microcontroaldor y este lo detecte como una interrupción, entonces ¿cuál es la lógica para que el algoritmo de control, deje de seguir ejecutándose o mejor se detenga por completo?

Esto es lo que hecho en el IDE de Arduino, al activarse la interrupción, fijo un indicador global de control a verdadero en la ISR, y dentro de las funciones de control y función de ciclo continuo (LOOP)  pregunto si esa bandera o indicador no se ha fijado y si es así, el código se ejecuta normalmente, en caso de que se halla pulsado el botón muestra un mensaje, y como nunca cambio de estado la bandera de control, solo reiniciar el sistema, hará que vuelva al curso normal de ejecución

Código: C++
  1. #define INTERRUPT_4 02
  2. #define EMERGENCY_STOP_INTPIN INTERRUPT_4
  3.  
  4. volatile bool emergencyStop_intrFlag  = false;
  5.  
  6.  
  7. attachInterrupt( digitalPinToInterrupt( EMERGENCY_STOP_INTPIN  ), emergencyStop_ISR() , high_to_low_trig );
  8.  
  9. // RUTINA DE SERVICIO DE INTERRUPCIÓN
  10. void emergencyStop_ISR( ) {
  11.   emergencyStop_intrFlag = true;
  12. }
  13.  
  14. // BLOQUE O CICLO CONTINUO
  15. void loop( ) {
  16.         if (emergencyStop_intrFlag == false) {
  17.          funcion1();  // ….  Lineas a ejecutar
  18.                // …
  19.                // …
  20.  
  21.         } else {
  22.                Serial.println( "PARADA DE EMERGENCIA ACTIVA, REINICIE SISTEMA:" );
  23.       }
  24. }// end loop
  25.  
  26. void funcion1(){
  27.  
  28. if (emergencyStop_intrFlag == false) {
  29.          // ….  Codigo a ejecutar
  30.                // …
  31.                // …
  32.  
  33.         } else {
  34.                Serial.println( "PARADA DE EMERGENCIA ACTIVA, REINICIE SISTEMA:" );
  35. }
  36. }

Lo anterior funciona bien, solo si el botón de parada se activa en el momento de cada inicio de cada función , si  no es así algunas sentencias son ejecutadas que es el caso general, ¿que hacer para evitar esto? o como lo hacen con PICs o similares
« Última modificación: 21 de Agosto de 2016, 17:18:22 por CompSystems »
Desde Colombia

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:lógica para que una interrupción pare en la totalidad un código de control
« Respuesta #1 en: 21 de Agosto de 2016, 17:09:41 »
Cuando decis detener, me imagino que estas hablando de que comienze de nuevo todo un bucle SIN pasar por las demas instrucciones y en cualquier lugar donde ocurra.

Detener el flujo de lo que estas haciendo a no ser que cada sentencia este bloqueda por este bit no va a ser posible facilmente. Hay muchas cosas que quedarian cargadas, entre ellas el stack/registros, etc.

Si quisiera realmente realizar eso ( lo que escribi al comienzo) se me ocurre solo una cosa y es casi involucrarse a nivel maquina.

Reinicializar el stack, esto se podria realizar si es que es posible saber el valor del puntero de stack al comienzo de la funcion (es decir acceder a los 32 registros y hacer una copia de los mismos), supongamos al final del setup(), Ahi guardar cual es el puntero al stack. Tambien fijar una etiqueta para realizar un salto incondicional (un goto)

De esa forma la rutina de interrupcion, al ocurrir, retornaria el stack a su valor del final del setup, procede a activar las interrupciones ( ya que al entrar se deshabilitan ), limpiar flags, activar el bit y finalmente realizar un salto con un goto, para que no afecte al stack. Igual es muy rebuscado Y seria casi lo mismo que un reset, nomas que mantendrias todos los valores static o globales ( a no ser que lo reasignes en tu codigo ). Y tambien no deberias configurar los modulos ya que estan realizados, lo que si un reset podria afectar a las salidas, ya que uno setea las salidas a un nivel "default" en el setup, y estarian cambiando.

Tal ves generar un Reset sea mas sencillo. De todas formas el boton de parada deberia ser un zeta, es decir un boton que se queda presionado al hacerlo, y para liberarlo suele necesitarse un giro del mismo.

---------------------------

Ahora si queres que pare hasta que se resuelva el problema, que quede en un while (dentro de la interrupcion) hasta que las condiciones sean las apropiadas: vuelva el estado del pin a un valor alto.

---------------------------

La otra es protejer aquellas instrucciones donde se cambia algun puerto o que se maneje la parte de "potencia" que seria la que no deberia moverse ante una emergencia, con algun if, para que cuando ocurra salte al final de la funcion (con un goto o break o lo que sea ).
Es decir solo se ejecutarian las instrucciones que no harian daño, mientras que los puertos quedan como estan. Lo que si debes esperar que algo asi ocurra en tu programa, y que hay instrucciones que no se ejecutarian.

La otra es conservarlas dentro de los if a las instrucciones que modifican los puertos, para que no se ejecuten, asi termina todo el bucle sin realizar ningun daño alguno. Finalizado el bucle imagino que estara protegido ya por el bit ese.

---------------------------

Si alguno tiene mas ideas, las acepto :P, es lo unico que se me ocurrio de como realizarlo.
« Última modificación: 21 de Agosto de 2016, 17:14:26 por KILLERJC »

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:lógica para que una interrupción pare en la totalidad un código de control
« Respuesta #2 en: 22 de Agosto de 2016, 08:16:54 »
Tienes que comprobar la condición antes de ejecutar cada orden.
Otra opción es no hacer nada. La parada de emergencia debe cortar alimentación y frenar todos los motores y actuadores. Como nada se mueve, el ciclo del programa no puede continuar.
Tu pregunta parece más teórica que práctica. Lo primero que necesitas es un programa que mueva algo y, a partir de ahí, añadir el manejo de paradas (de emergencia u otras).
Un saludo.

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino