How do I convert string to array of bytes?

2008-06-14
2010-04-09
  • norm.boessler - 2008-06-14

    I want to send strings to the rs232 which needs to be 1 byte at a time.

    The CoDeSys RS232 tutorial is missing the function code which would show me this so any assistance would be great.

    Essentially I imagine something like:

    s string;

    b byte;

    for i := 1 to len(s) do

    b := string_to_byte(mid(s,1,i));

    SendChar(b);

    end_for;

    I get error with the conversion from string to byte in this example.

    Or perhaps a string converted to array of bytes and then iterate through the index to send each byte.

     
  • hugo - 2008-06-14

    you can find examples for this code in the open source library OSCAT.LIB

    to be downloaded from w www.oscat.de w

    pls look at the modules buffer_to_string and string_to_buffer

     
  • norm.boessler - 2008-06-16

    Thanks Hugo. Is good.

    For anyone else interested, below is what I did minus full error handling.

    My function is arbitrarily set to handle up to 80 characters.

    Calling function:

    FUNCTION F_SEND_TEXT_RS232 : BOOL

    VAR_INPUT

    sText : STRING(80);

    END_VAR

    VAR

    i : INT;

    SendData: FB_PUT_RS232_CHAR;

    fbGetRS232TxBufCount : FB_GET_RS232_TX_BUF_COUNT;

    abText : ARRAY[0..80] OF BYTE;

    iLength : INT;

    END_VAR

    F_STRING_TO_BYTE_ARRAY(sText,0,ADR(abText),SIZEOF(abText));

    FOR i := 0 TO LEN(sText) DO

      REPEAT
    
        fbGetRS232TxBufCount();
    
      UNTIL
    
        fbGetRS232TxBufCount.Status = C_NO_ERR
    
      END_REPEAT;
    
        SendData(bByte := abText[i]);
    

    END_FOR;

    F_SEND_TEXT_RS232 := TRUE;

    Implementation of string to byte array:

    FUNCTION F_STRING_TO_BYTE_ARRAY : BOOL

    ( Usage: F_STRING_TO_BYTE_ARRAY(str, pos, adr("array"),sizeof("array")); )

    VAR_INPUT

    str : STRING(80);
    
    pos : INT;
    
    pt : POINTER TO ARRAY[0..79] OF BYTE;
    
    size : UINT;
    

    END_VAR

    VAR

    ps : POINTER TO BYTE;
    
    i: INT;
    
    end: INT;
    

    END_VAR

    ps := ADR(str);

    end := MIN(pos + LEN(str) - 1,UINT_TO_INT(size));

    FOR i := pos TO end DO

    pt^[i] := ps^;
    
    ps := ps + 1;
    

    END_FOR;

    F_STRING_TO_BYTE_ARRAY := TRUE;

     
  • Igor Petrov - 2008-06-30

    Another one simple method is to declare the 'string' and the 'byte array' on the same direct address in 'M' memory.

     
  • norm.boessler - 2008-07-01

    Igor, could you give an example for this. Would be greatly appreciated.

    Norm.

     
  • robkristiaan - 2008-07-04

    there is a simple solution to you're problem

    declare a pointer byte array with the same size as you're string

    byByte:BYTE;

    sString:STRING(8 ); (a normal string has a size of 80 chars)

    abyByte: pointer to POINTER TO ARRAY[0..7] OF BYTE;

    abyByte:=ADR(sString); (if lengths do not match you can get real weird problems)

    byByte:=abyByte^[i];

     
  • ndzied1 - 2008-07-11

    norm.boessler hat geschrieben:
    Igor, could you give an example for this. Would be greatly appreciated.
    Norm.

    I have made a little sample showing how the addressing overlap works. It includes a visualization for demonstration. Once you unzip it, you should be able to import it into a new project and run it in simulation mode.

    When you define variables that overlap in the marker address area, in this example a string and an array of bytes, it is like a union in C. You can put a string into the string variable and then each character can be pulled out from the overlapping byte array.

    In the program, I only access MyString but as soon as you copy a string into the MyString variable, the bytes of it are immediately available in the MyBArray array.

    Here is the Text if you can't import the attached file.

    VAR_GLOBAL
    (*  Declare the string and byte array at the same location in marker memory  *)
    (* In practice, this may be in a global variable file for access by other rouines *)
       MyString   AT %MW0:      STRING(80);
       MyBArray   AT %MW0:      ARRAY [0..79] OF BYTE;
    END_VAR
    PROGRAM PLC_PRG
    VAR
       Init:            BOOL := TRUE;
       MyBool:      BOOL;
       MyBoolOS:      R_TRIG;
       MyInt:         INT:=0;
       MyList:       ARRAY [0..4] OF  STRING(80) :=
          'One String', 'Two String', 'Three String', 'Four String', 'Five String';
    END_VAR
    IF Init THEN
       MyString   := MyList[MyInt];
       MyInt      := MyInt + 1;
       Init         := FALSE;
    END_IF
    MyBoolOS(CLK:=MyBool );
    IF MyBoolOS.Q THEN
       MyString   := MyList[MyInt];
       MyInt      := MyInt + 1;
       IF MyInt >4 THEN MyInt := 0; END_IF
    END_IF
    

    OVERLAP.zip [1.22 KiB]

     
  • norm.boessler - 2008-07-23

    Great examples. I've learned much from this. Thanks to all who helped!

     
  • Anonymous - 2010-03-03

    Originally created by: HASAN SERKAN DURMU&#3

    Norm,

    Can you please share lib that you used for coding your rs232 sample program since my sample program giveS an error which has mentioned about unknown type FB_PUT_RS232_CHAR and unknown type FB_GET_RS232_TX_BUF_COUNT.

    i am looking forward your response,

    Best Wishes,

     
  • Andreaz - 2010-04-09

    You can also use a pointer for this, similar to the M solution above but without the need to know the M address of the source string.

    PROGRAM PLC_PRG
    VAR
       Text : STRING;
       Index: INT;
       Char : POINTER TO BYTE;
    END_VAR
    Text:= 'Hello world!';
    Char:= ADR(Text);
    FOR Index:=0 TO LEN(Text) DO
       Send(Char^);
       (* Goto the next character *)
       Char:= Char + 1;
    END_FOR;
    
     

Log in to post a comment.