2012年7月26日 星期四

ModBus TCP 連線

  
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
//加入網路連線類別庫
using System.Net;
using System.Net.Sockets;

namespace ServiceRequestData
{
    class ConnectDevice
    {
        public string Value = ""; //向Device要回的資料
        public bool TimeOut = false; //是否有TimeOut發生
     
        //與Device連線
        public ConnectDevice(string hostip,int port,int func,string startaddress,int length)
        {
            byte[] senddata = SendModbusCommend(func, startaddress, length); //傳送的資料
            byte[] recvdata = SocketConnectCommend(hostip,port,senddata); //傳送後接收回來的資料
            Value = RecvModbusCommend(recvdata);


        }
     
        //Modbus傳送指令 fuction,StartAddress,Length
        //支援func:1,2,3,4
        //StartAddress:"0f ff"
        //length:wordcount,bitcount
        private byte[] SendModbusCommend(int func, string StartAddress, int length)
        {
            byte[] refnum = new byte[2];
            byte[] count = new byte[2];
            byte[] Commend = new byte[12];
            refnum = strToHexByte(StartAddress);
            count = BitConverter.GetBytes(length);
            for (int i = 0; i < Commend.Length; i++)
                switch (i)
                {
                    case 5:
                        Commend[i] = Convert.ToByte(6); //封包後面長度
                        break;
                    case 6:
                        Commend[i] = Convert.ToByte(1);
                        break;
                    case 7:
                        Commend[i] = Convert.ToByte(func); //function
                        break;
                    case 8:
                        Commend[i] = refnum[0]; //startaddress
                        break;
                    case 9:
                        Commend[i] = refnum[1];
                        break;
                    case 10:
                        Commend[i] = count[1]; //length
                        break;
                    case 11:
                        Commend[i] = count[0];
                        break;
                    default:
                        Commend[i] = Convert.ToByte(0);
                        break;

                }

            return Commend;

        }
     
        //Modbus接收指令
        //傳回字串型態Bytes
        private string RecvModbusCommend(byte[] recvcmd)
        {
         
            byte [] data = new byte[recvcmd[8]];
            for (int i = 9; i < recvcmd.Length; i++)
            data[i-9] = recvcmd[i];

            return byteToHexStr(data);
         
        }

        //TCP同步傳輸:傳送指令後接收資料
        private byte[] SocketConnectCommend(string host, int port, byte[] sendBytes)
        {
            //int port = Convert.ToInt32("502");
            //string host = "192.168.1.204";
            IPAddress ip = IPAddress.Parse(host);
            IPEndPoint ipe = new IPEndPoint(ip, port);
            Socket sk = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //byte[] sendBytes = strToHexByte("00 00 00 00 00 06 01 05 00 01 00 01 00");
            byte[] recvBytes = new byte[256];

            try
            {

                sk.Connect(ipe);
                sk.Send(sendBytes, sendBytes.Length, 0);
                sk.Receive(recvBytes, recvBytes.Length, 0);
                sk.Close();
                return recvBytes;
            }
            catch (ArgumentNullException ex)
            {
                MessageBox.Show(ex.ToString());
                TimeOut = true;
                return null;
            }
            catch (SocketException ex)
            {
                MessageBox.Show(ex.ToString());
                TimeOut = true;
                return null;
            }
        }


        //十六進位轉成字串 0x00 0x01 0x0f 0xff "00 01 0f ff"
        private static string byteToHexStr(byte[] bytes)
        {
            string returnStr = "";
            if (bytes != null)
            {
                for (int i = 0; i < bytes.Length; i++)
                {
                    returnStr += bytes[i].ToString("X2") + " ";
                }
            }
            return returnStr;
        }

        //字串轉成Byte陣列 "00 01 0f ff" 0x00 0x01 0x0f 0xff
        private static byte[] strToHexByte(string hexString)
        {
            hexString = hexString.Replace(" ", "");
            if ((hexString.Length % 2) != 0)
                hexString += " ";
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            return returnBytes;
        }

     

            }
        }
 

沒有留言:

張貼留言