arm/WindowsFormsApp1/Modbus.cs
2025-02-04 20:09:10 +08:00

224 lines
7.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.IO.Ports;
using System.Data;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text.RegularExpressions;
namespace WindowsFormsApp1
{
class Modbus
{
//===================Defind=================================
string Command_Tcp_Begin = "000000000006";
string Command_Rs232_Begin = ":";
string Command_Rs232_End = "\r\n";
string absport;
SerialPort serialport = new SerialPort("COM1",9600,Parity.Even,7,StopBits.One);
Socket T;
bool TCP;
//MySqlConnection conn;
// MySqlCommand command;
// string MyConnectionString = "server=192.168.0.112 ; uid=user ; pwd=40227000 ; database=scada ; ";
//===================Property====================================
public bool isopen;
public string response;
// public string Command;
// public string Type;
// public string Lrc;
//===================Method===================================
//====================命令==========================================================================
public string Command( string Command , string Type)
{
try
{
if (Type == "TCP")
{
if(absport == "502")
{
Send(Command_Tcp_Begin + Command);
}
if (absport == "29999")
{
Send(Command);
}
string TCP_Butter = Listen();
Thread.Sleep(50);
return TCP_Butter; //Command_Tcp_Begin + Command + Command_Tcp_End;
}
else if (Type == "RS232")
{
string SerialPort_Butter="";
serialport.Write(Command_Rs232_Begin + Command + LRC(Command) + Command_Rs232_End);
Thread.Sleep(50);
if (serialport.BytesToRead != 0)
{
SerialPort_Butter = serialport.ReadLine() + "\r\n";
Regex r = new Regex(":");
SerialPort_Butter = r.Replace(SerialPort_Butter, "");
}
else
{
SerialPort_Butter = "緩衝區未有訊號";
}
return SerialPort_Butter;
}
else
{
MessageBox.Show("未選擇傳輸類型", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return "";
}
}
catch(Exception ex)
{
MessageBox.Show( ex.ToString() );
return "";
}
}
//========================== TC連線 ===============================================================
public void Connert( string Type , string IP , string Port )
{
absport = Port;
try
{
IPEndPoint EP = new IPEndPoint(IPAddress.Parse(IP), int.Parse( Port ) ); //IPAddress是ip如" 127.0.0.1" ;IPEndPoint是ip和端口對的組合如"127.0.0.1: 1000 "
T = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //new Socket( 通訊協定家族ip4 , 通訊端類型 , 通訊協定TCP)
T.Connect(EP); //建立連線
// MessageBox.Show( "已連線至伺服器" );
TCP = true;
}
catch (Exception)
{
// MessageBox.Show( "無法連線至伺服器" );
TCP = false;
}
}
//================連接===================================================================
public void Connert(string Type, string ComPort)
{
try
{
serialport.PortName = ComPort;
serialport.Open();
}
catch
{
serialport.Close();
MessageBox.Show("通訊錯誤");
}
}
//==================通訊偵測==================================================================
public void IsOpen()
{
if (serialport.IsOpen == true || TCP == true)
{
isopen = true;
}
else
{
isopen = false;
}
}
//======================中斷連線===============================================================
public void Disconnect()
{
serialport.Close();
try
{
T.Close();
}
catch { }
TCP = false;
}
//================================= private 內用副程式 =========================== ======================================================
//=============傳送訊息給PLC (TCP傳需先轉成Byte!!!!)=========================================================
private void Send(string Str)
{
if (absport == "502")
{
byte[] A = new byte[1]; //初始需告陣列(因不知道資料大小,下面會做陣列調整)
for (int i = 0; i < Str.Length / 2; i++)
{
Array.Resize(ref A, Str.Length / 2); //Array.Resize(ref 陣列名稱, 新的陣列大小)
string str2 = Str.Substring(i * 2, 2);
A[i] = Convert.ToByte(str2, 16); //字串依照"frombase"轉換數字(Byte)
}
T.Send(A, 0, Str.Length / 2, SocketFlags.None);
}
if (absport == "29999")
{
Str = Str+ "\n";
T.Send(Encoding.ASCII.GetBytes(Str));
}
}
//================接收訊息==========================================
private string Listen()
{
EndPoint ServerEP = (EndPoint)T.RemoteEndPoint;
byte[] Buffer = new byte[1023];
int inLen = 0;
try
{
inLen = T.ReceiveFrom(Buffer, ref ServerEP);
}
catch (Exception)
{
T.Close();
MessageBox.Show("伺服器中斷連線!");
}
string response = BitConverter.ToString(Buffer, 0, inLen);
Regex r = new Regex("-");
response = r.Replace(response, "");
return response;
}
//===================校驗碼======================================================================
private string LRC(string Command)
{
int str = 0;
int LRC_Length = Command.Length / 2;
string LRC_Space = Command;
for (int i = 0; i < LRC_Length; i++)
{
string midtext = LRC_Space.Substring(i * 2, 2);
str += Convert.ToInt16(midtext, 16);
}
while (str > 255)
{
str = str - 256;
}
str = Convert.ToByte(str);
string D2A2 = (Convert.ToString(255 - str + 1, 16)).ToUpper();
string D2A3 = D2A2.PadLeft(2, '0');
return D2A3;
}
}
}