Forming the String in SCL

Piroman

Member
Join Date
Apr 2011
Location
Poltava
Posts
6
Hello all,

my task is to send an array of ASCII codes through VIPA CP341.
The device which I want to connect uses its own framing like this:

7wD9FAQEAOw==
attachment.php


The current problem is that I need to take a byte variable (b#16#02 for example) and transfer it to ASCII code like "30 32" (that means divide byte for two chars) but SCL don't have anything like BYTE_TO_STRING (similar to INT_TO_STRING) for that purpose. =(
Do I need to write my own block with comparison table or there some other way to form a string from a different parts?
Also the reverse operation is needed for reply encoding.
Will be grateful for any help!

Framing.gif
 
Example code to form the first part of your message frame:

Code:
FUNCTION_BLOCK FB481
VAR
 cData: ARRAY[1..6] OF CHAR;
 sData AT cData: STRING[4];
  Frame:STRUCT
    Start:CHAR;
    Slaveaddress1:CHAR;
    SlaveAddress2:CHAR;
    MasterAddress1:CHAR;
    Masteraddress2:CHAR;
    Command:CHAR;
    MemoryAddress1:CHAR;
    MemoryAddress2:CHAR;
    MemoryAddress3:CHAR;
    MemoryAddress4:CHAR;  
    MessageLength1:CHAR;
    MessageLength2:CHAR;
    CRC1:CHAR;
    CRC2:CHAR;
    END:CHAR;
    END_STRUCT;
END_VAR
VAR_TEMP
 iNibble:INT;
 iSlaveAddress:INT;
 wSlaveAddress AT iSlaveAddress:WORD;
 wNibble AT iNibble:WORD;
 iMasterAddress:INT;
 wMasterAddress AT iMasterAddress:WORD;
 bySlaveAddress AT islaveAddress:ARRAY[1..2] OF BYTE;
 byChar:BYTE;
 cChar AT byChar:CHAR;
END_VAR
BEGIN
byChar:=16#3A;
Frame.Start:=cChar;

iSlaveAddress:=2;
wNibble:=wSlaveAddress AND 16#0f;
sData:=int_to_string(iNibble);
Frame.SlaveAddress2:=cData[4];
wNibble:=SHR (IN:=wSlaveAddress, N:=4);
sData:=int_to_string(iNibble);
Frame.SlaveAddress1:=cData[4];
iMasterAddress:=16#91;
wNibble:=wMasterAddress AND 16#0f;
sData:=int_to_string(iNibble);
Frame.MasterAddress2:=cData[4];
wNibble:=SHR (IN:=wMasterAddress, N:=4);
sData:=int_to_string(iNibble);
Frame.MasterAddress1:=cData[4];
    
END_FUNCTION_BLOCK
 
Peter Nachtwey, I'm using a similar method including corrections for upper/lower case etc.

L D[AR2,P#0.0]
, I'm using "AT" construct in message forming too. But your Nibble-way code (as it is posted) not work for nibbles after "9" like a,b,c,d,e,f.

Thanks all of you for your advises. Now I see the direction of further work. I thought that there is a simple integrated solution for such a widespread task :rolleyes:

Here is my code for BYTE_TO_CHARS FC:

Code:
FUNCTION FC201 : VOID

VAR_INPUT
    IN_BYTE     : BYTE;
    CAPS        : BOOL; // 1 - use 4x ASCII group / 0 - use 6x ASCII group
END_VAR

VAR_OUTPUT
    OUT_CHAR_L  : CHAR;
    OUT_CHAR_H  : CHAR;
END_VAR

VAR_TEMP
    Temp_byte_L : BYTE;
    Temp_byte_H : BYTE;
END_VAR

Temp_byte_L := IN_BYTE AND b#16#0f;
Temp_byte_H := INT_TO_BYTE(BYTE_TO_INT(IN_BYTE) / 16);

IF BYTE_TO_INT(Temp_byte_L) > 9
THEN OUT_CHAR_L := INT_TO_CHAR(BYTE_TO_INT(Temp_byte_L) + 87 - 32 * BOOL_TO_INT(CAPS));
ELSE OUT_CHAR_L := INT_TO_CHAR(BYTE_TO_INT(Temp_byte_L) + 48); END_IF;

IF BYTE_TO_INT(Temp_byte_H) > 9
THEN OUT_CHAR_H := INT_TO_CHAR(BYTE_TO_INT(Temp_byte_H) + 87 - 32 * BOOL_TO_INT(CAPS));
ELSE OUT_CHAR_H := INT_TO_CHAR(BYTE_TO_INT(Temp_byte_H) + 48); END_IF;

END_FUNCTION
and CHARS_TO_BYTE FC:

Code:
FUNCTION FC202 : VOID

VAR_INPUT
    IN_CHAR_L   : CHAR;
    IN_CHAR_H   : CHAR;
END_VAR

VAR_OUTPUT
    OUT_BYTE    : BYTE;
    CHAR_L_CAPS : BOOL; // 1 - incoming "low" char in uppercase 
    CHAR_H_CAPS : BOOL; // 1 - incoming "high" char in uppercase
END_VAR

VAR_TEMP
    Temp_byte_L : BYTE;
    Temp_byte_H : BYTE;
END_VAR

CASE CHAR_TO_INT(IN_CHAR_L) OF
    48..57: Temp_byte_L := INT_TO_BYTE(CHAR_TO_INT(IN_CHAR_L) - 48);
    65..70: Temp_byte_L := INT_TO_BYTE(CHAR_TO_INT(IN_CHAR_L) - 55); CHAR_L_CAPS := true;
   97..102: Temp_byte_L := INT_TO_BYTE(CHAR_TO_INT(IN_CHAR_L) - 87); CHAR_L_CAPS := false;
ELSE: Temp_byte_L := b#16#00;
END_CASE;

CASE CHAR_TO_INT(IN_CHAR_H) OF
    48..57: Temp_byte_H := INT_TO_BYTE(CHAR_TO_INT(IN_CHAR_H) - 48);
    65..70: Temp_byte_H := INT_TO_BYTE(CHAR_TO_INT(IN_CHAR_H) - 55); CHAR_H_CAPS := true;
   97..102: Temp_byte_H := INT_TO_BYTE(CHAR_TO_INT(IN_CHAR_H) - 87); CHAR_H_CAPS := false;
ELSE: Temp_byte_H := b#16#00;
END_CASE;

OUT_BYTE := INT_TO_BYTE(BYTE_TO_INT(Temp_byte_H AND b#16#0f) * 16) OR (Temp_byte_L AND b#16#0f);

END_FUNCTION

Upper/lower case characters in messages means master or slave broadcast. Code for full message generation I'll post later when check it on the target device.
I will be grateful for your criticism of my code. :nodi:
 

L D[AR2,P#0.0]
, I'm using "AT" construct in message forming too. But your Nibble-way code (as it is posted) not work for nibbles after "9" like a,b,c,d,e,f.

Quite right, I overlooked that as I was blinkered due to using int_to_string :)
 

Similar Topics

Kindly, we have one Kinetix drive in stock, sitting since three years. Can we directly install and run it on the machine? Or it needs some...
Replies
5
Views
2,565
There is a very old manually operating hydraulic forming press in our production. At the moment it's out of operation due to some issues with the...
Replies
17
Views
6,112
i want a pdf to how communication data transfer between s7_300 and indradrive via profibus communication
Replies
0
Views
1,611
Hey guys, I know this is not PLC related but many of you are pretty crafty. I need to resurrect an old PowerFlex 700 VFD. AB calls for reform...
Replies
4
Views
2,318
I came across some information concerning reforming of capacitors in VFD's that have been stored for more than 2 years. We have quite of few that...
Replies
8
Views
2,377
Back
Top Bottom