Beckhoff#TwinCAT3 Bytes配列から変数に変換

今回は少しプログラムのKnow-howを話しします。わかれば大したことやってないです。通信するときによくByte配列でデータをやりとりし、最後は自分の力最初の4Byte目は実数、次の2Byteは整数…などです。まずは4Byteの配列を実数に変換すると考えてしましょう。

以下のサイドで32Bitの実数をHexに変換することができます↓

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

3.41242=0x405a6517になります。

注意するのはByteの順番はSmallやBigにより変わります。

方法1-UNION構造体

UNIONは様々なデータ・タイプの変数を持つ構造体です。ですが、Union内のすべての変数は同じのMemoryのOffsetが持っています。つまり違う変数だが、同じのメモリアドレスになっています。説明するのは難しいので実例を見てみましょう。

説明

DUT>Add>DUTします。

一番したにUnionを選択し作成します。

その前にまずDUT_8Bitsというデータタイプがあります。

中にbBit1…のようなBIT変数が8個が含まれています。こちらはまだUNIONの構造体ではなく、普通の構造体ですね。

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

END_TYPE

次はuDUT_16Bitsを定義しました。

みんなさんもわかりと思いますが、普通のDUTよりUNIONのKeywordがありますね。

その中で、3つの変数があります。が、3つの変数も同じのアドレスです。

つまり、iValues=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

実際変数定義し実験してみますね。いまiValues=0になりますと、arrBoolとbBytesにも0ですね。

iValues=1なると、arrBool[0].bBit1もTrueになり、bBytes[0]にも1になります。

値は一致していますね。

次はbBytes[0]=255,bBytes[1]=3になると、他の変数にも反映します。

Example

では実際をやってみましょう。

UNIONのDUT定義し、4BytesのarrBytes配列とrRealの実数を定義します。REALは32Bitなので=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の配列はちゃんと実数に変換できますね。

方法2-Pointerを使う

Byte配列のMemory AddressをADRから読み出し、Pointerの変数を宣言し、最後は^でByte配列を実数として読み込みます。こっちらの方法はBeckhoffのFunction 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の配列はちゃんと実数に変換できますね。

こちらはSample Codeです:

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

はーい、お疲れ様です。

もしなにか質問あれば、メール・コメント・Twitterなどでもどうぞ!

Twitterのご相談:@3threes2

メールのご相談:soup01threes*gmail.com (*を@に)

Footer_Basic

Find ME

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

シェアする

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

フォローする