Dummy MPS(MEMO 3)

llsf-refbox/src/libs/llsf_sps の中身を見ても,modbus に関する設定がほとんど見つかりません….
関連しそうなのは,以下の4つの関数のみ….

  • modbus_new_tcp
  • modbus_read_registers
  • modbus_read_input_registers
  • modbus_write_registers

mps.h の中には,

//#define MODBUS_TCP_SLAVE 0x04

てのがありますが,
コメントアウトされています.
これのMASTER みたいなのが設定できたらいいのになぁ.

とりあえず,実機で動作確認してみます.
llsf-refbox/cfg/config.yaml のmps の部分を書き換えます.

  mps:
    enable: true
    # type: 1(incoming station), 2(singel p&p), 3(double p&p), 4(delivery station)
    stations:
      C-BS:
        active: true
        type: BS
        # host: !ipv4 192.168.2.27
        host: !ipv4 192.168.4.163
        port: !tcp-port 502

host は,自分の環境に変えてください.

受信側は,firewall の解除が必要です.
Fedora の場合は,

sudo firewall-cmd --add-port=502/tcp --zone=public --permanent
sudo firewall-cmd --reload
sudo firewall-cmd --list-all

です.

おそらく,MPS 側がMASTER で,RefBox がSLAVEとして,host につなぎに行くはずです.
というわけで,Raspberry Pi(MPS)側でtcpdump を立ち上げ,ノートパソコン上でRefBox を立ち上げてみると….

[pi@pi3Bp1 ~]$ sudo tcpdump -vvv -i wlan0 port 502 -X -s 512 -B 512
tcpdump: listening on wlan0, link-type EN10MB (Ethernet), capture size 512 bytes
16:00:12.917030 IP (tos 0x10, ttl 64, id 3060, offset 0, flags [DF], proto TCP (6), length 60)
    192.168.4.156.45886 > pi.mbap: Flags [S], cksum 0x2172 (correct), seq 3277209057, win 29200, options [mss 1460,sackOK,TS val 313680079 ecr 0,nop,wscale 7], length 0
	0x0000:  4510 003c 0bf4 4000 4006 a428 c0a8 049c  E..<..@.@..(....
	0x0010:  c0a8 04a3 b33e 01f6 c356 3de1 0000 0000  .....>...V=.....
	0x0020:  a002 7210 2172 0000 0204 05b4 0402 080a  ..r.!r..........
	0x0030:  12b2 60cf 0000 0000 0103 0307            ..`.........
16:00:12.917269 IP (tos 0x10, ttl 64, id 26614, offset 0, flags [DF], proto TCP (6), length 40)
    pi.mbap > 192.168.4.156.45886: Flags [R.], cksum 0x6ed3 (correct), seq 0, ack 3277209058, win 0, length 0
	0x0000:  4510 0028 67f6 4000 4006 483a c0a8 04a3  E..(g.@.@.H:....
	0x0010:  c0a8 049c 01f6 b33e 0000 0000 c356 3de2  .......>.....V=.
	0x0020:  5014 0000 6ed3 0000                      P...n...

というわけで,RefBox から,初期化の命令が飛んでいる感じです.

よくよく考えたらmodbus のパケットではなく,TCP としてのキャプチャーですので,TCPのヘッダも付いてますね.

3c → 6010 byte = Length
c0a8 04a3 → 192.168.4.163 (Raspberry pi),
c0a8 049c → 192.168.4.156 (Laptop PC),
01f6 → 502 (port)
このあたりは,TCP の情報です.

ただ,このままだと初期化のパケットで止まってしまいます.
TCP ですので,ACK を返さないといけません.

とりあえず,パケット受信のプログラムを作ってみました.
C言語で学ぶソケットAPI入門 第3回 サーバ/クライアント編 #1です.

受信後(recv後)に,以下を追記.

            for(int i = 0; i < recvMsgSize; i++)
                    printf("%02x:", recvBuffer[i]);
            printf("\n");

これで,RefBox から接続パケットとシグナル制御パケットが飛んできます.

00:01:00:00:00:09:ff:10:00:0a:00:01:02:00:01:

Preset Multiple Registers です.
10番地からの1つのレジスターの値を,1に設定する.

f2:1e:00:00:00:06:ff:04:00:03:00:01:

最初の2byte は,トランザクション識別子.
次の2byte は,プロトコル識別子(0).
その次の2byte は,フィールド長.今回は6byte.
その次の2byte は,ユニット識別子.0xFF.
その次の1byte は,ファンクションコード.
今回は,04.Read Input Register.3番地から1つのレジスターの値を要求しています.
とすると,レスポンスが必要ですね.
シグナルの赤の状態を返す形です.
→ 故障検知を行っているっぽいです.

42:7d:00:00:00:0d:ff:10:00:03:00:03:06:00:00:00:01:00:00:

3番地からの3つのレジスターの値を,0,1,0に設定する.
シグナルの赤,黄,緑に対応.

というわけで,レジスターの中身のまとめが必要そうです.
次は,そこに取り組みます.

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

*