Documentos de Académico
Documentos de Profesional
Documentos de Cultura
5. Programación de robots
Un robot cuenta como característica fundamental, que lo define e individualiza respecto de otras
máquinas, el hecho de ser multifuncional. Es decir, no se fabrica para un uso específico – salvo
contadas aplicaciones – sino que podemos adaptar su utilización según el proceso en que lo
apliquemos.
Esta multifuncionalidad se logra debido a que en producción funcionará según un programa
elaborado a fines de cumplir los objetivos del proceso.
El programa no será rígido, sino que podrá ser modificado, corregido, actualizado y
eventualmente reemplazado si cambia el proceso al que está destinado. De haber condiciones
desfavorables a un cambio de funcionalidad en un robot industrial, éstas estarán centradas en
cuestiones relacionadas con montos de inversión, complicaciones de logística o espacios disponibles
para una nueva utilización. No habrá cambios estructurales requeridos en el robot propiamente
dicho, a excepción lógica de diseñar y construir las nuevas herramientas requeridas.
En este capítulo conoceremos los principios empleados en la programación de un robot
industrial. Lo haremos estudiando el lenguaje de programación RAPID empleado en los robots de la
firma ABB. Salvo aspectos particulares en lo que hace a la sintaxis y formato de manejo de la
información, las herramientas, estructuras, componentes y criterios aprendidos nos servirán a futuro
para encarar el estudio de cualquier otro lenguaje de programación.
dado que “pisar” o “sobrescribir” un valor 5 con otro valor 5 no produce cambios. Caso contrario, el
valor guardado se actualizará al nuevo asignado.
En el ejemplo que usa el dato o variable cuenta, la instrucción resuelve primero lo que está a la
derecha del símbolo de asignación (:=), o sea, lee lo que guarda cuenta y le suma 1. Luego, toma el
resultado y lo asigna a cuenta sobrescribiendo el valor que guardaba, actualizándolo. Esta instrucción
en la que vemos la misma variable en ambos lados de la asignación no debe asustarnos. Es lo que en
programación se llama “contador” dado que, si pasamos reiteradamente por esta instrucción, en cada
pasada habrá incrementado su valor en 1, “contando” las veces que la hemos ejecutado.
Continuemos. Las instrucciones en un programa estarán agrupadas en conjuntos denominados
rutinas. En un programa habrá como mínimo una rutina, pudiendo haber más de una. Esta rutina que
como mínimo debe existir deberá denominarse main() – los paréntesis a continuación del nombre
forman parte de la estructura.
Existen tres tipos de rutinas: procedimientos, funciones y rutinas TRAP.
- Procedimientos: Se utilizan como subprogramas.
- Funciones: Devuelven un valor de un tipo concreto y se utilizan como
argumento de una instrucción.
- Rutinas TRAP: Se utilizan para dar respuesta a una interrupción. Las rutinas
TRAP pueden asociarse con una interrupción, ejecutándose por
ejemplo si se activa una entrada.
La información se almacena en espacios en memoria administrados por el controlador a tal fin.
Estos espacios serán los datos, por ejemplo, los datos de las herramientas (que contienen información
sobre las herramientas, como su TCP y su peso) y datos numéricos (que pueden usarse por ejemplo
para contar el número de piezas que deben procesarse). Los datos se agrupan en distintos tipos de
datos que describen los distintos tipos de información, como herramientas, posiciones y cargas.
Dado que es posible crear estos datos y asignarles nombres arbitrarios, no existe ningún límite
en el número de datos (excepto el límite impuesto por la memoria disponible). Estos datos pueden
existir de forma global en el programa o sólo localmente dentro de una rutina.
Existen tres tipos de datos según cómo guardan la información: constantes, variables y
persistentes.
- Constantes: Datos que guardan un valor fijo asignado al inicio del programa
o previo a su utilización. No puede variar durante la ejecución.
- Variables: Datos en los que la asignación de valores nuevos puede
realizarse durante la ejecución del programa.
- Persistentes: Dato en el que el valor de inicialización se actualiza con cada
inicio del programa, tomando el último guardado.
Finalmente, la rutina o rutinas que constituyen el programa se agrupan en conjuntos
denominados módulos. Un módulo puede ser de programa o de sistema, habiendo un único módulo
de sistema por programa, mientras que módulos de programa habrá como mínimo uno, pero puede
haber más. Este módulo mínimo que como mínimo debemos tener en el programa será el que aloje
a la rutina denominada main().
5.3.2. Comentarios
Se emplean en el código de cualquier programa para que ayuden al programador a explicar
criterios de utilización de partes del programa, descripción de datos o instrucciones y cualquier
narración que desee hacer en el código.
Tiene como característica que admite cualquier tipo de caracteres, dado que el controlador
cuando lee este texto lo pasa por alto sin interpretarlo como una instrucción. Para ser reconocido, en
cualquier lenguaje un comentario debe iniciarse por un carácter específico que identifica el inicio del
comentario.
En el lenguaje RAPID los comentarios deben iniciarse con el carácter: !
Los comentarios sirven para facilitar la comprensión del programa. Por lo tanto, se debe saber
que no afectan de ningún modo el funcionamiento del programa.
Ejemplo
5.3.3. Encabezado
Dependiendo de la estructura de archivos con la que elaboremos un programa, en ciertos casos
el código inicia con un encabezado que sirve para proporcionar cierta información específica.
No interviene en el funcionamiento del programa. En el lenguaje RAPID, en función de la versión
de lenguaje que se emplee, los programas iniciarán siempre con el siguiente encabezado:
%%%
VERSION:1 (Versión M94 ó M94A del programa)
LANGUAGE:ENGLISH (o bien otro idioma: alemán o francés)
%%%
En los programas que elaboremos podremos ingresar indistintamente o no este encabezado
cuando empleemos el software de simulación para realizar las pruebas de funcionamiento.
5.3.4. Módulos
Como hemos visto, una aplicación estará dividida en módulos. Habrá módulos de programa y
módulos de sistema.
5.3.4.1. Módulos de programa
Un módulo de programa estará formado por diferentes datos y rutinas.
En todo programa habrá como mínimo un módulo de programa, y será éste el que contendrá el
procedimiento de inicio o entrada del programa llamado main.
Ejecutar un programa significa, realmente, ejecutar este procedimiento main o principal. El
programa podrá incluir varios módulos de programa, pero sólo uno de ellos contiene un
procedimiento principal.
Mientras que las pequeñas instalaciones suelen estar contenidas en un único módulo de
programa, las instalaciones más complejas pueden tener un módulo principal que hace referencia a
rutinas y/o datos contenidos en uno o varios otros módulos. Esta organización de un programa en
distintos módulos permite al programador dividir el trabajo agrupando tareas por funcionalidad,
resultando partes más pequeñas de código que serán más sencillas de escribir, leer y eventualmente
corregir.
5.3.4.2. Módulos de sistema
Un módulo de sistema contendrá información de uso general, por ejemplo: la declaración de
datos de sistema (como ser las entradas y salidas que se definen en etapa de parametrización y son
comunes a todos los programas), la definición de herramientas, la definición de los sistemas de
coordenadas definidos por el usuario, etc.
Cuando se guarda un programa no se incluyen estos módulos, los cuales son accesibles sólo
desde la unidad de programación o bien empleando herramientas especiales de software.
Una declaración de módulo especifica el nombre y los atributos de este módulo. Dichos atributos
sólo podrán añadirse de forma OFF-LINE, cuando estamos escribiendo código mediante una
herramienta de software específica, y no mediante la unidad de programación.
Los atributos nos permiten dar ciertas características a los módulos, como permitir que sea de
sólo lectura, que pueda o no ser modificable, permitir o no su ejecución paso a paso, que pueda o no
ser visualizado en la unidad de programación, etc.
No utilizaremos atributos en los módulos como objetivo de este curso.
Como en toda estructura, de cualquier lenguaje de programación, debemos abrirla y cerrarla. Lo
haremos con palabras clave según el lenguaje. En RAPID, abrimos un módulo con la palabra
“MODULE” y lo cerramos con “ENDMODULE”. Veamos un ejemplo:
MODULE nombre_módulo
! ___
! ___
! ___
ENDMODULE
Al igual que cualquier otro componente en un programa, y como es regla básica en cualquier
lenguaje de programación, un módulo no podrá tener el mismo nombre que otro módulo o que una
rutina global o que un dato.
5.3.5. Rutinas
Las rutinas agrupan las instrucciones que al ejecutarse harán que el robot realice su trabajo. Es
la verdadera mínima expresión de un programa, siendo que toda instrucción – con excepción de la
declaración de datos – debe estar contenida en una rutina.
5.3.5.1. Alcance y declaración de las rutinas
El alcance de una rutina indica el área dentro del programa en que la rutina está accesible.
Hemos dicho que todo programa inicia su ejecución a partir de la rutina main. Luego, es en la
rutina main donde estarán las instrucciones que permitan “llamar” a otras rutinas, pasando la
ejecución a la primera instrucción de la rutina “llamada”. En función del alcance, una rutina podrá o
no ser llamada desde un sitio, por poder o no verse desde allí.
En forma predeterminada toda rutina es global, llamándose así a una rutina que puede ser vista
desde cualquier punto del programa. Para declararla lo haremos con palabras clave como se muestra
en el siguiente ejemplo:
PROC Nombre_Rutina(…)
….
….
….
ENDPROC
Una rutina será en cambio local, cuando podremos verla para llamarla sólo desde otra rutina que
comparta módulo con aquella. La declaramos así:
LOCAL PROC Nombre_Rutina(…)
….
….
….
ENDPROC
Una rutina no deberá tener el mismo nombre que otra rutina o datos dentro del mismo módulo.
Una rutina global no deberá tener el mismo nombre que otra rutina global o que datos globales de
otro módulo.
Reiterando conceptos para fijar conceptos, independientemente de la consideración anterior, en
programación es norma no repetir nombres, independientemente de que un elemento pueda o no
ser visto desde un sitio con nombre compartido.
PROC Trabajo()
…
Posición:=Altura(3);
ENDPROC
En la rutina “Trabajo” empleamos el valor que devuelve la función “Altura” cuando la llamamos
con el parámetro en valor 3. Luego, la variable “Lado” tomará este valor, lo procesará y la función
devolverá un resultado a través de la instrucción RETURN que será empleado en la instrucción donde
se llamó a la función.
Veremos más adelante otros ejemplos de aplicación.
Las rutinas del tipo TRAP se explican con detalle en el “Anexo A”, por no ser objetivo del presente
curso.
Como valores complejos o registros tendremos todo el resto de datos posibles, considerándose
así porque se componen a su vez de otros datos, siendo la mínima expresión un tipo de dato simple.
Veamos los siguientes ejemplos:
Asignación de un dato numérico Num:
A:=2;
Asignación de un dato String:
miTexto:=”Máquina parada por fallo”;
Asignación de un dato de posición RobTarget:
P0:=[[Posicion1, Orientacion1, Configuracion1, EjesExt1];
P0:=[[0,210,600],[0,0.259,0.5,0.766],[0, 0, 1, 0],[9E+9, 9E+9, 9E+9, 9E+9, 9E+9, 9E+9]];
Asignación de un dato de configuración ConfData:
Configuracion1:=[0, 0, 1, 0];
Asignación de un dato de ejes externos ExtJoint:
EjesExt1:=[9E+9, 9E+9, 9E+9, 9E+9, 9E+9, 9E+9];
Asignación de un dato de posición JointTarget:
Punto1:=[[10,0,25,80,30,120), EjesExt1]];
En los ejemplos anteriores, recordando el dato de posición RobTarget, vemos que el dato está
formado a su vez por los datos Pos, Orient, ConfData, ExtJoint.
Luego, el dato de configuración ConfData a su vez está formado por cuatro datos numéricos
simples, así como el dato tipo Pos está formado por tres datos numéricos simples.
También podemos ver que en la asignación de valores a un dato complejo como el JointTarget,
podemos trabajar directamente con los valores numéricos simples o con un dato del tipo ExtJoint
mientras sea del tipo adecuado y guarde la información adecuada.
5.3.6.2. Duración de un valor dentro de un dato
En función la posibilidad de actualizar o no el valor de un dato, podremos definir:
- Variables
- Constantes
- Persistentes
Datos variables
Son datos que pueden tener o no valor inicial, pero pueden ser actualizados en cualquier
parte del programa. En caso de reiniciarse el programa, vuelven a tomar el valor inicial que
indicamos en su declaración.
Ejemplos: VAR num x; !Dato numérico que se iniciará con cero.
VAR num x:=1; !Dato numérico con valor inicial 1.
VAR string Texto:=”Fallo”; !Dato String con valor inicial “Fallo”.
VAR num x{2, 3}; !Matriz de datos numérico, de 2 filas por 3 columnas,
estando los 6 valores de la tabla virtual con valor inicial cero.
1 2 3 4 5 6
Tendremos:
1 1 4 6 0 2.4 23 - Matriz{1,1} guarda el valor 1
2 0 5 7 98 3,88 34,7
- Matriz{1,5} guarda el valor 2,4
3 0 0 123 22 6 88
- Matriz {3,6} guarda el valor 88
De igual manera podemos tener una matriz de 3 dimensiones, que pensaremos como una
tabla tridimensional, es decir, tiene filas, columnas y capas. Es especialmente útil para guardar
datos de posición que representan las ubicaciones en una pila de pallets.
Datos constantes
Son datos que requieren un valor inicial determinado al momento de su declaración, y
luego se mantiene invariable a lo largo del programa. Es decir, no se le podrá asignar ningún
valor nuevo.
Se emplea para guardar valores que se utilizarán reiteradas veces en el programa, sin
necesidad de ser actualizados.
Dato Local
Puede ser un dato de rutina, en cuyo caso no es necesaria ninguna aclaración porque
indefectiblemente será un dato local, o un dato de programa en cuyo caso debe aclararse la
situación dado que será por defecto un dato global.
Ejemplo de declaración de un dato de rutina: VAR num MiVariable;
Ejemplo de declaración de un dato de programa: LOCAL VAR num MiVariable;
Por lo general se acostumbra a declarar todos los datos de alcance global. A nivel de módulo
declararemos los datos generales, de uso en todas las rutinas del programa, que convengan ser
declaradas al inicio del programa por prolijidad y leerse en modo resumen.
Los datos a nivel de rutina serán declarados de esta manera cuando se trate de datos específicos
de la rutina, menores para figurar en el inicio del programa, y de poco valor relativo dentro del
programa.
Sirve para esperar durante un tiempo específico, indicado en la instrucción en segundos. Cuando
se ejecuta esta instrucción, el controlador aguarda el tiempo especificado hasta leer y ejecutar la
siguiente instrucción.
Durante el tiempo de espera la manipulación de las interrupciones y otras funciones similares
siguen estando activas.
Código:
%%%
VERSION:1
LANGUAGE:ENGLISH
%%%
MODULE PROGRAMA
CONST extjoint ejes:=[9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]; !Declaramos el dato ejes
CONST jointtarget P0:=[[0,0,0,0,0,0], ejes]; !Declaramos la posición de calibración
CONST jointtarget P1:=[[10,10,25,0,30,0], ejes]; !Posición de inicio de trayectorias
VAR robtarget A0; !Posición de inicio como RobTarget
PROC main()
MoveAbsJ P0, v1000, fine, tool0; !Movemos hasta calibración
MoveAbsJ P1, v1000, fine, tool0; !Movemos hasta inicio de trayectorias
A0:=CRobT(); !Guardamos posición como RobTarget
Resumiendo, el robot suele tener una o más tarjetas de E/S. Cada una de las tarjetas tiene varios
canales digitales y/o analógicos que deberán ser conectados a señales lógicas antes de poder ser
utilizados. Esta operación se lleva a cabo en los parámetros del sistema y normalmente ya se ha
realizado utilizando nombres estándar antes de la entrega del sistema. Los nombres lógicos deberán
utilizarse siempre durante la programación.
Ejemplo 1:
IF E01=1 THEN
Set S01;
Set S02;
ENDIF
Evaluamos la condición E01=1. Si es verdadera, se activarán las salidas S01 y la S02. Caso
contrario, la estructura no realiza acción alguna.
Ejemplo 2:
IF E01=1 THEN
Set S01;
Set S02;
ELSE
Reset S03;
A:=A+1;
ENDIF
Ejemplo 3:
IF A=1 THEN
Set S01;
Set S02;
ELSE IF A=3 THEN
Reset S03;
D:=D+1;
ELSE IF A=4 THEN
B:=3;
ELSE
B:=0;
D:=0;
ENDIF
Cada evaluación de la variable A que queremos analizar, se realiza en la rama CASE terminando
con el carácter “:”. Si ninguna de las anteriores condiciones es verdadera, entonces se ejecutarán las
instrucciones de la rama DEFAULT.
Tanto esta estructura como la anterior resuelven el problema de tomar decisiones según el valor
de una expresión o dato en particular. Pero la estructura TEST-ENDTEST proporciona mayor prolijidad
y facilidad de lectura. De todas maneras, quedará en la preferencia del programador el uso de una u
otra metodología.
Contador: El nombre del dato que contendrá el valor del contador de bucle actual. El dato es
declarado automáticamente y su nombre no podrá coincidir con ningún otro nombre de
ningún dato ya existente.
Inicial: Dato numérico que representa el valor inicial deseado del contador de bucle. (suelen ser
números enteros).
Final: Dato numérico que representa el valor final deseado del contador de bucle. (suelen ser
números enteros).
Incremento: Dato numérico que representa el salto o valor con el que el contador de bucle deberá
ser incrementado (o disminuido). Suelen ser números enteros.
Si este valor no está especificado, el valor de incremento será automáticamente 1 (o -1 si
el valor inicial es mayor que el valor final).
Ejemplo 1:
FOR i FROM 1 TO 10 DO
Rutina1;
ENDFOR
Ejemplo 2:
FOR i FROM 10 TO 2 STEP -1 DO
a{i}:=a{i-1};
ENDFOR
Los valores de una matriz se ajustan de forma creciente. a{10}:=a{9}, a{9}:=a{8}. Para lograrlo
empleamos el valor del contador como índice de la matriz.
WHILE Condición DO
…;
ENDWHILE
Condición: La condición que debe ser cumplida para que las instrucciones del bucle puedan
ejecutarse.
Ejemplo:
Se repiten las instrucciones del bucle WHILE mientras reg1 < reg2.
Las instrucciones comprendidas entre la etiqueta sig y la evaluación del valor de reg1 se
repetirán cinco veces.
+Y +Y
A B
400mm
B{2} B{5}
200mm
A{1} A{4}
+X + X B{1} B{6}
100mm 100mm
1. Contemplar como posición inicial del robot la de calibración (todos los ejes en 0º).
2. Tomar como posición A0 la que corresponde a:
a. Eje 1=10º
b. Eje 2=10º
c. Eje 3=25º
d. Eje 5=30º
Esta será la posición de inicio de las trayectorias. En la imagen, corresponde a los puntos A{1} y
B{1}. Observar que los vértices de la figura están indicados como componentes de matrices.
3. Emplear una entrada (E01) para iniciar los movimientos. El estado de inicio es E01=1.
4. En función del estado de una segunda entrada (E02), se inicia el movimiento “A” en forma
continua (si E02=0) o la trayectoria “B” en forma continua (si E02=1). En forma continua significa
en forma cíclica.
5. Ante cambio de estado de la entrada E02, cambia la trayectoria mantenida en forma cíclica.
6. Los movimientos se detienen cuando E01=0.
Consideraciones
- Se nos pide procesar los vértices de las figuras a través de matrices con datos de posición. Esto nos será
útil porque, una vez completadas las matrices, recorrerlas para obtener los movimientos será sencillo
empleando una estructura de iteración FOR-ENDFOR.
Tenemos dos posibilidades para realizar esto:
1. Declarar dos matrices de una dimensión, una para cada figura, para el cuadrado de 4 elementos y
para el hexágono de 6. Luego, emplear cada matriz según se requiera.
2. Declarar una matriz de 6 filas por 2 columnas. Emplear la primera columna para los vértices del
cuadrado, dejando dos lugares al final sin utilizar, y emplear la segunda columna con los vértices del
hexágono.
Como hemos dicho, no hay modo correcto ni incorrecto de elaborar un código mientras cumpla con los
requerido en tiempo de ejecución. Para facilitar el desarrollo del código, emplearemos dos matrices.
- Contemplaremos que el programa trabaja en modo manual. O sea, que la ejecución cíclica del programa
dependerá del código, no del controlador. Esto significa que, finalizado un ciclo, nosotros debemos
escribir el código necesario para que la ejecución vuelva a iniciarse una y otra vez, mientras esté el
programa en ejecución.
Código
%%%
VERSION:1
LANGUAGE:ENGLISH
%%%
MODULE PROGRAMA
CONST extjoint ejes:=[9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]; !Declaramos el dato ejes
CONST jointtarget P0:=[[0,0,0,0,0,0], ejes]; !Declaramos la posición de calibración
CONST jointtarget P1:=[[10,10,25,0,30,0], ejes]; !Posición de inicio de trayectorias
VAR robtarget A0; !Posición de inicio como RobTarget
VAR robtarget A{4}; !Matriz para vertices del cuadrado
VAR robtarget B{6}; !Matriz para vertices del hexagono
PROC main()
MoveAbsJ P0, v1000, fine, tool0; !Movemos hasta calibración
MoveAbsJ P1, v1000, fine, tool0; !Movemos hasta inicio de trayectorias
A0:=CRobT(); !Guardamos posición como RobTarget
A{1}:=Offs(A0,-400,0,0); !Cargamos los vertices del cuadrado
A{2}:=Offs(A0,-400,400,0); !Presten atención a cómo ordené
A{3}:=Offs(A0,0,400,0); !los puntos dentro de la matriz.
A{4}:=A0;
B{1}:=Offs(A0,-200,-100,0); !Cargamos los vertices del hexagono
B{2}:=Offs(A0,-400,0,0);
B{3}:=Offs(A0,-400,200,0);
B{4}:=Offs(A0,-200,300,0);
B{5}:=Offs(A0,0,200,0);
B{6}:=A0;
EtiquetaInicio: !Etiqueta para funcionamiento cíclico
WaitDI E01, 1; !Inicio movimientos si E01=1
IF E02=0 THEN
CUADRADO; !Ejecuto el cuadrado
ELSE
HEXAGONO; !Ejecuto el hexagono
ENDIF
GOTO EtiquetaInicio;
ENDPROC
PROC CUADRADO()
FOR k FROM 1 TO 4 DO
MoveL A{k}, v1000, fine, tool0;
ENDFOR
ENDPROC
PROC HEXAGONO()
FOR m FROM 1 TO 6 DO
MoveL B{m}, v1000, fine, tool0;
ENDFOR
ENDPROC
ENDMODULE
¿Otro método de simular el funcionamiento cíclico?
Reescribo sólo el procedimiento main() con una ligera variación:
PROC main()
MoveAbsJ P0, v1000, fine, tool0; !Movemos hasta calibración
MoveAbsJ P1, v1000, fine, tool0; !Movemos hasta inicio de trayectorias
A0:=CRobT(); !Guardamos posición como RobTarget
A{1}:=Offs(A0,-400,0,0); !Cargamos los vertices del cuadrado
A{2}:=Offs(A0,-400,400,0); !Presten atención a cómo ordené
A{3}:=Offs(A0,0,400,0); !los puntos dentro de la matriz.
A{4}:=A0;
B{1}:=Offs(A0,-200,-100,0); !Cargamos los vertices del hexagono
B{2}:=Offs(A0,-400,0,0);
B{3}:=Offs(A0,-400,200,0);
B{4}:=Offs(A0,-200,300,0);
B{5}:=Offs(A0,0,200,0);
B{6}:=A0;
WHILE E01=1 DO
IF E02=0 THEN
CUADRADO; !Ejecuto el cuadrado
ELSE
HEXAGONO; !Ejecuto el hexagono
ENDIF
ENDWHILE
ENDPROC
Si se inhabilitan las interrupciones, todas las que se produzcan serán puestas en una cola y no
aparecerán hasta que se vuelvan a habilitar de nuevo. Observar que la cola de interrupciones puede
contener más de una interrupción en espera. Las interrupciones de una cola aparecerán siguiendo un
orden FIFO (la primera que entra es la primera que sale). Las interrupciones están siempre
inhabilitadas durante la ejecución de una rutina TRAP.
Cuando se realiza una ejecución paso a paso y cuando el programa ha sido detenido, las
interrupciones no serán procesadas. Las que se produzcan en estas instancias no serán tratadas.
El número máximo de interrupciones simultáneas es de 40 por tarea. La limitación total
determinada por la CPU de E/S es de 100 interrupciones.
Cuando se borra una interrupción desaparece también su definición. No es necesario borrar de
forma explícita una definición de interrupción, pero no se podrá definir una interrupción nueva a una
variable de interrupción hasta que se haya borrado la definición precedente.
Rutinas de tratamiento de las interrupciones (TRAP)
Las rutinas TRAP proporcionan un medio para procesar las interrupciones. Una rutina TRAP podrá
ser conectada a una interrupción particular mediante la instrucción CONNECT. En el caso en que
ocurra una interrupción, el control es inmediatamente transferido a la rutina TRAP asociada (siempre
y cuando haya una). Si ocurre una interrupción que no ha sido conectada a ninguna rutina TRAP, la
interrupción será considerada como un error fatal, es decir, que provoca inmediatamente el paro de
la ejecución del programa.
Ejemplo:
VAR intnum vacío;
Declaración de datos tipo intnum para
VAR intnum lleno;
asociarlas a las interrupciones.
PROC main()
…
CONNECT vacío WITH etrap; Conexión de rutina tratamiento de
CONNECT lleno WITH ftrap; interrupciones
ISignalDI di1, alto, vacío; Define las entradas del PLC que serán
ISignalDI di3, alto, lleno; supervisadas.
…
IDelete vacío;
IDelete lleno;
ENDPROC
llamada (la rutina de entrada de la tarea) sin encontrar ningún gestor de errores, o si se alcanza el
final de cualquier gestor de errores dentro de la cadena de llamada, se llamará al gestor de errores
del sistema. El gestor de errores del sistema sólo registrará el error y detendrá la ejecución. Dado que
una rutina TRAP sólo podrá ser llamada por el sistema (como una respuesta a una interrupción),
cualquier propagación de un error desde una rutina TRAP se realizará al gestor de errores del sistema.
La recuperación de errores no estará disponible para las instrucciones que se encuentran en el
gestor de ejecución hacia atrás. Estos tipos de errores serán siempre enviados al gestor de errores
del sistema.
Además de los errores detectados y generados por el robot, un programa puede, de forma
explícita, provocar errores mediante la instrucción RAISE. Esta utilidad podrá utilizarse para resolver
situaciones muy complejas. Podrá utilizarse, por ejemplo, para salir de posiciones profundamente
anidadas, es decir, de situaciones en que se han llamado a subrutinas dentro de subrutinas de forma
excesiva. Se podrá utilizar cualquier número de error entre 1 y 90 en una instrucción RAISE. Los
errores suscitados de forma explícita son procesados exactamente de la misma forma que los errores
provocados por el sistema.
Se debe observar que no será posible resolver o responder a errores que ocurren dentro de una
cláusula de error. Este tipo de errores son siempre enviados al gestor de errores del sistema.