Studio 5000 UTF-8

Thanks, I like the thinking in the last post..

If you reconsider what I posted to begin with, I need to send a set of byte codes in hex to a printer, they are a command sequence. Each command has a specific sequence, followed by the data the printer has to print. The 8th byte of hex must be the length of the data in hex, which varies with each message content.

That's why I was converting the length of the message data text into hex, then trying to add that length onto the end of the existing string of command bytes (also already in hex, $EB$04$00$01$00$00$00$??), followed by the actual data.

I've written a lot of software in machine automation but not required to do a lot of PLC string handling, which is easy as pie in C# world but clunky it seems in ControlLogix world. Normally all PLC strings are alarm messages or HMI stuff, nothing difficult, until this task came along.

Here's where we came in - trying to add a 2 digit hex string on the end of the command string, but unable to CONCAT the string with a 8th '$' and the hex value of the length.

I assumed it was clear what I was trying to do, and the previous solution was going to handle hex as a string to BCD but of course I now realise it doesn't when the hex contains non numeric chars - which of course hex does.

I have tried every possible method of creating a string char in a SINT array, of the correct value in hex and preceded by a $ sign but jeez it is not letting me do any of it. This is why I turned to asking on here to see if anyone had a better idea how to make that seemingly simple task work.

Thanks, sorry for the long winded post.
 
@drbitboy and @MikeyN - I came up with a glaringly simple way to do it, after thinking about bits and mapping of string SINTs

My length value of the message data lets say for instance is 127 chars, so I put that in DecimalValue (DINT). Then, I have a HexString (STRING) which I can map the bits to, in 2 lines of ST:

HexString.LEN := 1;
HexString.DATA[0] := DecimalValue;


HexString now contains '$7F' (Dec 127 in Hex) - then add that string to the end of the command hex bytes string:

CommandString.LEN := 8;
CONCAT(HexString, CommandString, CommandString);

and then of course CONCAT the new command string with correct hex length value in the last byte, to the message for printing.

It was that simple. Jesus wept.

Thank you for all of your help, it was invaluable in getting my mind on the right track - BITS.

SOLVED!
 
Last edited:
I am pretty sure you are not trying to "add a 2 digit hex string on the end of the command string."

You are trying to convert a binary length as an 8-bit integer, and insert that as the eighth single character of a string, where the printer will interpret that eighth character as an 8-bit integer length.

The '$xx' convention, where xx is a 2-digit hexadecimal number, in the Studio 5000 IDE is a form of string literal i.e. it is a way to use the keys on a keyboard only to specify a non=printable, i.e. not-on-the-keyboard, ***SINGLE*** character into a string. The PLC program knows nothing about the '$xx' character entry convention.

There is no such thing as a "hexadecimal integer," in Studio 5000, or anywhere else. There is a hexadecimal representation of an integer (e.g. 7F), typically a string or displayed characters, analogous to the decimal or octal or binary representation of an integer (e.g. 127 decimal or 177 octal or 01111111 binary, for the same value as hexadecimal 7F).
 
@drbitboy and @MikeyN - I found a glaringly simple way to do it, after thinking about bits and mapping of string SINTs

My length value of the message data lets say for instance is 127 chars, so I put that in DecimalValue (DINT). Then, I have a HexString (STRING) which I can map the bits to, in 2 lines of ST:

HexString.LEN := 1;
HexString.DATA[0] := DecimalValue;

HexString now contains '$7F' - then add that string to the end of the command hex bytes string:

CONCAT(HexString,CommandString,CommandString);

It was that simple. Jesus wept.

Thank you for all of your help, it was invaluable in getting my mind on the right track - BITS.

SOLVED!
If you look at my Post #7, you will see that I suggested exacty that, but without the need for a separate 1-character string and a CONCAT operation, because you can overwrite the 'DecimalValue' directly into the eighth element, i.e. into .DATA[7], of the string you are constructing, and then assign a value of 8 to that string's .LEN attribute (or start with a constant string length of 8 by starting with '$EB$01$00$04$00$00$00$00' i.e. a length of 0 in the eighth character holding the position that will be replaced by the actual length when the rest of the string is known).

Again, your tag named "DecimalValue" is not a decimal value, it is a binary Double-word (32-bit) INTeger i.e. DINT. And your tag named "HexString" is not string of hexadecimal characters with dollar signs, it is a compound object comprising
  • a length (.LEN), and
  • a sequence (array .DATA[]) of binary Single-byte (8-bit) INTegers i.e. SINTs,
that is interpreted, and displayed, as a string of ASCII characters. For display in Studio 5000 IDE only, those integers are displayed as
  • EITHER as the corresponding ASCII character for integers represeting printable characters (space, !, ... 0, 1, 2, ..., @, A, B, C, etc.),
  • OR as the '$xx' (dollar-plus-two-hexadecimal-digits) convention, for non-printable
    • which displays three characters to represent only, and exactly, one element of the string's array of SINTs (.DATA).
To illustrate my point, try entering a string-to-print length (not the .LEN) of 64 (hexadecimal 0x40 in C or '$40' in Studio 5000 IDE). When the Studio 5000 IDE displays that string, it will display '$EB$01$00$04$00$00$00@' not ''$EB$01$00$04$00$00$00$40'

So in the end it is no more complicated than C.
 
Last edited:
It's just bits; the only choice is how many bits per entity (integer) and how to display them:
Code:
% cat x.c
#include <stdio.h>
int main() {
                /* hex   ....binary   octal   ...decimal  ASCII */
  char raw[8] = { 0xEB,  0b00000001,    000,  4, 0, 0, 0,   '@' };
  return 8 == fwrite(raw, 1, 8, stdout) ? 0 : -1;
}
%
%
% gcc -o x x.c
%
%
% ./x | od -a -b -to1 -tu1 -td1 -tx1
0000000    k  soh  nul  eot  nul  nul  nul    @   ;;; -a display as ASCII characters, with special codes (soh, nul, eot) for non-printable chars
         353  001  000  004  000  000  000  100   ;;; -b display as bytes, using octal
         353  001  000  004  000  000  000  100   ;;; -to1 display as octal 1-byte integers (equivalent to -b above)
         235    1    0    4    0    0    0   64   ;;; -tu1 display as decimal 1-byte unsigned integers
         -21    1    0    4    0    0    0   64   ;;; -td1 display as decimal 1-byte signed integers (0xEB becomes -21 decimal (=256 - 0xEB = 256 - 225)
          eb   01   00   04   00   00   00   40   ;;; -tx1 display as hexadecimal 1-byte integers using lowercase a-f
0000010
%
 
If you look at my Post #7, you will see that I suggested exacty that, but without the need for a separate 1-character string and a CONCAT operation, because you can overwrite the 'DecimalValue' directly into the eighth element, i.e. into .DATA[7], of the string you are constructing, and then assign a value of 8 to that string's .LEN attribute (or start with a constant string length of 8 by starting with '$EB$01$00$04$00$00$00$00' i.e. a length of 0 in the eighth character holding the position that will be replaced by the actual length when the rest of the string is known).

Again, your tag named "DecimalValue" is not a decimal value, it is a binary Double-word (32-bit) INTeger i.e. DINT. And your tag named "HexString" is not string of hexadecimal characters with dollar signs, it is a compound object comprising
  • a length (.LEN), and
  • a sequence (array .DATA[]) of binary Single-byte (8-bit) INTegers i.e. SINTs,
that is interpreted, and displayed, as a string of ASCII characters. For display in Studio 5000 IDE only, those integers are displayed as
  • EITHER as the corresponding ASCII character for integers represeting printable characters (space, !, ... 0, 1, 2, ..., @, A, B, C, etc.),
  • OR as the '$xx' (dollar-plus-two-hexadecimal-digits) convention, for non-printable
    • which displays three characters to represent only, and exactly, one element of the string's array of SINTs (.DATA).
To illustrate my point, try entering a string-to-print length (not the .LEN) of 64 (hexadecimal 0x40 in C or '$40' in Studio 5000 IDE). When the Studio 5000 IDE displays that string, it will display '$EB$01$00$04$00$00$00@' not ''$EB$01$00$04$00$00$00$40'

So in the end it is no more complicated than C.

Ok, I missed that in the messages. Thanks.
 

Similar Topics

Hi Everyone, I am facing an issue while installing the STUDIO 5000 in my windows 10 PC. During installation I am getting an error that " Error...
Replies
1
Views
30
I am connecting to a remote device. When attempting to upload I receive an error that states: Error: Auto_Functions: The Import was aborted due...
Replies
3
Views
137
I recently did a program conversion from logix 500 to studio 5000 and when machine runs it depends on two ton instructions to keep the machine in...
Replies
17
Views
512
Hi Everyone. Not posted on here for a long time, but I am hoping someone can help me. I am doing a differential pressure calculation in a L27ERM...
Replies
16
Views
399
Back
Top Bottom