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に設定する.
シグナルの赤,黄,緑に対応.
というわけで,レジスターの中身のまとめが必要そうです.
次は,そこに取り組みます.
コメントを残す