0
0

データのByte配列の中身をPLCと各言語で比較する。

Last updated at Posted at 2023-09-27

はじめに

ソケット通信を行うときは、データをByte配列によるバッファに変換してサーバに送信します。そして、受信したデータもByte配列を文字列や実数等に変換して、クライアント側で処理します。

「データをByte配列にする」ということはいったい何?という疑問もささやかれると思いますが、簡単に言えば、データを16進数にまとめているといえばわかりやすいかと思います。

パソコンとPLCの間で上位リンク通信を行う上では、その中身を知ることが非常に重要だったりしますので、PLCと各言語でどのように変換されるのか確認したいと思います。
結論から言えば、PLCでもプログラミング言語でも結果は同じとなりますが、その変換のコードも書き方も本投稿で学習のきっかけとなれば幸いです。

PLCの場合

試しに-35,256,852という数字をPLCであらわしてみましょう。
CR2002とMOV.Lコマンドでこの数字をDM0に転送します。

image.png

その結果を登録モニタで32bit16進数で確認すると下図のようになると思います。

image.png

これは単純にこの数字が16進数として表記された結果ですが、DM0にどのようにデータが格納されたかを細かく分析するとこのようになります。
つまり、"05"と"EC"が下位レジスタであるDM0、"FD"と"E6"が上位レジスタであるDM1に格納されているということになります。
つまり、32bit符号付き整数が4つのByte配列になって、PLC内のレジスタに格納されているということになります。1つのByteで8bitですから、4バイトで32bitということになります。

image.png

Pythonの場合

Pythonで同じ数字を変数に代入して、Byte配列にしたらどうなるか、見てみましょう。コードは下記のとおりです。
valueという変数に整数を格納し、to_bytesメソッドでByte配列に変換します。その引数は配列数が4で、変換はリトルエンディアン、符号付きという意味になります。
※リトルエンディアンについては割愛いたします。

結果は0xfdという風に出てきますが、PLCとの比較で分かりやすくするために0xの表記を削除し、upper()メソッドで大文字に変換します。

value = -35256852

buf = [hex(x).replace('0x','').upper()
       for x in value.to_bytes(4, 'little', signed=True)]
str = buf[3]+', '
str += buf[2]+', '
str += buf[1]+', '
str += buf[0]

print('変換結果: ' + str)

実行結果:
image.png

結果としてはPLCで出力された結果と一致しています。
当然といえば当然のことですが、データがByte配列にどのようにPLCまたはパソコンンのメモリに格納されているかを知ることで、この先のPLC上位リンク通信でさまざま役に立つ場面が出てくると思います。

C#の場合

C#の場合もコードと結果を記載しておきます。
ToString("X")で数字を16進数の大文字表記にしております。

internal class Program
{
    private static void Main(string[] args)
    {
        int value = -35256852;

        var buf = BitConverter.GetBytes(value)
                    .Select(x => x.ToString("X")).ToArray();

        Console.WriteLine($"実行結果: {buf[3]}, {buf[2]}, {buf[1]}, {buf[0]}");

    }
}

実行結果

image.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0