今回は少しプログラムの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 (*を@に)