You are on page 1of 18

https://es.scribd.

com/document/137899992/Curso-Fanuc-I-M07-programacion-2010

Sending a Fanuc Robots Position to the PLC


3 Comments Posted by Scott Whitlock in Industrial Automation
This information is for a Fanuc R30-iA, RJ3-iA or RJ3-iB controller but might work with
other ones.

If youre looking for a way to send the robot world TCP position (X, Y, Z, W, P, R) over to
the PLC, its not actually that difficult. The robot can make the current joint and world
position available in variables, and you can copy them to a group output in a background
logic task. There is one caveat though: the values only update when youre running a
program. They dont update while jogging. However, there is a work-around for this too.

First you should make sure that the feature to copy the position to variables is enabled. To
get to the variables screen, use MENU, 0 (Next), 6 (System), F1 (Type), Variables.
Find this variable and set it to 1 (or True): $SCR_GRP[1].$m_pos_enb
The name of that variable is Current position from machine pulse
Now create a new robot program, and in it write the following:

GO[1:X POS]=($SCR_GRP[1].$MCH_POS_X*10)
GO[2:Y POS]=($SCR_GRP[1].$MCH_POS_Y*10)
GO[3:Z POS]=($SCR_GRP[1].$MCH_POS_Z*10)
GO[4:W ANG]=($SCR_GRP[1].$MCH_POS_W*100)
GO[5:P ANG]=($SCR_GRP[1].$MCH_POS_P*100)
GO[6:R ANG]=($SCR_GRP[1].$MCH_POS_R*100)
Note that Ive multiplied the X, Y, and Z positions by 10, so you will have to divide by 10 in
your PLC. Likewise I multiplied the W, P, and R angles by 100, so divide by 100 in the
PLC.

To run this program in the background, use MENU, 6 (Setup), F1 (Type), 0 (Next), BG
Logic. Configure it to run your new program as a background task.
Obviously you need to send these group outputs to the PLC. Ethernet/IP is great for this,
but you can use hardwired interlocks too. You need to make sure that you have enough
bits to handle the full range of motion. A 16-bit integer should work pretty well for all of
these. Note that the robot will happily send negative numbers to a group output as twos
complement, so make sure you map the input to the PLC as a signed 16-bit integer (a.k.a.
INT in most PLCs). For the X, Y, and Z positions, a 16-bit integer will give you from
+3276.7 mm to -3276.8 mm of total range. For the W, P, and R angles youll get +327.67
deg to -327.68 deg. For most applications this is good (remember this is TCP, not joint
angles). Please check that these are suitable though.

As I said, these numbers dont update while youre jogging, and wont update until the
robot starts a move in a program. One little trick is to do a move to the current position at
the start of your program:
PR[100:SCRATCH]=LPOS
J PR[100:SCRATCH] 10% FINE
This starts sending the position without moving the robot. In my programs I typically enter
a loop waiting for an input from the PLC, and inside this loop I turn a DO bit on and off.
The PLC detects this as a ready for command heartbeat, and as long as the PLC sees
this pulsing, then it knows the program is running and the position data is valid.

Another trick you can use is to detect when the robot has been jogged:

DO[n]=$MOR_GRP[1].$jogged
The name of this variable is Robot jogged. The description from the manual is: When set
to TRUE,the robot has been jogged since the last program motion. Execution of any user
program will reset the flag.
Thats how you get the world position of the TCP into the PLC. If you just want joint angles,
you can use $SCR_GRP[1].$MCH_ANG[n] as the variable, where n is the joint
number.
Important note: The I/O will probably change asynchronously to the program scan, so
what you want to do is make a copy of the X, Y, Z, W, P, R values coming into the PLC
and compare the current values to the values from the last scan. If they havent changed,
then update your actual values, otherwise throw them away because they might not be
valid. If you have a fast scanning PLC and I/O then you should still be able to keep up with
the robot even during a fast move. If you have a slow scan time on your PLC, then you
might only get valid stable values when the robot is stopped.
Now what if you want to know what the TCP position is relative to one of your user
frames? The robot controller doesnt seem to give you access to this, but the PLC can at
least calculate the X, Y, and Z positions of the TCP in your user frame itself, given the
world position and the user frame parameters.

First you need to find the accurate user frame parameters. Under the normal frames
screen you can only get one decimal point of accuracy, but you need the full 3 decimal
points to have your numbers in the PLC match the user frame position given in the robot.
You can find these accurate positions in a variable: use MENU 0,6 (SYSTEM) F1
(TYPE) Variables $MNUFRAME[1,9] F2 (DETAIL). The second index in square
bracket is the frame number, so $MNUFRAME[1,1] is frame one
and $MNUFRAME[1,2] is frame 2. Copy these numbers down exactly.
Heres the math for calculating the TCP relative to your user frame. All variables are
LREAL (which is a 64-bit floating point variable). I dont know if you can use a regular 32-
bit float or not. Result is your TCP in user frame. Point is your point in world frame
(from the robot) and Frame is the accurate user frame data you copied from
the $MNUFRAME[] variable.

Result.X_mm := Point.X_mm - Frame.X_mm;


Result.Y_mm := Point.Y_mm - Frame.Y_mm;
Result.Z_mm := Point.Z_mm - Frame.Z_mm;
RadiansW := DegreesToRadians(-Frame.W_deg);
CosOfAngleW := COS(RadiansW);
SinOfAngleW := SIN(RadiansW);
RadiansP := DegreesToRadians(-Frame.P_deg);
CosOfAngleP := COS(RadiansP);
SinOfAngleP := SIN(RadiansP);
RadiansR := DegreesToRadians(-Frame.R_deg);
CosOfAngleR := COS(RadiansR);
SinOfAngleR := SIN(RadiansR);
// Fanuc applies rotations WPR as W (around Z), P
(around Y), R (around X)
// AROUND Z
temp := Result.X_mm;
Result.X_mm := Result.X_mm * CosOfAngleR - Result.Y_mm *
SinOfAngleR;
Result.Y_mm := Result.Y_mm * CosOfAngleR + temp *
SinOfAngleR;
// AROUND Y
temp := Result.Z_mm;
Result.Z_mm := Result.Z_mm * CosOfAngleP - Result.X_mm *
SinOfAngleP;
Result.X_mm := Result.X_mm * CosOfAngleP + temp *
SinOfAngleP;
// AROUND X
temp := Result.Y_mm;
Result.Y_mm := Result.Y_mm * CosOfAngleW - Result.Z_mm *
SinOfAngleW;
Result.Z_mm := Result.Z_mm * CosOfAngleW + temp *
SinOfAngleW;
Note that DegreesToRadians() is just PI*deg/180.
Run that on your PLC and check that the values in your Result variable match the user
frame TCP position reported on the teach pendant.

I havent gotten around to calculating the W, P, and R angles of the TCP in user frame yet.
Currently I just look at W, P, and R in world frame if I need to know if Im pointed at
something. If you get the math to work for W, P, and R, Id really appreciate if you could
share it.
https://www.robot-forum.com/robotforum/fanuc-robot-forum/how-to-restore-to-home-
position/
https://www.robot-forum.com/robotforum/fanuc-robot-forum/recovery-planning/
STARTING FANUC ROBOTS IN
AUTO
FI L E D UNDE R: FANUC

Youve finished programming your robot, tested it in T1, and now you want to run it faster.
If youre like me, you sometimes forget the details on Remote vs. Local, UOP signals and
the different startup types available (RSR, PNS, Style, Other). For your (and my own)
reference, heres a quick no-BS guide on how to get things running.

T HE MODE SELECT ( T 1/ T 2/ AUT O) SWIT CH

T1 and T2 are for teaching and testing the robot. T1 limits the tool center point (TCP) speed
to a nice and safe 250mm/sec.

If your robot has T2, you probably have an older robot or youre outside the US. This mode
became non-standard in the US several years ago, but it allows you to test-run programs
with the teach pendant at full speed. Be careful out there.

When the robot is switched into AUTO, youre running programs without the teach
pendant. In fact, if the teach pendant is enabled, the robot will be in a fault condition. Some
other device (covered later) will issue signals to start the robot.

FENCE CIRCUIT

The fence circuit is bypassed in T1 and T2, but it must be closed when in AUTO mode.

LOCAL MODE

Now that your robot is in AUTO, you can choose to start it remotely or locally. This
configuration option is on the System Config screen (Menu > System > Config).

When in local mode, the robot will be started from the Standard Operator Panel (SOP)
buttons located on the controller.
Be careful: when the robot is in local mode, it will always run whatever program you have
selected on the SELECT menu. The robot will ignore any setup you have done on the
Program Select method screen.
I generally switch things over to AUTO/Local after some thorough testing in T1. Start out
slow with your finger on the HOLD button, gradualling bumping up the override before
doing the same thing with the PLC in charge.

REMOTE MODE

When the robot is in Remote mode, it will follow the Program Select method and
Production Start method you defined in the system config screen. Youll probably always
use UOP as the Production Start method.

There are four Program Select methods: RSR, PNS, STYLE and OTHER, but I think
OTHER is best option.

OTHER

Ah, OTHER: the simplest, most barebones and easy-to-use startup method. The robot
simply runs an explicitly stated program when it receives a start signal.

Set your Program Select Mode to OTHER on the system config screen and then specify a
program to run by hitting DETAIL. You can also set the program name via
the $shell_wrk.$cust_name system variable.
I find that keeping it simple, having the robot start some main task and handling any job
requests, etc. from there is generally best, but Ill briefly summarize the other methods as
well.

ROBOT SERVICE REQUEST (RSR)

Im not sure why anyone would use this program select method. (If you have a compelling
reason, please let me know.) RSR basically lets you specify 8 numerically identified
programs that correspond to 8 input bits. You have the option to add an acknowledge bit,
but its not really a full handshake.

The setup screen has you associate a number with each of your 8 RSR bits (e.g. 10, 20, 30,
etc.). You can also specify a base that these numbers will get added to (e.g. 100). With
these example values, if the RSR1 input is given the robot will execute RSR0110 (base of
100 + RSR1 bit value of 10). RSR2 would execute RSR0120, RSR0130 for RSR3, and so
on.

You have to follow this naming convention (RSRxxxx) exactly, but you can modify the
RSR prefix via $shell_cfg.$job_root.
Im not a fan of these non-descriptive names (what the heck does RSR0150 do again?), so I
wouldnt recommend using this method.

PROGRAM NUMBER SELEC T (PNS)

PNS is kinda like RSR, but it interprets the 8-bits as a binary number. You dont have to
explicitly set numbers fo each signal, but you can define a base
number $shell_cfg.$pns_base. The naming convention is similar (PNSxxxx) unless
you change the prefix with $shell_cfg.$pns_program.
This startup type is a bit more useful since it requires less setup and you get more jobs, but
Im still not seeing the benefit here

STYLE SELECT

Style is basically PNS without a naming convention. You have to explicitly setup a table
that associates a given TP program with the input job number.

Additionally, you can enable/disable entries via the setup table. You can also write a
comment to remind yourself what your poorly named program does if thats how you roll.

THE BOTTOM LINE WITH PROGRAM SELECT METHODS

It seems to me that the RSR, PNS and STYLE Program Select methods are all remnants of
an earlier time. Who wants to name their programs RSR0001 or PNS1000 when you could
write something more descriptive like UNLOAD_LATHE_A?
If you cant be bothered to setup your own logic for job requests, STYLE is probably your
best bet.

A SI MPL E JOB REQUE S T HAN DSH AK E

Heres how I might write a simple routine to get a job request:

! get_job.ls

LBL[1] ;

WAIT (DI[1:job request]) TIMEOUT,LBL[500] ;

R[1:job]=GI[1] ;

! GO[1:job] echos R[1] in BG logic ;

DO[1:job ack]=ON ;

LBL[2] ;
WAIT (!DI[1:job request]) TIMEOUT,LBL[501] ;

DO[1:job ack]=OFF ;

END ;

LBL[500] ;

! timed out waiting for job ;

JMP LBL[1] ;

LBL[501] ;

! timed out waiting for job request to go low ;

JMP LBL[2] ;
The PLC would be responsible for validating GO[1] after DO[1:job ack] comes on.
Then your main routine might look something like this:

! main.ls

LBL[1] ;

CALL GET_JOB ;

SELECT R[1:job]=1,CALL SOME_JOB ;

=2,CALL SOME_OTHER_JOB ;

ELSE,CALL INVALID_JOB ;

! maybe put a job done handler here ;

JMP LBL[1] ;
In 2016 I think its a little silly to pass integers around I havent personally seen anyone
do it this way, but you could (in theory) use Explicit Messaging to set a string register and
call the result:

! main.ls

LBL[1] ;

! populate SR[1] ;

CALL GET_JOB ;

CALL SR[1] ;

! maybe put a job done handler here ;


JMP LBL[1] ;
UOP SIGNALS

Im willing to bet youre going to start your robot with a PLC communicating via
Ethernet/IP. I wont go over the Ethernet/IP setup here (maybe a topic for another post), but
lets quickly cover the various UOP signals and what they do.

UOP I NPUT SI GN ALS

On the input side (from the robots perspective), you get up to 18 signals, but youll
probably only need the first 8.

NOTE: You have to enable UI signals from the MENU > System > Configscreen. Set
Enable UI Signals to TRUE.
UI[1:*IMSTP] Leave this on all the time. When it drops, the robot will stop immediately,
but this should not be used for safety purposes.
UI[2:*Hold] Leave this on unless you want to pause the robot. If this signal ever dips,
the robot will slow to a controlled stop, pause its program and wait for a start signal to
resume.
UI[3:*SFSPD] This annoying little signal is normally on. When it drops, it will pause the
robot and clamp the override to $scr.$sfrunovlim. If youre in teach, itll clamp the
override to $scr.$sfjogovlim.
UI[4:Cycle stop] This signal can be used as a cycle stop or immediate abort signal
depending on the value of $shell_cfg.$use_abort. If set to true, it will act as an abort
signal. If set to false, youll have to check UI[4] in your program and ABORT by hand.
UI[5:Fault reset] Normally off, this signal will attempt to reset any errors on your
robot. Note: your robot cannot start or resume if any faults are present.
UI[6:Start] This one depends on $shell_cfg.$cont_only. If set to true, UI[6] will
only resume a paused program, and youll have to use UI[18:Prod start] to start from
scratch. If set to false, it will resume or start an aborted program from the cursor position.
UI[7:Home] Pretty useless, but the idea is that your robot will execute a home macro
when this signal is received.
UI[8:Enable] When this signal is high, the robot can move.
So basically, to start the robot:

1. Turn on UI[1:*IMSTP]
2. Turn on UI[2:*Hold]
3. Turn on UI[3:*SFSPD]
4. Turn on UI[8:Enable]
5. Pulse UI[5:Fault reset] to clear any faults
6. If there are no faults, pulse UI[6:Start]
If the robot is paused (from dropping the hold signal, a fault or e-stop):
1. Keep UI[1:*IMSTP], UI[2:*Hold], UI[3:*SFSPD] and UI[8:Enable] high
2. Pulse UI[5:Fault reset] if necessary to clear faults
3. Pulse UI[6:Start]
UOP OUTPUT SIGNALS

Youll get some signals back from the robot if you want. Feel free to use any or all of them
to make your PLC more intelligent.

UO[1:Cmd enabled] This is ON when the robot is in Remote mode and not faulted. You
can only start/resume the robot when this is ON.
UO[2:System ready] Servo motors are on
UO[3:Prg running] A program is running
UO[4:Prg paused] A program is paused
UO[5:Motion held] On when the robot is actively being held (e.g. UI[2:*Hold] is
low)
UO[6:Fault] On when there is a fault that needs to be cleared/reset
UO[7:At perch] When the robot is at reference position #1
UO[8:TP Enabled] When the teach pendant is on
UO[9:Batt alarm] When the CMOS RAM battery voltage is less than 2.6V or robot
battery voltage is low
UO[10:Busy] When the robot is thinking
Im not a PLC guy, but I would:

1. Make sure UO[1:Cmd enabled] is on before issuing any start signals


2. Dont bother issuing any start signals if UO[3:Prg running], UO[5:Motion
held] or UO[6:Fault] is on
3. Know that youll have to give a reset if UO[6:Fault] is on
4. Maybe prohibit a start from the top unless `UO[7:At perch] is on
5. Tell the operator to turn off the TP if you want to run and UO[8:TP enabled] is on
6. Tell someone to change the batteries if UO[9:Batt alarm] is on
Member

United States

geoplc is offline

Join Date: Oct 2006


Location: PAinesville OH

Posts: 123

Hi mzolo

The sequence for pns is important and as follows.

1.Turn on binary program select bits (PNS01 binary 1, PNS02 binary 2, PNS03 binary 4, etc)

2. Turn on PNS strobe signal

3 . Now you should see the SNACK program you sent echo back under SN01, SN02, etc which
relate one to one with PNS01, etc

4. Turn off PNS strobe, if you do not the robot will never respond to the PRODSRT production
start.(Not START, that is only used to start a paused program or HELD robot)

5. Send PRODSTRT pulse (do not hold on)and the robot should run the program

All the signals can be monitord under the IO screens under UOP/SOP

Also the prgrams name needs to be PNSXXXX X being the program number i.e. PNS0003

You also need to setup the robot to PNS from RSR, cant remember menu strokes but will look up
and send them

Good luck talk again son

Hi mzolo
Member The sequence for pns is important and as follows.
1.Turn on binary program select bits (PNS01 binary 1,
PNS02 binary 2, PNS03 binary 4, etc)
2. Turn on PNS strobe signal
3 . Now you should see the SNACK program you sent echo
Join Date: Oct 2006
Location: PAinesville OH back under SN01, SN02, etc which relate one to one with
Posts: 123 PNS01, etc
4. Turn off PNS strobe, if you do not the robot will never
respond to the PRODSRT production start.(Not START, that
is only used to start a paused program or HELD robot)
5. Send PRODSTRT pulse (do not hold on)and the robot
should run the program
All the signals can be monitord under the IO screens under
UOP/SOP
Also the prgrams name needs to be PNSXXXX X being the
program number i.e. PNS0003
You also need to setup the robot to PNS from RSR, cant
remember menu strokes but will look up and send them
Good luck talk again soon

You might also like