BRAND.03 / R-30iB PLUS + R-50iA
The teach-pendant language and the Pascal-like KAREL behind FANUC's robots.
FANUC controllers from the R-30iA through the R-30iB Plus to the newer R-50iA give you two ways to program. TP (teach pendant) is the line-numbered language most cells run on: J P[1] 100% FINE, DO[1]=ON, WAIT DI[1]=ON, written and touched up on the pendant. KAREL is a structured, Pascal-like language that you write on a PC, translate into a .pc file and load onto the controller, which needs the KAREL software option (R632). Integrators use it for what TP does badly: socket messaging, file handling, string parsing and custom logic, usually called from a TP program. Switch between the two below.
A TP program is a list of numbered lines edited on the pendant. Each line is a motion (J, L, C, A), an I/O write, a register operation, a branch (IF, JMP LBL, CALL) or a wait. Comments start with !. The editor shows [End] after the last line, and an END instruction ends the program early. Exported as an .LS file, every line also ends with ;.
J P[1] 100% FINE L P[2] 500mm/sec FINE DO[1]=ON WAIT 0.5(sec) END
A motion line is type, position, speed and termination. J speed is a percentage of maximum joint speed; L and C speed is in mm/sec. C runs an arc through a via point to an end point. FINE stops at the point. CNT0 to CNT100 blends into the next move, and the number is a degree of rounding, not a distance: the same CNT50 cuts a wider corner at 2000 mm/sec than at 200.
J P[1] 100% FINE L P[2] 500mm/sec CNT50 C P[3] P[4] 200mm/sec FINE
P[n] is a taught point that belongs to its program. PR[n] is a global position register any program can read or write while running; PR[n,j] is one element of it, j = 1 to 6 for X, Y, Z, W, P, R. A PR used with Offset turns one taught point into approach points and pallet rows.
PR[5]=LPOS-LPOS PR[5,3]=100 L P[2] 500mm/sec FINE Offset,PR[5]
UFRAME_NUM selects the user frame (the fixture) and UTOOL_NUM the tool frame (the TCP). Each P[] remembers the frame numbers it was taught with, and the robot will not run it with other numbers active, so set both at the top of every program.
UFRAME_NUM=1 UTOOL_NUM=2 L P[1] 500mm/sec FINE
DO[] and DI[] are general-purpose signals mapped to a fieldbus or I/O card. RO[] and RI[] come through the arm to the end-effector connector, where gripper valves and sensors are usually wired. GO[] and GI[] treat a group of bits as one number. UI[] and UO[] are the system signals a PLC uses to start, stop and select programs.
RO[1]=ON WAIT RI[1]=ON GO[1]=5
TP branches with labels: IF cond,JMP LBL[n] jumps when the condition holds, JMP LBL[n] always jumps. CALL runs another program and comes back. FOR/ENDFOR counts with a register, SELECT branches on a register value, and WAIT ... TIMEOUT,LBL[n] gives a wait a way out.
FOR R[1]=1 TO 3 IF DI[1]=ON,JMP LBL[10] L P[2] 500mm/sec FINE LBL[10] ENDFOR
| Instruction | Category | Purpose | Example |
|---|---|---|---|
| J | Motion | Joint move. Speed is a percentage of maximum joint speed; the TCP path is a curve you do not control. | J P[1] 100% FINE |
| L | Motion | Linear move at a TCP speed in mm/sec (cm/min, inch/min and sec are also offered). | L P[2] 500mm/sec FINE |
| C | Motion | Circular move from the current point through a via point to an end point. The pendant shows the via and end points on two lines. | C P[3] P[4] 200mm/sec CNT50 |
| A | Motion | Circular arc motion: a run of consecutive A points is joined into one smooth arc path. Not offered on older controller software. | A P[5] 100mm/sec CNT100 |
| FINE | Motion | Termination type: the robot stops at the point before the next line runs. | L P[2] 500mm/sec FINE |
| CNTn | Motion | Termination type: blend into the next move. n is 0 to 100, a degree of rounding, not a distance; the same CNT cuts a wider corner at higher speed. | L P[2] 500mm/sec CNT50 |
| PR[] | Position | Position register as the move target. PRs are global: every program on the controller sees the same PR[1]. | L PR[1] 200mm/sec FINE |
| Offset | Motion | Motion option: add a PR to this target, in the user frame. Approach points and pallet rows come from one taught point this way. | L P[1] 200mm/sec FINE Offset,PR[5] |
| Tool_Offset | Motion | Motion option: add a PR to this target in the tool frame, for example a retreat along tool Z. | L P[1] 200mm/sec FINE Tool_Offset,PR[3] |
| DO[] | I/O | General-purpose digital output, mapped to a fieldbus or I/O module in the I/O configuration. | DO[1]=ON |
| DI[] | I/O | General-purpose digital input. | IF DI[1]=ON,JMP LBL[10] |
| RO[] | I/O | Robot output: wired through the arm to the end-effector connector, typically the gripper valves. | RO[1]=ON |
| RI[] | I/O | Robot input from the end-effector connector, typically gripper open/closed sensors. | WAIT RI[1]=ON |
| GO[] | I/O | Set a group output (multiple bits as a value) | GO[1]=5 |
| GI[] | I/O | Read a group input | R[1]=GI[1] |
| AO[] | I/O | Set an analog output | AO[1]=R[2] |
| PULSE | I/O | Pulse a DO for a fixed time | DO[3]=PULSE,0.5sec |
| WAIT | Wait | Wait a fixed number of seconds | WAIT 0.5(sec) |
| WAIT (cond) | Wait | Wait until a condition becomes true | WAIT DI[1]=ON |
| WAIT TIMEOUT | Wait | Wait for a condition, jump to a label if it is not met within the time in $WAITTMOUT. | WAIT DI[1]=ON TIMEOUT,LBL[99] |
| IF | Flow | Conditional jump or call | IF R[1]>5,JMP LBL[20] |
| JMP LBL[] | Flow | Unconditional jump to a label | JMP LBL[10] |
| LBL[] | Flow | Define a label (jump target) | LBL[10] |
| CALL | Flow | Call another TP (or KAREL) program; it returns here at its END. | CALL PICK_PART |
| RUN | Flow | Run a program in the background (multitasking) | RUN MONITOR |
| END | Flow | End the program here and return to the caller, if any. | END |
| ABORT | Flow | Abort program execution | ABORT |
| PAUSE | Flow | Pause until operator presses CYCLE START | PAUSE |
| FOR | Flow | Start of a counted loop (FOR/ENDFOR) | FOR R[1]=1 TO 5 |
| ENDFOR | Flow | End of a FOR loop | ENDFOR |
| SELECT | Flow | Multi-way branch on a register value; the next lines hold =2,JMP LBL[2] and ELSE,JMP LBL[9]. | SELECT R[1]=1,JMP LBL[1] |
| R[] | Register | Numeric register (integer or real). Global and retained through power-off, so two programs can fight over the same R[]. | R[1]=R[1]+1 |
| R[]=expr | Register | Arithmetic on registers | R[2]=R[1]*10 |
| PR[i,j] | Position | One element of a position register: j = 1 to 6 for X, Y, Z, W, P, R. PR[1,3] is Z. | PR[1,3]=200 |
| P[] | Position | Taught position, local to its program. It stores the UFRAME and UTOOL numbers it was taught with. | L P[1] 500mm/sec FINE |
| UFRAME_NUM | System | Select the active user frame | UFRAME_NUM=1 |
| UTOOL_NUM | System | Select the active tool frame (TCP) | UTOOL_NUM=2 |
| OVERRIDE | System | Set the speed override (%) from the program. | OVERRIDE=80% |
| PAYLOAD | System | Switch the active payload schedule, for example gripper empty versus gripper with part. | PAYLOAD[2] |
| TIMER[] | System | Start, stop, or reset a timer | TIMER[1]=START |
| MESSAGE | System | Display a message on the teach pendant | MESSAGE[Cycle complete] |
| ! | Misc | Comment to end of line (TP convention) | ! Pick station setup |
These are the faults that turn up on real cells, most of them during commissioning.
DO[1]=OFF after L P[3] 1000mm/sec CNT100 fires before the robot reaches P[3], because the next line runs while the robot is still blending. With CNT100 on a pick point the gripper may never reach the part at all. Approach on CNT, arrive on FINE, or use a TIME BEFORE or DISTANCE BEFORE option when the output must switch on the path.
A P[] remembers the UFRAME and UTOOL numbers it was taught with, and the robot will not run it with other numbers active. Editing the values of a frame moves every point taught in it. Write UFRAME_NUM and UTOOL_NUM at the top of every program instead of relying on whatever was active last.
R[] and PR[] are global and keep their values through power-off. Two programs that both use R[1] as a loop counter corrupt each other, and a PR left over from an aborted cycle sends an Offset move somewhere new. Keep a register map, comment the registers on the pendant, and set PRs at the start of the program that uses them.
WAIT DI[1]=ON with no TIMEOUT leaves the robot standing with no alarm when a sensor dies. Add TIMEOUT,LBL[n] and a branch that shows a message or posts an alarm the operator can act on.
J P[1] 100% asks for the full joint speed of the arm, which on a large robot is very fast. The pendant override scales it, so a path that looked gentle at 10% override in testing can be violent at 100% in production. Raise the override in steps on a new path.
Fences, light curtains and E-stops go through the controller safety circuit, with DCS (Dual Check Safety) where zones and speed limits are needed. A TP or KAREL program that checks a door switch is a convenience on top of that, never a replacement.