I understand the I/O mapping, I don't see where I can use character strings. Goal is to declare a variable in kuka, set the characters, then retrieve it. ex. Description=this is part description.
CastTo and SWRITE
-
TickTack -
February 4, 2016 at 7:29 PM -
Thread is marked as Resolved.
-
-
create signals in $config.dat:
SIGNAL char1 $OUT[1] to $OUT[8]
SIGNAL char2 $OUT[9] to $OUT[16]
.... -
...or write function that will dump string into bit array (which is what outputs are)
-
If i use SIGNAL char1 $OUT[1] to $OUT[8], then I would have 25 of them per string that I want to get across. When you are using this is char1 the binary value of the actual character?
-
A multi-bit SIGNAL is treated as an INT variable. Assigning an INT variable a CHAR value converts the CHAR into its ASCII equivalent.
So:
CodeSIGNAL CHAR1 $OUT[1] TO $OUT[8] SIGNAL CHAR2 $OUT[9] TO $OUT[16] DECL CHAR _chString[2] _chString = "XY" CHAR1 = _chString[1] CHAR2 = _chString[2]
Outputs 1-8 will have a binary representation of the ASCII value X", and Outputs 9-16 will have a binary representation of of the ASCII value of "Y"
-
Thank you, that seems useful for this application, the only thing that concerns me is that I'll have to use too many bits.
each item i want to send across.
8bytes
8bytes
3bytes
25bytes
25bytes
4bytes
4bytesIll be using 616 bits just to send 7 strings, is this common for kuka? I would think it be a lot easier to use explicit messaging to get these across?
-
using EIP you can map to single node more than 500 bytes for inputs and 500 bytes for outputs.
500byte * 8bit/byte = 4000 bits. so you are using 616 bits. what seem to be the problem?
-
Oh Okay, I see what you mean now. Thank you!
-
at last... , i was suggesting same thing months ago.
-
since i have 2 characters that have 25 bytes each, is there a way to use a looping pointer to break that up into 1 byte, so i can set the same Outputs 25 times?
-
A character, by definition, is one byte. I think you mean "string".
Yes, this can be done, but you would need to add some handshaking logic so that the receiving device would know if you're sending over the 1st, last, or Nth character of the string.
But you can use a FOR loop to iterate through a string (or, technically, CHAR array, since KRL doesn't have a distinct "string" type).
-
-
So in the code posted above, say I wanted to transfer 5 bytes at a time, would the SIGNAL Index, be the number of characters at a time per loop? And StrLen is the total length of string? So would it go through the loop until Index is equal to StrLen?
DECL INT Index
DECL INTstrlenIndex=5
strlen=25SIGNAL Char1 $OUT[1] to $OUT[8] ; THROUGH CHAR5
............
SIGNAL Index $OUT[9] to $OUT[16] ; what's the purpose of this?FOR Index = 5 TO strlen(Variable[])
Char1 = variable[Index]
Char2 = variable[Index]
Char3 = variable[Index]
Char4 = variable[Index]
Char5 = variable[Index]$out[]= true
Wait for $IN[] = true -
nope....
1. you cannot mix declarations and assignments, declarations must be on top, before any initialization
2. you cannot do double declarations (Index is declared twice, once as an integer and once as a signal)
3. no point in mapping same character to 5 locations. it is enough to transfer it once. to transfer 5 different characters, use different index.
4. no need to initialize index before FOR loop, FOR loop does everything: initialization, incrementing and condition check.
5. if index is mapped to outputs, it will be transferred at the same time as the character that is mapped. this can be used to reconstruct block of data that was transferred piece-wiseCode
Display More;DECL INT Index ; do not use this, we have it declared as signal below SIGNAL Index $OUT[41] to $OUT[48] ; works as integer but also gets transferred to aid re-assembly on receiving end DECL INT str_length SIGNAL Char1 $OUT[1] to $OUT[8] ; this is ONE character only (first one) SIGNAL Char2 $OUT[9] to $OUT[16] ; this is second character... SIGNAL Char3 $OUT[17] to $OUT[24] SIGNAL Char4 $OUT[25] to $OUT[32] SIGNAL Char5 $OUT[33] to $OUT[40] ;............ str_length = strlen(Variable[]) FOR Index = 1 TO str_length step 5 Char1 = variable[Index] Char2 = variable[Index+1] Char3 = variable[Index+2] Char4 = variable[Index+3] Char5 = variable[Index+4] ENDFOR
-
I took the SIGNAL declarations as implied from the previous post.
-
With this stringvariable the char1 would return a "s" correct?
-
It would return each of string characters one by one... why don't you just try the code and see what it does? Delay can be eliminated if you know how to step through code....
-
I tried the code...when i declare the stringvariable[] what do i declare that as? i tried Char already...
-
This is all detailed in the KSS manuals. Unless declaring as a "receiving" argument in a subroutine/function, you must declare any array (including CHAR) with an explicit dimension.
-
sigh... omg... for a moment i thought we had a breakthrough but this is.... pretty faaaaaaar from it...
why do you need to over complicate things? when exactly you want this to be operational (months, years, eons)? what is your actual goal?
i was under impression that on one device you have some data (anything, integers, reals, strings... collection of bits) and you wish to transport it to another device (such as PLC or whatever). the simplest (and the fastest) possible way is to transfer them all at once (no scrambling, handshaking, streaming, descrambling etc) just SEND IT ALL IN A ONE SHOT!!!.
sending 25 characters one at a time requires at least 25 interpolation cycles and each is 12ms (and that is ideal case but it may easily be 2-3 times that depending on what you know and how you handshake).
25x12ms = 300ms = 0.3 second in the best possible case.if you do handshaking etc and need more than one IPO per char, this will be 0.6 or 0.9 or 1.2 seconds.
to transmit several strings through same pipe would of course take even longer. and not to mention royal pain the a$s to troubleshoot and recover any lost packets.when you don't have possibility to transfer whole block at once, fine - workaround is needed and that is when one may have to resort to trickling one or two characters at a time, do handshaking and assembly of transmitted data etc. this is when you need programmer (which you are obviously not). but that is NOT your case so why bother?
you have there KRC4 which means you have 4096 outputs - use them. and if that is not enough, you can double it to 8192 outputs by a mere click in WoV - no cost, no penalty, no worry, no hassle...
are there alternatives to spoon-feeding data through some tiny bottleneck? yes...
1. long and simple way was already presented so many times. to easily map 25 characters to outputs, you need to declare 25 signals of one byte. how hard is that? you mentioned 616-bit or just 77 characters in total, that is nothing compared to 500+ characters that can be transferred easily in a snap.
2. more compact way of writing (and much more flexible way to do something like this) is to write some own routine that will map string to bunch of outputs starting with particular output number, without having to declare all those signals. this also allows easy remapping without having to edit 25 lines of signal declarations (which is still not much of a deal since it needs to be done only once anyway).as mentioned, option 1 was already presented - read previous replies.
option two would look something like this:Codevar1[]="PB505" var2[]="I-Beam" var3[]="Matthew JAMES Folsom or fifty characters long" String_to_Outputs(var1[],1100) ; starting with output 1100, note var1 is 10char long String_to_Outputs(var2[],1180) ; 10 char is 80 bits so next one can start with output 1100+80 = 1180 String_to_Outputs(var3[],1260) ; use same logic as above
i think this is quite nice and rather readable part of program, not to mention easy to modify (change string name or starting output number).
all that is still missing is that String_to_Outputs() routine which could be done in many ways.
how about something generic like this:Code
Display MoreDEF String_to_Outputs(msg[]:out,lsb:in) ; msg[] = message to be sent ; lsb = first output in a contiguous block ; len = message length as declared ; chars = message length as initialized DECL CHAR msg[] DECL int lsb, fout, len, letter, chars len = strdecllen(msg[]) chars = strlen(msg[]) for letter=1 to len fout=lsb +(letter-1)*8 if letter<=chars then $out[fout + 0] = 0< msg[letter] b_AND 1 $out[fout + 1] = 0< msg[letter] b_AND 2 $out[fout + 2] = 0< msg[letter] b_AND 4 $out[fout + 3] = 0< msg[letter] b_AND 8 $out[fout + 4] = 0< msg[letter] b_AND 16 $out[fout + 5] = 0< msg[letter] b_AND 32 $out[fout + 6] = 0< msg[letter] b_AND 64 $out[fout + 7] = 0< msg[letter] b_AND 128 else $out[fout + 0] = false $out[fout + 1] = false $out[fout + 2] = false $out[fout + 3] = false $out[fout + 4] = false $out[fout + 5] = false $out[fout + 6] = false $out[fout + 7] = false endif endfor END
EDIT (formatting)
-