Problem with S7 STRING to REAL conversion

I guess that S7Guy means that the second header byte must contain a "14".


Yes, that's right. The first byte (byte 0) could be anything, and byte 1 MUST be 14 in order for FC39 to work. As far as I can tell, S7 sets byte 1 (actual string length) of the string to match the initial value only when you create the variable. If some other device sends a string that is S7 complient, then you will also see the correct value in byte 1. But if you change the initial value without going to the edit menu and "initializing the actual value with teh initial value", byte 1 will not have the correct length.

As I said, I still don't see how it can be CPU specific, because FC39 is pretty routine. I'm guessing now the problem is with the sequence of how the DB variable is created, downloaded, and initialized. Perhaps it's worth a try to force byte 1 to "14" before calling FC39.
 
Is this a case of the obnoxious "byte order" confusion that S7 may impose on the unsuspecting programmer ?

Are you guys really sure that we are all talking about the same when we say "first byte", "second byte", "byte 0", "byte 1" ?
 
No, I think I agree with S7Guy.
On creation of the STRING[14] declaration as the first element of my DB, a value of 14 was put in the initial value of DBB0. The initial value of DBB1 - DBB15 was zero.

While running the code and monitoring all the bytes, the only condition which seemed to affect the success of FC39 was the contents of DBB1. It had to be 14. A value of 13 was no good. A value of 15 was no good. The value of DBB0 however seemed to be a 'don't care' as far as the FC was concerned. I even put a value in DBB0 which was beyond the end of the DB itself and wouldn't have been surprised to get the usual 'area-length error when reading', but no it just kept on running.

Maybe this Siemens stuff is easier and more forgiving than we think!

Ken.
 
So Roy's application should work with any declared string size from 14 upwards provided the second byte contains a value of 14.

It does on the 314 CPU and on the 317, it works with all values for MAX from 16 upwards (still with 14 in the second Byte, of course).

As you can see in another recent post, new MMC thread, I haven't yet managed to upgrade the 317 to V2.3 firmware yet, so I don't yet know whether this will change things.
 
That's about the size of it Ken. I guess if I were sending strings from a Siemens TP, I would get a string that had the correct value in byte 1. But if it comes from anything else, it could be anything. Like I said before, for that reason I very rarely bother using strings and rely on character arrays (plus, the array can be longer that the 254 character limitation of the Siemens string).

RMA, keep in mind that you could still use an array, and pass the characters into a local string variable, and still use FC39. You would just have to load a 14 into byte 1 of the local string variable, and you'd be all set. I think it would be more reliable in the long run.
 
Perhaps it's worth a try to force byte 1 to "14" before calling FC39.

That's exactly what I was doing in my program and a LONG way before the FC39 call (about 50 + lines). But looking in the VAT, in wasn't getting loaded. Hence my query about how the compiler optimises code!

By the way, it does work, with my test program and a STRING[14] declaration the program was running and failing th FC30 call. Then I wrote a "14" from the VAT to the first Byte and the program started working immediately. By contrast, in the real program my:

L B#16#E
T DB41.DBB0

did not work - at least I couldn't see it in the VAT, it stayed stubbornly indicating "0".

Maybe we ought to start a new thread on this point and see if we can catch the attention of some whiz kids!

Cheers

Roy
 
Last edited:
If you can't force a value in the VAT table, then something in your program is overwriting it. Can you post a sample of the code so we can see what's going on?
 
Hey careful, Roy! S7Guy is a whizz kid!

Oops! :oops:

If you can't force a value in the VAT table, then something in your program is overwriting it. Can you post a sample of the code so we can see what's going on?

When I forced the VAT in my test program, it worked fine, in the real program, I was just observing in the VAT.

Oh heck, I was in Borte's posting before I came here, so I'll copy what I wrote there, it really belongs here anway.

(Quote:)
The code is executed and variables updated line by line, so there is definitely something happening in the logic. Another thing it could be is a pointer problem. Going back to Borte's previous post:

OK, if that's the case, how come my

L B#16#E
T DB41.DBB0

didn't work when the string definition was STRING[14] and with no changes to the FC program , after redefining the DB using STRING[16] and no other changes , everything worked perfectly?

You make an interesting point though, unfortunately(?) I'm back home now, so I'll have to wait till tomorrow to try writing the "14" in the VAT and see what happens.

Cheers

Roy
 
OK, if that's the case, how come my

L B#16#E
T DB41.DBB0

didn't work when the string definition was STRING[14] and with no changes to the FC program , after redefining the DB using STRING[16] and no other changes , everything worked perfectly?

They were unrelated events. When you forced 14 to DBB0, you weren't forcing the correct byte. When you changed the length to [16], it started working because you downloaded the block again, and DBB1 was loaded with 14 because that's how long your data was.

Let's say you enter a string in DB41 (we'll use TestString[150]), starting at byte 0, as you displayed earlier in this thread. By Siemens string convention, the first byte (byte 0) contains the configured length of the string, so it will have the value of 150. If the data block is not intialized with a value (meaning, you don't type anything in the initial value field), the value of byte 1 (the actual length of the string) will be 0 (this is the byte that FC39 reads).

Now, let's suppose you open DB41, switch to data view, type "This is a string test" in the actual value field, and download the DB. When you look at DBB0, it will still be 150, but DBB1 will be 21. If you called FC39 with this string, it would fail immediately when it read the 21. If you repeat the same test with a proper real number, FC39 will work because DBB1 will magically (without intervention from you) become 14.

This is why working with strings is not very flexible. Good or bad, you can send a string of 80 characters to DB41 starting at byte 2, but byte 1 remains 14 no matter what, because the data came down as individual characters (or non-Siemens string format). Again, with a character array, I treat the array as a string (but a normal string, not a Siemens one), and then add the header manually (it could be a header for a printer with a bunch of escape sequences, or it might be the two bytes you are concerned about).

In fact, if you look at FC39, you can scrap the whole string concept altogether with a couple of minor changes. The only reason it uses a string as an input is to make sure the length is 14 characters. If I were doing this, I would just make sure my message was always 14 characters myself, and rip through the conversion (that's all that FC39 does: it just loops through the bytes one by one).

Those canned functions are nice in some cases, but I have found that you can usually do it better with less code yourself.
 
S7Guy,

Are you suggesting that this arrangement of bytes in a string is a Siemens-only convention? I thought this was what the IEC61131 standard had mandated for a STRING datatype? I'm not trying to defend Siemens, I'm just wondering if I had got it wrong with that assumption. Do any other PLC manufacturers treat the first two bytes of a string in the same way?

Ken
 
They were unrelated events. When you forced 14 to DBB0, you weren't forcing the correct byte. When you changed the length to [16], it started working because you downloaded the block again, and DBB1 was loaded with 14 because that's how long your data was.

I'm not sure if I fully understand what you're trying to say here, in the actual program, I didn't force anything, I purely observed in the VAT. When I forced the "14" into DBB0 in my test program, it worked OK.

There again we're heading for 1:00 o'clock in the morning here, so maybe I'm not thinking clearly enough any more, maybe I ought to look at it again tomorrow!

Thanks for the interest nonetheless!

Cheers
Roy
 
Are you suggesting that this arrangement of bytes in a string is a Siemens-only convention?

I'm not familiar with other conventions. But it's irrelevant as to what other PLC manufacturers consider as a string, because the string can come from other sources (such as via a UDP broadcast) that don't know anything about the IEC61131 standard. For instance, try this as a test: Create a string variable, set it to the 100 bytes, and type "This is a test string" in the initial value field. Download the block, open the individual bytes in a VAT table, and you will see that the first byte of the string is 100, and the second byte is 21. Now, within the VAT table, add more characters to the string simply by forcing the characters beyond the orginal string, so that the actual characters spell "This is a test string +3". Even though we now have 24 characters within the string, byte 1 will still read 21, because the string wasn't formatted as a whole. To get it to read 24, you would have to type in "This is a test string +3" in the DB and download it again.

I am now seeing that explaining strings is very difficult. I'll tell you what I'm going to do, since it might benefit others: I am taking a week off and have a little time on my hands, and I'll come up with a short tutorial that will step through string manipulation. I think at the end of the tutorial, you won't want to use strings again. :)
 
Last edited:
S7Guy,

I don't see the issue of a STRING in a DB being any different to any other data type.

STEP7 will populate the DB with whatever data it has available at the point of creation of the variable. In other words if you specify an initial value it uses that, and in the case of a STRING it also derives the length information and fills these values in the first two bytes. After that it's all up to the user program.

With your example above, creating a STRING[100] and specifying no initial value gave me a DB with 100 and 0 as the first two byte values. Now delete the block, recreate it, but this time use "This is a test string" as the initial value and sure enough I get 100 and 21. Now modify the initial value (without re-creating the block or variable) re-download and the length info is unchanged. However, if change the actual value (not the initial value) offline and re-download, then the second byte does change as I would expect.

If I use any S7 functions which create or write to a STRING (integer conversion, real conversion) then S7 will update the second byte correctly according to the results of the procedure. On the other hand if I simply move values in or out of the declared string variable using load-and-transfer or moves etc these instructions know nothing about the significance of what they've just done. How would they know to update a byte at an arbitrary position in a DB several addresses ahead of where they've been working?

I guess PLCs were just never meant to learn to read properly - they should have stopped when they learned to count without taking their socks off!

Ken
 

Similar Topics

Hello folks, Using AB RSLogix micro.. I have a 6 digit ASCII text string and Im looking to convert the 4 most significant digits to an integer...
Replies
2
Views
1,449
I have a Red Lion G310 that im programming with Crimson 2.0 I have a internal string Tag that needs to be retentive. I have a string text with...
Replies
6
Views
3,930
hello, i am new here and have this problem that have driven me crazy, i have a lot of string edits in one display to control all the string...
Replies
0
Views
1,254
Hi, I have configured a tag of string with length 6. Ie N16:1 to N16:6. When that string is displayed in panel view it is showing in reverse...
Replies
9
Views
2,774
Ran across a problem with the TwinCAT Real_To_String conversion today. I have found that if my real is 0.12345 it converts to '1.2345' It also...
Replies
2
Views
1,709
Back
Top Bottom