Node-Red Modbus FC=6 , 16 , 3
參考來源 https://stevesnoderedguide.com/node-red-modbus
Write 16 bits / 32 bit Integer value To ModBus Server
Modbus 部分功能碼
代 碼
|
中文名稱
|
寄存器 PLC 位址
|
位操作/字操作
|
運算元量
|
01
|
讀 數字量輸出
|
00001-09999
|
位操作
|
單個或多個
|
02
|
讀 數字量輸入
|
10001 -19999
|
位操作
|
單個或多個
|
03
|
讀 模擬量輸出
|
40001-49999
|
字操作
|
單個或多個
|
04
|
讀 模擬量輸入
|
30001-39999
|
字操作
|
單個或多個
|
|
|
|
|
|
05
|
寫 單個數位量輸出
|
00001-09999
|
位操作
|
單個
|
06
|
寫 單個模擬量輸出
|
40001-49999
|
字操作
|
單個
|
15
|
寫 多個數位量輸出
|
00001-09999
|
位操作
|
多個
|
16
|
寫 多個模擬量輸出
|
40001-49999
|
字操作
|
多個
|
Function
|
內容
|
備註
|
Write 16001-16bit
|
var fc=6;
var
sa=40;
var
addresses=1;
var
value=16001;
//msg.slave_ip="192.168.1.76";
msg.slave_ip="127.0.0.1";
msg.payload={"value":value
, 'fc': fc, 'unitid': 1, 'address': sa , 'quantity': addresses };
return
msg;
|
|
write int 68001-32 bit
|
var
fc=16;
var sa=50;
var addresses=2;
var buf=Buffer.alloc(4);
//We then write the integer (68001) into
this buffer.
//For multiple resisters the node expects
16 bit decimal values
//for each register and so we need to
split our buffer into 2 parts.
//We then create an array of the form
[value1,value2].
//Notice value1 is the low order 2 buffers
(0,1),
//and value 2 is the higher order buffers
(2,3).
//Notice also we need to multiple the
buffers 1 and 2 by 256.
buf.writeInt32BE(68001);
var values=[(buf[0]*256+buf[1]),(buf[2]*256)+buf[3]]
//msg.slave_ip="192.168.1.76";
msg.slave_ip="127.0.0.1";
msg.payload={"value":values ,
'fc': fc, 'unitid': 1, 'address': sa , 'quantity': addresses };
return msg;
|
|
Read
16 Bit INT 16001
|
var
fc=3;
var sa=40;
var addresses=1;
var slave_ip=msg.payload.slave_ip;
//msg.slave_ip="192.168.1.31";
msg.slave_ip="127.0.0.1";
msg.payload={value: msg.payload, 'fc': fc,
'unitid': 1, 'address': sa , 'quantity': addresses };
return msg;
|
|
32 Bit INT 68001
|
var
fc=3;
var sa=50;
var addresses=2;
var slave_ip=msg.payload.slave_ip;
//msg.slave_ip="192.168.1.31";
msg.slave_ip="127.0.0.1";
msg.payload={value: msg.payload, 'fc': fc,
'unitid': 1, 'address': sa , 'quantity': addresses };
return msg;
|
|
|
const buf = Buffer.from(msg.payload.buffer);
const
value = buf.readUInt16BE();
msg.value = value;
return msg;
|
|
[{"id":"52801767.987938","type":"modbus-flex-getter","z":"7b56bdd1.53b7b4","name":"local getter","showStatusActivities":true,"showErrors":true,"logIOActivities":false,"server":"54dde46e.53267c","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"keepMsgProperties":false,"x":530,"y":320,"wires":[[],["35d76135.13a9ce"]]},{"id":"88fcd542.cbd938","type":"debug","z":"7b56bdd1.53b7b4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":810,"y":320,"wires":[]},{"id":"d9eaec07.529b8","type":"function","z":"7b56bdd1.53b7b4","name":"16 Bit INT 16001","func":"\nvar fc=3;\nvar sa=40;\nvar addresses=1;\n\n\nvar slave_ip=msg.payload.slave_ip;\n//msg.slave_ip=\"192.168.1.31\";\nmsg.slave_ip=\"127.0.0.1\";\nmsg.payload={value: msg.payload, 'fc': fc, 'unitid': 1, 'address': sa , 'quantity': addresses };\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":350,"y":320,"wires":[["52801767.987938"]]},{"id":"76191a4e.a7fe44","type":"inject","z":"7b56bdd1.53b7b4","name":"Read 16bit Integer","props":[{"p":"payload","v":"","vt":"date"},{"p":"topic","v":"","vt":"string"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":150,"y":320,"wires":[["d9eaec07.529b8"]]},{"id":"35d76135.13a9ce","type":"function","z":"7b56bdd1.53b7b4","name":"","func":"const buf = Buffer.from(msg.payload.buffer);\nconst value = buf.readUInt16BE();\nmsg.value = value;\nreturn msg;","outputs":1,"noerr":0,"x":690,"y":320,"wires":[["88fcd542.cbd938"]]},{"id":"8ef1599a.ef14b8","type":"debug","z":"7b56bdd1.53b7b4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":710,"y":66,"wires":[]},{"id":"b3588a11.4a8588","type":"inject","z":"7b56bdd1.53b7b4","name":"Write32INT","props":[{"p":"payload","v":"","vt":"date"},{"p":"topic","v":"","vt":"string"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":120,"y":140,"wires":[["718d2c98.d836a4"]]},{"id":"718d2c98.d836a4","type":"function","z":"7b56bdd1.53b7b4","name":"write int 68001-32 bit","func":"\nvar fc=16;\nvar sa=50;\nvar addresses=2;\nvar buf=Buffer.alloc(4);\n\n//We then write the integer (68001) into this buffer.\n//For multiple resisters the node expects 16 bit decimal values \n//for each register and so we need to split our buffer into 2 parts.\n//We then create an array of the form [value1,value2].\n//Notice value1 is the low order 2 buffers (0,1), \n//and value 2 is the higher order buffers (2,3). \n//Notice also we need to multiple the buffers 1 and 2 by 256.\n\nbuf.writeInt32BE(68001);\nvar values=[(buf[0]*256+buf[1]),(buf[2]*256)+buf[3]]\n\n//msg.slave_ip=\"192.168.1.76\";\nmsg.slave_ip=\"127.0.0.1\";\nmsg.payload={\"value\":values , 'fc': fc, 'unitid': 1, 'address': sa , 'quantity': addresses };\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":320,"y":140,"wires":[["40811305.6928dc","edaab567.c14fe8"]]},{"id":"40811305.6928dc","type":"modbus-flex-write","z":"7b56bdd1.53b7b4","name":"","showStatusActivities":false,"showErrors":false,"server":"54dde46e.53267c","emptyMsgOnFail":false,"keepMsgProperties":false,"x":550,"y":140,"wires":[[],["b6d33137.938a8"]]},{"id":"5669f2cf.75418c","type":"inject","z":"7b56bdd1.53b7b4","name":"Write16INT","repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":120,"y":60,"wires":[["81253f30.1a85c"]]},{"id":"81253f30.1a85c","type":"function","z":"7b56bdd1.53b7b4","name":"Write 16001-16bit","func":"\nvar fc=6;\nvar sa=40;\nvar addresses=1;\nvar value=16001;\n\n//msg.slave_ip=\"192.168.1.76\";\nmsg.slave_ip=\"127.0.0.1\";\nmsg.payload={\"value\":value , 'fc': fc, 'unitid': 1, 'address': sa , 'quantity': addresses };\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":310,"y":60,"wires":[["df58d810.49a408"]]},{"id":"df58d810.49a408","type":"modbus-flex-write","z":"7b56bdd1.53b7b4","name":"","showStatusActivities":false,"showErrors":true,"server":"54dde46e.53267c","emptyMsgOnFail":false,"keepMsgProperties":false,"x":530,"y":60,"wires":[[],["8ef1599a.ef14b8"]]},{"id":"edaab567.c14fe8","type":"debug","z":"7b56bdd1.53b7b4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":510,"y":200,"wires":[]},{"id":"57936ccb.6a9e84","type":"comment","z":"7b56bdd1.53b7b4","name":"read functionm","info":"read functionm\n function codes 1,2,3 and 4 \n \nFunction Code\tAction\tTable Name\n01\tRead\tDiscrete Output Coils\n02\tRead\tDiscrete Input Contacts\n04\tRead\tAnalogue Input Registers\n03\tRead\tAnalogue Output Holding Registers\n\n\nCoil/Register Numbers\tType\tTable Name\tData Addresses\tData Type\n\n1-9999\tRead-Write\tDiscrete Output Coils\t0000 to 270E\t**Boolean**\n10001-19999\tRead-Only\tDiscrete Input Coils\t0000 to 270E\t**Boolean**\n\n30001-39999\tRead-Only\tAnalogue Input Registers\t0000 to 270E\t**Unsigned Word**\n\n40001-49999\tRead-Write\tAnalogue Output Holding Registers\t0000 to 270E\t**Unsigned Word**","x":120,"y":200,"wires":[]},{"id":"7ae56582.3edcdc","type":"comment","z":"7b56bdd1.53b7b4","name":"write functionm","info":"read functionm\n function codes 5,15,6 and 16 \n \n \nFunction Code\t Action \tTable Name\n05\tWrite single\tDiscrete Output Coil\n15\tWrite multiple\tDiscrete Output Coils\n06\tWrite single\tAnalogue Output Holding Register\n16\tWrite multiple\tAnalogue Output Holding Registers\n\n\n\nCoil/Register Numbers\tType\tTable Name\tData Addresses\tData Type\n\n1-9999\tRead-Write\tDiscrete Output Coils\t0000 to 270E\t**Boolean**\n10001-19999\tRead-Only\tDiscrete Input Coils\t0000 to 270E\t**Boolean**\n\n30001-39999\tRead-Only\tAnalogue Input Registers\t0000 to 270E\t**Unsigned Word**\n\n40001-49999\tRead-Write\tAnalogue Output Holding Registers\t0000 to 270E\t**Unsigned Word**","x":300,"y":200,"wires":[]},{"id":"b6d33137.938a8","type":"debug","z":"7b56bdd1.53b7b4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":710,"y":140,"wires":[]},{"id":"6a95bb4d.dc7dd4","type":"inject","z":"7b56bdd1.53b7b4","name":"Read 32bit Integer","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":150,"y":360,"wires":[["b870a4c8.b41068"]]},{"id":"b870a4c8.b41068","type":"function","z":"7b56bdd1.53b7b4","name":"32 Bit INT 68001","func":"\nvar fc=3;\nvar sa=50;\nvar addresses=2;\n\nvar slave_ip=msg.payload.slave_ip;\n//msg.slave_ip=\"192.168.1.31\";\nmsg.slave_ip=\"127.0.0.1\";\nmsg.payload={value: msg.payload, 'fc': fc, 'unitid': 1, 'address': sa , 'quantity': addresses };\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":350,"y":360,"wires":[["52801767.987938"]]},{"id":"658d0b7b.c4b074","type":"comment","z":"7b56bdd1.53b7b4","name":"映射地址","info":"\n## 代码 中文名称 寄存器 PLC 地址 位操作/字操作 操作数量\n## 01 读数字量输出 00001-09999 位操作 单个或多个\n## 02 读数字量输入 10001-19999 位操作 单个或多个\n## 03 读模拟量输出 40001-49999 字操作 单个或多个\n## 04 读模拟量输入 30001-39999 字操作 单个或多个\n## \n## 05 写单个数字量输出 00001-09999 位操作 单个\n## 06 写单个模拟量输出 40001-49999 字操作 单个\n## 15 写多个数字量输出 00001-09999 位操作 多个\n## 16 写多个模拟量输出 40001-49999 字操作 多个","x":120,"y":260,"wires":[]},{"id":"c0ec7d8a.52667","type":"comment","z":"7b56bdd1.53b7b4","name":"","info":"fc (function code)\n(fc=1 <--> fc 5,15)\nread \n读数字量输出\nfc=1 , 00001-09999\nwrite\n写单个数字量输出\nfc =5 , 00001-09999\n写多个数字量输出\nfc =15 , 00001-09999\n\nread \n读数字量输出\nfc=2 , 10001-19999\nfc=4 ,30001-39999\n\n\n(fc=3 <--> fc 6,16)\nread \n读模拟量输出出\nfc=3 , 40001-49999\nwrite\n写单个模拟量输出\nfc =6 , 40001-49999\nwrite\n写单个模拟量输出\nfc =16 , 40001-49999\n\n\n\n","x":290,"y":260,"wires":[]},{"id":"54dde46e.53267c","type":"modbus-client","name":"local_2","clienttype":"tcp","bufferCommands":true,"stateLogEnabled":true,"queueLogEnabled":false,"tcpHost":"127.0.0.1","tcpPort":"502","tcpType":"DEFAULT","serialPort":"/dev/ttyUSB","serialType":"RTU-BUFFERD","serialBaudrate":"9600","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","unit_id":"2","commandDelay":"1","clientTimeout":"1000","reconnectOnTimeout":false,"reconnectTimeout":"2000","parallelUnitIdsAllowed":false}]
源自於https://tlcheng.wordpress.com/2014/10/26/software-modbus-%E8%BB%9F%E9%AB%94%E6%8E%A8%E8%96%A6/
Modbus PLC Simulator : http://www.plcsimulator.org/
https://sourceforge.net/projects/modrssim/
簡單的說,這套軟體提供 Modbus RTU / TCP 裝置端的模擬,適合開發人員使用。
什麼意思呢?
對於開發者來說,寫程式就要有設備才能測試通訊,沒設備就只能在那邊傻著不知道要如何了。但電腦功能強大為什麼不弄個模擬器來用?這就是…
對於 Modbus TCP 本機測試來說,連線都不要,對於 Modbus RTU 來說,則是需要一條跳接線,讓兩個 COM 對連。
比較有趣的是,這套軟體的 RTU 模式還可以開啟雜訊功能… 有沒有很想揍作者… 在 RS-232/RS-485 通訊線路常會受動力線或環境干擾,基本上就是用 Cat5e SFTP 的線,並做好銅網接地,若是干擾嚴重的話,就只能靠光纖了。所以在實際上,程式排除包含雜訊的通訊失敗內容是很重要的。
Modbus TCP Server 部分則是可以設定連線數,大部分的 Modbus TCP Server 多半有此限制,一般連線數都不多,多半在 50 以內,因為使用微處理晶片負荷能力有限,而且重點是 RS-232 / RS-485 都是詢答模式,太多 client 連入,將會影響輪詢。
這套注意一下,在 Download 頁面有說到,要免費使用要輸入怎樣的註冊資料,並提供 Windows 2003 以前用的 key.reg 與 Vista 以後用的 Vista_key.reg ,雖然 Vista_key.reg 寫在 8.18 中,不過新版的 8.20 仍然可以用這個檔註冊。如果沒註冊可是定時會關閉的。
Modbus PLC Simulator
前一套是 Server 端,後一套則是 Client 端了。
Client 端我平常多半使用 modscan32 ,這套在網路上也是頗富盛名,不過這套會跳試用畫面,比需花錢註冊才能輕鬆用,所以這邊介紹另一套:
Modbus Master Simulator : http://en.radzio.dxp.pl/modbus-master-simulator/
這套的好處是你可以把常用的 Modbus Protocol 輸入進去,然後要測試的時候,直接開啟該設定檔,改個 ID 就可以了,此外支援多種資料格式,就是 Modbus32 比不上的了。
Modbus Master Simulator
別名 (Alias) 的部分,就當成註解輸入,例如第 0 個位置是 功率 (0.01 kW) 之類的,才知道抓回來的數字還要除以 100 。
第二套由於可以載入設定,適合給測試人員使用,當然開發人員也可以使用。
畫面中傳輸的內容就是本篇介紹的兩套互連的資訊。
沒有留言:
張貼留言