# ModBus
持續學習中,如有錯誤歡迎留言賜教
## 說明
https://home.gamer.com.tw/creationDetail.php?sn=3854794
https://makerpro.cc/author/ryanhu/
https://www.ni.com/zh-tw/innovations/white-papers/14/the-modbus-protocol-in-depth.html
https://dotblogs.com.tw/Leo_CodeSpace/2018/12/26/185411
https://www.youtube.com/watch?v=txi2p5_OjKU&feature=emb_title
是一種工業上常用的通訊協定
主要分為3種通訊方式
- ModBus ASCII
- ModBus RTU ( remote terminal uint )
- ModBus TCP
其中 ModBus ASCII 是一開始設計出來時使用的編碼方式,現在已經很好人使用了,現在主要是使 ModBus RTU 為大宗,可以搭配 RS-232,RS-422,RS-485使用,ModBus TCP某種意義上可以說是 ModBus RTU 為了能在網路上傳輸訊息的變種,在架構上可以是 點對點 或是主從關係,由使用者做決定
以 RTU 方式所傳出的資料格式

Device Address 是指定要傳輸 Slave 裝置
Function Code 是參照下方的指令表跟記憶體位址選擇要執行的命令


上圖四種記憶體分別是
- Coils 數位輸出
- Discrete Inputs 數位輸入
- Input Regusters 類比輸入
- Holding Registers 類比輸出
Type prefix 可以當成對其記憶體種類的編號,在使用上依據函式庫要求填上編號
下方為 Function code

在使用時,須結合兩張表的資訊,選擇函式引數
在傳輸時,ModBus 通常以使用者角度看是以 PDU 為單位做傳送,但在實際傳輸時,會依不同的通訊協定加上不同的標頭跟結尾變成一個應用資料單元 ( Application Data Unit APU )做傳輸,在特殊狀況下可以依需求以人工方式將 ADU 做拆分,但通常其況下這部分會交由函式庫做處理。
## 比較
https://stackoverflow.com/questions/17081442/python-modbus-library
## 規格書
https://modbus.org/docs/MBConformanceTestSpec_v3.0.pdf
https://modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf
## pymodbus
### github
https://github.com/riptideio/pymodbus
https://pymodbus.readthedocs.io/en/latest/readme.html
https://pythonhosted.org/pymodbus/examples/index.html
## 工具
### modbustool
https://www.modbustools.com/download.html
### nmap
https://www.raspberrypi.org/documentation/remote-access/ip-address.md
## pyModbus function:
- write_coils( start_address, value(true or false), **kwargs(slave address) ) :
write a single coil_register ( digital out )
- write_coils( start_address, value(can input array), **kwargs(slave address) )
write multi coil_registers by array ( digital out )
- write_register(start_address, value, **kwargs(slave address) )
write a single holding_register
- write_registers(address, values, **kwargs(slave address) )
write multi holding_registers by array
- read_coils(start_address, count=1(how many), **kwargs(slave address) )
read coil_registers return a deferred response handle
use .bits to show the boolean array
- read_holding_registers(start_address, count=1(how many), **kwargs(slave address) )
read holding_registers return a deferred response handle
use . registers to show the number array
- read_discrete_inputs(address, count=1(how many), **kwargs)
read discrete_registers (digital input)
use .bits to show the boolean array
- close()
closes the underlying socket connection