Beckhoff#TwinCAT3 Bytes配列和變數轉換方法

今次我會寫1些關於program的knowhow。其實也不算是甚麼了不起的事,例如我們的在和其他裝置通信的時侯很多時侯都會用byte配列作為data傳送的buffer,最後會用人手作mapping。例如頭4個byte是小數,之後2byte是整數。

首先我們試試想一下將最初的4bytes轉換成小數。

在google有很多的web有hex轉變器,例如今次我用的時這個↓

https://gregstoll.com/~gregstoll/floattohex/

3.41242=0x405a6517

我們要小心byte的順序是samll還是big;這樣會影響byte排列的次序。

方法1-UNION構造體

利用UNION 可簡單地處理這種問題。union是一種data type是data type內每1個變數都持有同一樣的memory offset。那就算儘管變數是不同,但每個變數都有同樣的memory offset。用文字說明很難明白,我會用例子向大家說明一下。

説明

首先DUT>ADD>DUT新增1個dut。

然後選最下面的union,open。

首先我們再定義另1個dut,是由8個bit data組成。

TYPE DUT_8Bits :
STRUCT
    bBit1  : BIT;
    bBit2  : BIT;
    bBit3  : BIT;
    bBit4  : BIT;
    bBit5  : BIT;
    bBit6  : BIT;
    bBit7  : BIT;
    bBit8  : BIT;    
END_STRUCT

END_TYPE

然後我們追加1個union dut,名為uDUT_16Bits。

大家都從下面的例子看見,example多了1個UNION的預約語。

然後我們同時定義了3個變數,iValue,bBytes,arrBool。

因為這個dut是union,iValue=bBytes=arrBool。

TYPE uDUT_16Bits :
UNION
iValues :UINT;
bBytes :ARRAY[0..1] OF BYTE;
arrBool :ARRAY[0..1] OF DUT_8Bits;
END_UNION
END_TYPE


PROGRAM MAIN_UNION_SAMPLE
VAR
u:uDUT_16Bits;
END_VAR

現在我們做1點測試,iValues=0。同時見到arrBool和bBytes的現在值都是0。

iValues=1的時侯,arrBool[0].bBit1變成True,bBytes[0]的值也變成1。

所有的變數值也是一致。

今次將bBytes[0]=255,bBytes[1]=3,大家也看到其他變數也有同樣的轉變。

Example

那我們就再寫1點程式。

定義1個union的dut,入面為4bytes的array,另1個變數是小數=4Bytes。

DUT

TYPE DUT_Bytes2LReal :
UNION
arrBytes :ARRAY[0..3] OF BYTE;
rReal :REAL;

END_UNION
END_TYPE

VAR

PROGRAM MAIN_UsingUNION

VAR

rMyRealValue :REAL;

data :Dut_Bytes2LReal;

cLSB :BOOL:=TRUE;

END_VAR

Code

IF NOT cLSB THEN
data.arrBytes[0]:=16#40;
data.arrBytes[1]:=16#5A;
data.arrBytes[2]:=16#65;
data.arrBytes[3]:=16#17;
ELSE
data.arrBytes[0]:=16#17;
data.arrBytes[1]:=16#65;
data.arrBytes[2]:=16#5A;
data.arrBytes[3]:=16#40;

END_IF

rMyRealValue:=data.rReal;

結果

4Bytes的配列轉換成32bit小數。

方法2-使用Pointer

第2個方法是利用ADR將byte array的memory address offset,然後定義1個pointer,最後用^將byte array作為1個小數去讀取。我們會見到在beckhoff的function,functon blocks都見到有很好多時侯見到這個引數。

Example

VAR

PROGRAM MAIN_UsingPointer
VAR

rMyRealValue:REAL;
arrBytes :ARRAY[0..3] OF BYTE;
cLSB :BOOL:=TRUE;
pReal :POINTER TO REAL;

END_VAR

Code

IF NOT cLSB THEN
arrBytes[0]:=16#40;
arrBytes[1]:=16#5A;
arrBytes[2]:=16#65;
arrBytes[3]:=16#17;
ELSE
arrBytes[0]:=16#17;
arrBytes[1]:=16#65;
arrBytes[2]:=16#5A;
arrBytes[3]:=16#40;

END_IF

pReal:=ADR(arrBytes);

rMyRealValue:=pReal^ ;

結果

同樣地,4Bytes的配列轉換成32bit小數。

Sample Code:

https://github.com/soup01Threes/TwinCAT3/blob/main/TwinCAT%20Project_ConvertBytesArray2Real.tnzip

Twitter:@3threes2

email:soup01threes*gmail.com (*>@)

Footer_Basic

Please Support some devices for my blog

Amazon Gift List

Find ME

Twitter:@3threes2
Email:soup01threes*gmail.com (* to @)
YoutubeChannel:https://www.youtube.com/channel/UCQ3CHGAIXZAbeOC_9mjQiWQ

シェアする

  • このエントリーをはてなブックマークに追加

フォローする