2015年11月12日 星期四

an example to use the modbus rtu protocol to query/read/write the motor drivers

Modbus應用層協定常作為工業設備之間的溝通語言,
RS485實體層協定則常作為電腦及設備之間較長距離、耐雜訊的溝通工具。
因此,若想由電腦對馬達設備進行控制,常見利用
Modbus及RS485建立電腦和馬達驅動器之間的連線。

電腦和馬達驅動器之間的溝通關係如下:

電腦                              馬達驅動器
------                            --------------
客戶應用程式
MODBUS應用層<--------------------->MODBUS應用層
COM1序列埠
RS485實體層<---------------------->RS485實體層

電腦端應用層對實體層的介面就是COM1序列埠。
電腦及馬達兩者間的應用層溝通就靠MODBUS RTU協定。
MODBUS RTU (remote terminal unit)協定可針對特定id的馬達驅動器,
利用序列埠發出指令,讀寫不同暫存器,達成驅動馬達運轉的目的。

以下將以東方馬達的 AZ 系列驅動器,其支援的modbus指令為例,
介紹其利用modbus rtu協定讀、寫、查詢驅動器的溝通過程,
可作為撰寫序列埠相關程式之參考。
範例出自手冊 pp224-228, HM-60260C(AZ).pdf。

--------- 讀取一段連續暫存器 -----------

A.欲讀取馬達驅動器一段連續暫存器的資料:
A1.先循序對COM1寫出8 bytes如下:

id:         01h     表 馬達驅動器id
code:       03h     表 讀取一段連續暫存器 指令
start_addr: 18h,40h 表 1840h 暫存器起始住址
addr_count: 00h,06h 表 0006h 連續暫存器個數
crc:        c2h,bch 表驗證碼 bcc2h

表示對馬達驅動器id=01h,下03h號指令讀取一段連續暫存器,
回傳起始位址1840h,連續0006h個16bit暫存器的內容

A2.再從COM1循序接收結果如下:

01h      表馬達驅動器id,應為剛才id
03h      表讀取指令之回應結果,應為剛才code
0ch      表後續的byte個數,應為addr_count兩倍
00h, 00h 表 1840h 內容 0000h
00h, 02h 表 1841h 內容 0002h
ffh, ffh 表 1842h 內容 ffffh
d8h, f0h 表 1843h 內容 d8f0h
00h, 00h,表 1844h 內容 0000h
27h, 10h,表 1845h 內容 2710h
82h, eah 表 驗證碼ea82h



--------- 寫入一段連續暫存器 -----------

B.欲寫入資料到馬達驅動器的一段連續暫存器:
B1.先循序對COM1寫出21 bytes如下:

id:         04h     表 馬達驅動器id
code:       10h     表 寫入一段連續暫存器 指令
start_addr: 18h,c6h 表 18c6h 暫存器起始住址
addr_count: 00h,06h 表 0006h 連續暫存器個數
byte_count: 0ch     表後續的byte個數,應為addr_count兩倍
data:
  00h,00h           表 18c6h 內容 0000h
  27h,10h           表 18c7h 內容 2710h
  00h,00h           表 18c8h 內容 0000h
  4eh,20h           表 18c9h 內容 4e20h
  00h,00h,          表 1844h 內容 0000h
  01h,f4h,          表 1845h 內容 01f4h
crc:        6ch,a0h 表 驗證碼a06ch

表示對馬達驅動器id=04h,下10h號指令寫入一段連續暫存器,
將後續0ch個byte,依序寫入起始位址18c6h,連續0006h個16bit暫存器

B2.再從COM1接收回應結果如下

04h     表馬達驅動器id,應為剛才id
10h     表讀取指令之回應結果,應為剛才code
18h,c6h 表 18c6h 起始住址,應為剛才start_addr
00h,06h 表 0006h 連續住址個數,應為剛才addr_count
a6h,c3h 表 驗證碼c3a6h



--------- 寫入單一暫存器 -----------

C.欲寫出資料到馬達驅動器的單一暫存器:
C1.先循序對COM1寫出8 bytes如下:

id:    02h     表 馬達驅動器id
code:  06h     表 寫入單一暫存器 指令
addr:  02h,55h 表寫入住址0255h
data:  00h,50h 表寫入內容0050h
crc:   98h,6dh 表驗證碼6d98h

表示對馬達驅動器id=02h,下06h號指令寫入單一暫存器,
將data=0050h,寫入addr=0255h的16bit暫存器

C2.再從COM1接收回應結果如下:

02h 表馬達驅動器id,應為剛才id
06h 表讀取指令之回應結果,應為剛才code
02h,55h 表 0255h 暫存器住址,應為剛才addr
00h,50h 表 0006h 寫入內容,應為剛才data
98h, 6dh 表 驗證碼6d98h



--------- 診斷驅動器 -----------

D.欲診斷馬達驅動器:
D1.先循序對COM1寫出8 bytes如下:

id:          03h     表 馬達驅動器id
code:        08h     表 診斷 指令
subcode:     00h,00h 表子功能0000h
data:        12h,34h 表任意測試資料1234h
crc:         ech,9eh 表驗證碼9eech

表示對馬達驅動器id=03h,下08h號指令進行0000h號子功能診斷,
將隨意資料data=1234h送出,看會不會回傳該資料回來

D2.再從COM1接收回應結果如下: 應和剛才送出內容完全一樣

id:          03h     表 馬達驅動器id
code:        08h     表 診斷 指令
subcode:     00h,00h 表子功能0000h
data:        12h,34h 表任意測試資料1234h
crc:         ech,9eh 表驗證碼9eech

-

幾種環境的 Serial Port 寫法:

Linux/Cygwin C寫法:
  https://www.cmrr.umn.edu/~strupp/serial.html
  http://www.teuniz.net/RS-232/

Windows Win32 C寫法:
   http://cboard.cprogramming.com/windows-programming/141173-windows-serial-programming.html

Windows C#/C++/VB .NET寫法:
   https://msdn.microsoft.com/zh-tw/library/system.io.ports.serialport(v=vs.110).aspx

SerialPort存取原理
  http://www.dotblogs.com.tw/billchung/category/5702.aspx

PS:
https://en.wikipedia.org/wiki/Modbus
http://www.modbus.org/tech.php 標準文件及多種平台之程式碼

沒有留言: