Modbus レジスタデコーダのしくみ
Modbus はデータを 16 ビットのレジスタで運び、各レジスタは上位バイトから送られます。プロトコルが決めているのはそこまでです。32 ビット浮動小数点で送る温度や 64 ビット整数で送る電力量カウンタは 2 個または 4 個のレジスタにまたがり、その並び順は機器メーカーが決めます。多くの機器は上位レジスタを先に送りますが、下位レジスタを先に送るものや、各レジスタ内の 2 バイトまで入れ替えるものもあります。
このデコーダは、マスター、ゲートウェイ、テストツールに表示されたとおりのレジスタを受け取り、4 通りの順序で同時に変換します。順序は値のバイトを表す文字で書きます(A が最上位)。ABCD はビッグエンディアン、CDAB はよくあるワードスワップ、BADC は各レジスタ内のバイトを入れ替えたもの、DCBA は完全なリトルエンディアンです。
正しいバイト順を見つける
機器がおおよそ何を示すはずかわかっている状態でレジスタを 1 組読み、意味の通る行を探します。レジスタ 0x4120 0x0000 は ABCD で 10.0 です。CDAB で読むと 2.3 × 10⁻⁴¹ となり、どのセンサも示さない値なので、デコーダはこうした行を薄く表示します。機器が下位レジスタを先に送る場合は 0x0000 0x4120 と表示され、CDAB の行に 10 が出ます。
1 つの値で順序がわかれば、同じ機器・同じデータ型のすべての値で同じです。PLC のプログラムでバイトを入れ替えるのではなく、マスターの設定に書き込んでください。
スケーリングとデータ型
多くの機器は暗黙のスケールを持つ整数を送ります。12.34 bar を意味する 1234 の圧力や、0.1 度単位の温度などです。レジスタマップにあるスケール係数とオフセットを入力すると、生値の横に工学値が表示されます。値は 生値 × スケール係数 + オフセット です。書き込む値をエンコードするときは同じ係数を逆に使います。
INT16 と UINT16 の違いは最上位ビットの読み方だけで、0xFFFF は符号なしで 65535、符号付きで −1 です。ほとんどのレジスタマップはアドレスごとに型を示しています。示されていない場合、負にならないはずの値はたいてい符号なしです。
レジスタ番号とアドレス
機器のマニュアルでは、レジスタが 40001、30001、400001 のように書かれていることがよくあります。これは Modicon の慣例で、先頭桁がテーブル(4 は保持レジスタ、3 は入力レジスタ、0 はコイル、1 はディスクリート入力)を、残りが 1 から数えた番号を表します。回線上の要求には 0 から数えたアドレスが入るので、40001 は保持レジスタのアドレス 0 で、ファンクションコード 03 で読みます。参照番号を入力すると、プロトコルアドレス、ファンクションコード、複数レジスタの値が占めるレジスタがわかります。
ここで 1 ずれることが、もっともらしいのに間違った値になるいちばん多い原因です。マスターがある値の後半と次の値の前半を読んでしまいます。
よくある質問
一部の行に NaN が表示されるのはなぜですか?
指数ビットがすべて 1 の浮動小数点は、数値ではない(NaN)か無限大です。バイト順の誤りでこのパターンになることがよくありますが、センサ異常を意図的に NaN で知らせる機器もあります。後者の場合は機器のマニュアルを確認してください。
レジスタを 1 つの 16 進文字列で入力できますか?
できます。スペースなしの 8 桁または 16 桁の 16 進数は 4 桁ずつのレジスタに分けられ、41200000 は 0x4120 0x0000 として読まれます。
Modbus TCP の場合は?
レジスタの並びは TCP でも RTU でも同じで、違うのはフレームだけです。複数レジスタの値のバイト順は伝送路ではなく機器で決まります。