• Not Answered

String manipulation

Hello, what can you do with strings in DeltaV? I know you can concatenate 2 strings with the operator + but besides that can you do anithing else? can you look for a string inside another string? can you remove part of a string?

3 Replies

  • Within the controller your options of string manipulation are severely limited...

    Numbers will be default to what they have when converted to a string unless you do either of the below:

    • Integer (remove decimals - first just takes the decimals off and the second will convert float to integer)

    '^/STR_NUM.CV' := "My float to integer is " + TRUNC('^/NUM_PARAM.CV');

    '^/STR_NUM.CV' := "My float to integer is " + TRUNC(ROUND('^/NUM_PARAM.CV'));

    • FP specific decimals

    DECIMAL1 := 2;
    POWER1:= EXPT(10,DECIMAL1);
    '^/STR_NUM.CV' := "My float to 2 decimals is " + ((ROUND('^/NUM_PARAM.CV' * POWER1)) / POWER1);

    At the HMI, you have lots of string manipulation that can be done and only limited to VBA (Operate) or Java/TypeScript (DeltaV Live).

  • In reply to Matt Stoner:

    So thats all concatenating strings and other stuff so i guess no other operations right?
  • In reply to ThunderHunter13:

    The reasoning lies somewhere in the fact that controllers deal with machine level stuff and the HMI deals with Humans, and that pesky language thing that is so illogical.... There is a long history starting with the original OS used on controllers and how strings affected memory fragmentation. Back in the day, handling strings in the controller was not the chosen path. Named Sets convert integers to strings and Alarm types provide alarm messages that are stored at the workstations rather than the controllers. But handling and parsing strings and arrays and such was not in the cards early on, and that has stuck,

    Another challenge with strings is passing them via Modbus as ASCII characters. DeltaV does not have an ASCII format so these are passed simply as integers where a 16 bit integer holds two 8byte characters. We created a Composite block that reads a number of integers into an Array. The Block contains a second composite that contains 255 string parameters that are named by their ASCII "position" from CHR0 to CHR255. (ie. CHR65 holds the character "A".) The main composite contains a set of dynamic reference parameters called ASCII_1 to say ASCII_16. A Calc block parses the array to read each ASCII value and sets the $REF feild of of the ASCII_x parameter, pointing to the CHR# in the composite. Finally, the CALC block concatenates the .CV value of the dynamic references into a string, once the references are defined (.CST =1). We just check the first Character. If the text is shorter than the allotted parameters, the extra are all defined to a blank. The string is always the same size.

    We can add more ASCII_X fields to handle longer strings, or add several composites to handle substrings that are then concatenated into a longer string.

    This is not efficient, but works. Note: The array is a Float Array, so it will handle an unsigned 16 bit integer holdiing register accurately. Going the other way is much harder and we don't do in the controller. We usually see this for limited text information.

    String values don't change frequently, so this solution should be triggered to run on a change flag or periodically.

    Couple of things I'd like to see are:
    1. Integer Array: A float array cannot represent a 32 bit integer accurately. Being able to store and retrieve 32bit values would be useful, including an array of Time values from a DTE block
    2. A string call that would be able to read an LDT of ASCII characters as a String. A compiled function would be much more efficient that clever Composites.
    3. Find in String and Split functions would also be quite useful.

    With the new OS in all our controllers, the issues with strings should be easier to deal with.

    Andre Dicaire