初識Modbus TCP/IP-------------C#編寫Modbus TCP客戶端程式(二)

隨夢而飛發表於2017-08-02

由於感覺上一次寫的篇幅過長,所以新開一貼,繼續介紹Modbus TCP/IP的初步認識,

書接上回

3)、03(0x03)功能碼--------讀保持暫存器

請求與響應格式



這是一個請求讀暫存器108-110 的例項:




傳送資料為:

0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x6B, 0x00, 0x03

程式如下:
[csharp] view plain copy
  1. private void send03_Click(object sender, EventArgs e)  
  2. {  
  3.     byte[] data = new byte[] { 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x6C, 0x00, 0x03 };  
  4.     newclient.Send(data);  
  5. }  



接收資料為:

0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x06, 0x02, 0x2B, 0x00,0x00,0x00,0x64

程式如下:

[csharp] view plain copy
  1. public void showMsg03(string msg)  
  2. {  
  3.     //線上程裡以安全方式呼叫控制元件  
  4.     if (receive0x01.InvokeRequired)  
  5.     {  
  6.         MyInvoke _myinvoke = new MyInvoke(showMsg03);  
  7.         receive0x03.Invoke(_myinvoke, new object[] { msg });  
  8.     }  
  9.     else  
  10.     {  
  11.         receive0x03.AppendText(msg);  
  12.     }  
  13. }  

我們再來看一下Modbus Slave設定






我們再看一下Wireshark擷取封包

Modbus TCP請求



Modbus TCP響應



我們的軟體所收到的資料




4)、05(0x05)功能碼--------寫單個線圈
 
十六進位制值0XFF00請求線圈為ON。十六進位制值0X0000請求線圈為OFF。

其它所有值均為非法的,並且對線圈不起作用。

請求與應答PDU


這是一個請求寫線圈173 為ON 的例項:




傳送資料為;

0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x05, 0x00, 0xAD, 0xFF, 0x00

程式如下:

[csharp] view plain copy
  1. private void send05_Click(object sender, EventArgs e)  
  2. {  
  3.     byte[] data = new byte[] { 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x05, 0x00, 0xAD, 0xFF, 0x00 };  
  4.     newclient.Send(data);  
  5. }  

接收資料為:

0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x02, 0x03,0xAD, 0xFF, 0x00

程式如下:

[csharp] view plain copy
  1. public void showMsg05(string msg)  
  2. {  
  3.     //線上程裡以安全方式呼叫控制元件  
  4.     if (receive0x05.InvokeRequired)  
  5.     {  
  6.         MyInvoke _myinvoke = new MyInvoke(showMsg05);  
  7.         receive0x05.Invoke(_myinvoke, new object[] { msg });  
  8.     }  
  9.     else  
  10.     {  
  11.         receive0x05.AppendText(msg);  
  12.     }  
  13. }  

我們再來看一下Modbus Slave設定





我們再看一下Wireshark擷取封包

Modbus TCP請求



Modbus TCP響應



我們的軟體所收到的資料




5)、06 (0x06)寫單個暫存器


請求與應答PDU


這是一個請求將十六進位制00 03 寫入暫存器2的例項:




傳送資料為;

0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x06, 0x00, 0x01, 0x00, 0x03

程式如下:


[csharp] view plain copy
  1. private void send06_Click(object sender, EventArgs e)  
  2. {  
  3.     byte[] data = new byte[] { 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x06, 0x00, 0x01, 0x00, 0x03 };  
  4.     newclient.Send(data);  
  5. }  


接收資料為:

0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x06, 0x00,0x01, 0x00, 0x03

程式如下:

[csharp] view plain copy
  1. <span style="font-size:14px;">public void showMsg06(string msg)  
  2. {  
  3.     //線上程裡以安全方式呼叫控制元件  
  4.     if (receive0x06.InvokeRequired)  
  5.     {  
  6.         MyInvoke _myinvoke = new MyInvoke(showMsg06);  
  7.         receive0x06.Invoke(_myinvoke, new object[] { msg });  
  8.     }  
  9.     else  
  10.     {  
  11.         receive0x06.AppendText(msg);  
  12.     }  
  13. }</span>  

我們再來看一下Modbus Slave設定






我們再看一下Wireshark擷取封包

Modbus TCP請求



Modbus TCP響應




6)、15 (0x0F) 寫多個線圈


在一個遠端裝置中,使用該功能碼強制線圈序列中的每個線圈為ON 或OFF。

域位元位置中的邏輯“1”請求相應輸出為ON。

域位元位置中的邏輯“0”請求相應輸出為OFF。

請求與應答PDU




這是一個請求從線圈20 開始寫入10 個線圈的例項:



傳送資料為;

0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x01, 0x0F, 0x00, 0x14, 0x00, 0x0A,0x02,0xCD,0x01

程式如下:

[csharp] view plain copy
  1. <span style="font-size:14px;">private void send0F_Click(object sender, EventArgs e)</span>  
[csharp] view plain copy
  1. <span style="font-size:14px;">{  
  2.     byte[] data = new byte[] { 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x01, 0x0F, 0x00, 0x14, 0x00, 0x0A, 0x02, 0xCD, 0x01 };  
  3.     newclient.Send(data);  
  4. }</span>  



接收資料為:

0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x0F, 0x00,0x14,0x00, 0x0A

程式如下:

[csharp] view plain copy
  1. <span style="font-size:14px;">public void showMsg0F(string msg)  
  2. {  
  3.     //線上程裡以安全方式呼叫控制元件  
  4.     if (receive0x0F.InvokeRequired)  
  5.     {  
  6.         MyInvoke _myinvoke = new MyInvoke(showMsg0F);  
  7.         receive0x0F.Invoke(_myinvoke, new object[] { msg });  
  8.     }  
  9.     else  
  10.     {  
  11.         receive0x0F.AppendText(msg);  
  12.     }  
  13. }</span>  

我們再來看一下Modbus Slave設定







我們再看一下Wireshark擷取封包

Modbus TCP請求



Modbus TCP響應




我們的軟體所收到的資料



7)、16 (0x10)寫多個暫存器


請求與應答PDU




這是一個請求將十六進位制00 0A 和01 02 寫入以2 開始的兩個暫存器的例項:



傳送資料為;

0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x01, 0x010, 0x00, 0x02, 0x00, 0x02, 0x04,0x00,0x0A,0x01,0x02

程式如下:

[csharp] view plain copy
  1. <span style="font-size:14px;">private void send10_Click(object sender, EventArgs e)  
  2. {  
  3.     byte[] data = new byte[] { 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x01, 0x10, 0x00, 0x02, 0x00, 0x02, 0x04, 0x00,0x0A,0x01, 0x02 };  
  4.     newclient.Send(data);  
  5. }</span>  

接收資料為:

0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x10, 0x00,0x02, 0x00, 0x02

程式如下:

[csharp] view plain copy
  1. public void showMsg10(string msg)  
  2. {  
  3.     //線上程裡以安全方式呼叫控制元件  
  4.     if (receive0x10.InvokeRequired)  
  5.     {  
  6.         MyInvoke _myinvoke = new MyInvoke(showMsg10);  
  7.         receive0x10.Invoke(_myinvoke, new object[] { msg });  
  8.     }  
  9.     else  
  10.     {  
  11.         receive0x10.AppendText(msg);  
  12.     }  
  13. }  

我們再來看一下Modbus Slave設定






我們再看一下Wireshark擷取封包

Modbus TCP請求


Modbus TCP響應



我們的軟體所收到的資料




至此,我們對Modbus協議的初步認識就到此結束了,這裡我們只做了對Modbus TCP

客戶端的瞭解,之後的博文中我會陸續增加Modbus TCP伺服器,modbus 485協議的

主從站,還有在硬體上如何實現modbus通訊等一系列內容敬請關注,同時,由於本人

也是出於學習目的,希望博文中有任何不足的地方都請大家提出,我也學習改正。






相關文章