How to get a data type of REAL from PLC to robot? using profinet
What i have did is.
In $config.dat
Real Orange
In SRC.DAT
x=Orange
I want to get the real value(678.34) from PLC to robot.
Thank you for your time.
How to get a data type of REAL from PLC to robot? using profinet
What i have did is.
In $config.dat
Real Orange
In SRC.DAT
x=Orange
I want to get the real value(678.34) from PLC to robot.
Thank you for your time.
Multiply by x on the PLC end, then divide by x the KRC end.
100 is a good value for x
Sent with my Windows Phone using Tapatalk
Thanks for your reply. Can you please detail your statement because i cant't get your point.
As far as I know you can't do it.
That's why eusty is recommending you to send a normal int, word... from the plc to the robot and divide it by 100 or whatever you need regarding precision.
A bad solution as you can't use the complete variable range but...
Understand it as sending micrometers and not mm or so...
how to send the integer from plc to robot
What are setting should be done in robot side?
my profinet RANGE IS FROM $705 TO $867
INTEGER IS 2 BYTE
Should i set it anolog input? or...?
In the $config.dat:
SIGNAL my_int_from_plc $IN[X] to $IN[X+15] ;X is your start input and you said two bytes
In the .src file (example)
LIN XPOS
XPOS.X = XPOS.X + my_int_from_plc ;my_int_from_plc can be used as regular integer
LIN XPOS
Thank you.
Is this the same way If I am using a camera and sending my XYZ coordinates to robot. Can i use the same technique or different technique?
If its real I have to use
SIGNAL my_int_from_plc $IN[X] to $IN[X+123] ;X is your start input and 4bytes because data type real is 4 bytes.
Am i Rite?
There's some additional complexity here. First, in order to transfer Reals, you have to have a means to position the decimal point properly. Then, you have to deal with polarity.
For the decimal point, the simplest method is to multiply by 10^x on the transmitting side, to move the decimal point x places to the right -- in essence, converting the REAL into an INT (for a certain number of significant digits). Then, on the receiving end, you have to divide by 10^x before using the value. And, of course, you have to ensure that x is the same on both ends.
Handling +/- is more tricky. First, you have to remember this: KRL treats a multi-bit SIGNAL declaration as an unsigned INT, unless the SIGNAL is 32 bits in size -- then, and only then, does KRL treat it as a signed INT.
So, let's assume a simplistic 16-bit signed integer. If the 16th bit is the sign bit, then you have 15 bits of resolution -- your value can range from +32767 down to -32768. But the KUKA will only see it as ranging from 0 to +65535.
So, simple approach: in your KRL program, receive the 16-bit input, mask off the sign bit, divide by 10^x to get your decimal point back in the right location, then negate the resulting value if the sign bit was True.
DECL INT TempInt
DECL REAL TempReal, FinalX
SIGNAL CameraInputX $IN[1] to $IN[16]
TempInt = CameraInputX B_AND 'H7FFF' ; mask off the sign bit
TempReal = TempInt / 100 ; move decimal place 2 places to the left -- adjust as needed
IF CameraInputX B_AND 'H8000' THEN ; check if Sign bit was set
FinalX = 0 - TempReal ; sign bit was True, hence value was negative
ELSE
FinalX = TempReal ; sign bit was false, value was positive
ENDIF
That's a very simplistic implementation, and can suffer from some rounding error on the lower digits, but it's worked for me in the past. However, it will depend on how the transmitting device is formatting the REAL value. If it's using IEEE-754 encoding, for example, this trick won't work. You'll need to do some research into exactly how your camera encodes it data for transmission.
I want to get the real value(678.34) from PLC to robot.
using only 16-bit, you better keep x at 10 (on the PLC side multiply value by 10, on Robot side divide by 10 to get approximate value).
with x=100 you will have problem because:
678.34 * 100 = 67834 which exceeds range 0-65535
since you are using fieldbus between PLC and robot, why are you limiting the signal to 16-bit?
Display More
There's some additional complexity here. First, in order to transfer Reals, you have to have a means to position the decimal point properly. Then, you have to deal with polarity.For the decimal point, the simplest method is to multiply by 10^x on the transmitting side, to move the decimal point x places to the right -- in essence, converting the REAL into an INT (for a certain number of significant digits). Then, on the receiving end, you have to divide by 10^x before using the value. And, of course, you have to ensure that x is the same on both ends.
Handling +/- is more tricky. First, you have to remember this: KRL treats a multi-bit SIGNAL declaration as an unsigned INT, unless the SIGNAL is 32 bits in size -- then, and only then, does KRL treat it as a signed INT.
So, let's assume a simplistic 16-bit signed integer. If the 16th bit is the sign bit, then you have 15 bits of resolution -- your value can range from +32767 down to -32768. But the KUKA will only see it as ranging from 0 to +65535.
So, simple approach: in your KRL program, receive the 16-bit input, mask off the sign bit, divide by 10^x to get your decimal point back in the right location, then negate the resulting value if the sign bit was True.
CodeDECL INT TempInt DECL REAL TempReal, FinalX SIGNAL CameraInputX $IN[1] to $IN[16] TempInt = CameraInputX B_AND 'H7FFF' ; mask off the sign bit TempReal = TempInt / 100 ; move decimal place 2 places to the left -- adjust as needed IF CameraInputX B_AND 'H8000' THEN ; check if Sign bit was set FinalX = 0 - TempReal ; sign bit was True, hence value was negative ELSE FinalX = TempReal ; sign bit was false, value was positive ENDIF
That's a very simplistic implementation, and can suffer from some rounding error on the lower digits, but it's worked for me in the past. However, it will depend on how the transmitting device is formatting the REAL value. If it's using IEEE-754 encoding, for example, this trick won't work. You'll need to do some research into exactly how your camera encodes it data for transmission.
Hi,
I think I am facing a problem exactly what you have explained. I should detail the problem.
I am getting some values from Siemens PLC to offset the angles (A, B and C) while the robot is stacking a sheet. The range of these offsets should be +/-2 degrees. In my code, I am trying to take care of the negation i.e. overflow and the decimal points. Here is the code:
;In Config.dat
SIGNAL A_ANG_OFST $IN[2065] TO $IN[2080]
SIGNAL B_ANG_OFST $IN[2081] TO $IN[2096]
SIGNAL C_ANG_OFST $IN[2097] TO $IN[2112]
INT COPY_A_ANG_OFST=0
INT COPY_B_ANG_OFST=0
INT COPY_C_ANG_OFST=0
DECL REAL A_ANG_OFST[2]
A_ANG_OFST[1]=0.0
A_ANG_OFST[2]=0.0
;
DECL REAL B_ANG_OFST[2]
B_ANG_OFST[1]=0.0
B_ANG_OFST[2]=0.0
;
DECL REAL C_ANG_OFST[2]
C_ANG_OFST[1]=0.0
C_ANG_OFST[2]=0.0
;
;In Submit (Background)
COPY_A_ANG_OFST=A_ANG_OFST
IF COPY_A_ANG_OFST>=32768 THEN
COPY_A_ANG_OFST=COPY_A_ANG_OFST-65536
ENDIF
;
COPY_B_ANG_OFST=B_ANG_OFST
IF COPY_B_ANG_OFST>=32768 THEN
COPY_B_ANG_OFST=COPY_B_ANG_OFST-65536
ENDIF
;
COPY_C_ANG_OFST=C_ANG_OFST
IF COPY_C_ANG_OFST_A1>=32768 THEN
COPY_C_ANG_OFST=COPY_C_ANG_OFST-65536
ENDIF
A_ANG_OFST[1]=COPY_A_ANG_OFST/10
B_ANG_OFST[1]=COPY_B_ANG_OFST/10
C_ANG_OFST[1]=COPY_C_ANG_OFST/10
Display More
The problem is that the end result i.e. the values of A_ANG_OFST, B_ANG_OFST and C_ANG_OFST are getting rounded to the nearest integer value. I even tried to send the values in the multiple of 100 by doing so at both PLC and robot ends. I may implement the solution proposed by Skyfire but I would really like to understand the phenomenon as why the values are getting rounded to integers and are not with decimals even after using the REAL datatype.
BTW, the REAL tags are defined in arrays because I have two destination of stacking and the values are transferred to active destination.
Thanks
in KRL, SIGNAL is either BOOL type (if single bit) or an INTEGER... always... regardless of word size (2,3,4... 32 bit).
this means values that you transmit through SIGNAL will always be CAST into an integer.
CAST-ing causes rounding since integers cannot represent digits after decimal point.
Most people don't have good understanding of numbering system and prefer to choose simplest solution possible - FIXED instead of FLOATING decimal point.
Idea with FIXED decimal values is to multiply REAL by some scaling FACTOR before sending, then divide received value by same FACTOR n receiving end.
Again, majority of people choose FACTOR that is power of 10 (10, 100, 1000 etc.) although any other value could be used as well (such as 12 or 39).
Using FACTOR that is power of 10 does make representation simpler but it is usually inefficient (if using fewest number of bits is goal).
Name FIXED comes from a fact that decimal point is given FIXED location, something like:
000.012
001.234
123.456
Clearly this representation can only cover fairly narrow range of values. many years ago ID software released game DOOM which was revolutionary at the time. It allowed smooth 3D animation that required tons of calculation and it worked smoothly even on machines without math coprocessor (FPU) because underlying math was relying on calculations that use integers math to compute REALs expressed as FIXED decimal values.
Using FLOATING point values (this is real REAL) requires encoding since "decimal point" can be in different places (it "floats" around):
0.123456
12.3456
123456.0
This is because in FLOATING decimal point values is that contains both significand and exponents, permitting coverage over huge range of values with decent accuracy. This would otherwise require many more bits if using FIXED point representation. On systems without FPU computation of FLOATS is done in software which is MUCH slower (50-300x slower is a typical figure). However, today FPUs are in just about everything, even microcontrollers.
...I would really like to understand the phenomenon as why the values are getting rounded to integers and are not with decimals even after using the REAL datatype.
Take a look at documentation and topics discussed many times.
you are using INTEGERS in your calculations (which can be forgiven *if* used wisely) but you are also doing INTEGER calculations (pitfall )
;In Config.dat
SIGNAL A_ANG_OFST $IN[2065] TO $IN[2080] ; this is an INTEGER
SIGNAL B_ANG_OFST $IN[2081] TO $IN[2096]
SIGNAL C_ANG_OFST $IN[2097] TO $IN[2112]
INT COPY_A_ANG_OFST=0 ; this is an INTEGER
INT COPY_B_ANG_OFST=0
INT COPY_C_ANG_OFST=0
;...
;In Submit (Background)
COPY_A_ANG_OFST=A_ANG_OFST
IF COPY_A_ANG_OFST>=32768 THEN
COPY_A_ANG_OFST=COPY_A_ANG_OFST-65536 ; again an INTEGER
ENDIF
;
A_ANG_OFST[1]=COPY_A_ANG_OFST/10 ; an INTEGER division...! tsk..tsk... :uglyhammer2:
B_ANG_OFST[1]=COPY_B_ANG_OFST/10
C_ANG_OFST[1]=COPY_C_ANG_OFST/10
Display More
Short version of Panic's explantion: In KRL:
15/10 = 1
15/10.0 = 1.5
Replace your "/10" with "/10.0" and see what happens.
As attached pic shown, it's an example how convert signal variable (input) into float data type.
来自我的 MI 5s 上的 Tapatalk
Thanks to all of you. After reading your replies I caught my mistake and fix it. I changed the variables COPY_A_ANG_OFST, COPY_B_ANG_OFST, COPY_C_ANG_OFST to REAL datatypes and everything worked like a charm.
Thanks again.
As far as I know you can't do it.
That's why eusty is recommending you to send a normal int, word... from the plc to the robot and divide it by 100 or whatever you need regarding precision.
A bad solution as you can't use the complete variable range but...
Understand it as sending micrometers and not mm or so...
Hi, i found thread post very useful, i have another question about this.
If in my plc (an s7-300 -> profinet -> kuka ), i have a variable of 32bits like a real type, after i swap it's byte can i transfer it directly to the input of kuka if i have in my config.dat code a signal for example signal my_real $IN[0] to $IN[31] ?
Thanks a lot.
you can transfer it any time, and encoded any way you like but you will need to reverse process to get the data in usable format. this means that things like different endianness will need to be taken into consideration. and exact place where all this takes place is irrelevant.
for example you could do byte swapping either before or after transmission. you can also change bit or byte order after value is received, using own program. normally byte swapping is something that one does at I/O mapping level so the order change appears transparent to user programs. in KRC2 for example this was possible at byte level. in KRC4 this is possible at bit level and the bits don't even need to be grouped together.
Have look to Re: KRC4 Profinet/Ethercat/Ethernet IP Real Word Transfer
$IN[0] doesn't exist
Thanks for the answer.
But excuse me i do not understand if i write 32 bit from my plc in profinet to my kuka kr taking in consideration things like endiannes i can use REAL variable or i've need something else like casting or conversion.
;In Config.dat
SIGNAL my_real_input $IN[1] TO $IN[32]
Real my_real_variable = 0.0
;In my code
my_real_variable = my_real_input
;and then ? I can use my variable ?
Display More
Thanks a lot.
No. Read the above mentioned thread.
If you set a real variable (IEEE format) from PLC to the bus you have to use the conversion method b2r().
If you set a double word or double int from PLC you can use your code, but this is no conversion, but only a different presentation of the value.