Modbus 通訊中針對暫存區作讀寫時必須將數值拆解成 4 個 Byte 後帶入訊息
這時使用 Union 可以簡單的轉換
【服務項目】
自動化設備控制系統及機構設計
class MyModbus
{
public static SerialPort sp = new SerialPort();
public static bool Init()
{
sp.PortName = "COM2";
sp.BaudRate = 9600;
sp.DataBits = 7;
sp.StopBits = StopBits.One;
sp.Parity = Parity.Even;
sp.ReadTimeout = 1000;
sp.Open();
return true;
}
public static bool Close()
{
sp.Close();
return true;
}
public static bool Send(string Massage)
{
if (sp.IsOpen == false) return false;
sp.DiscardInBuffer();
sp.DiscardOutBuffer();
sp.Write(Massage);
return true;
}
public static bool Receive(out string Massage)
{
Massage = string.Empty;
if (sp.IsOpen == false) return false;
string str = sp.ReadTo("\r\n");
//比對開頭碼是否為':'
if (str[0] != ':') return false;
//移除符號
str = str.Trim(':', '\r', '\n');
//檢查 LRC
string checksum = str.Substring(str.Length - 2, 2);
string Data = str.Substring(0, str.Length - 2);
if (checksum != Lrc(Data)) return false;
Massage = str;
return true;
}
public static string BulidMassage(byte Address, byte Type, string Start, string Data)
{
string Cmd = Address.ToString("X2") + Type.ToString("X2") + Start + Data;
string Massage = ':' + Cmd + Lrc(Cmd) + "\r\n";
return Massage;
}
public static string Lrc(string Massage)
{
byte sum = 0;
for (int idx = 0; idx < Massage.Length; idx += 2)
{
string str = Massage.Substring(idx, 2);
byte value = Convert.ToByte(str, 16);
sum = (byte)((sum + value) & 0xff);
}
//取補數
byte checksum = (byte)((~sum + 1) & 0xff);
string Hex = checksum.ToString("X2");
return Hex;
}
}
class MyPLC
{
public MyPLC()
{
MyModbus.Init();
}
~MyPLC()
{
MyModbus.Close();
}
public bool[] ReadAllY()
{
bool[] Y = new bool[8];
//string Massage = MyModbus.BulidMassage(1, 3, "0614", "0008");
string Massage = MyModbus.BulidMassage(1, 2, "0500", "0008");
MyModbus.Send(Massage);
string Data = string.Empty;
MyModbus.Receive(out Data);
string Temp = Data.Substring(6, 2);
byte Value = Convert.ToByte(Temp);
for (int idx = 0; idx < Y.Length; idx++)
{
Y[idx] = (Value & (0x01 << idx)) > 0x00 ? true : false;
}
return Y;
}
public bool SetY(int Number , bool OnOFF)
{
string CoilNumber = "05" + Number.ToString("X2");
string Massage = MyModbus.BulidMassage(1, 5, CoilNumber, OnOFF ? "FF00" : "0000");
MyModbus.Send(Massage);
string Data = string.Empty;
MyModbus.Receive(out Data);
string Temp = Data.Substring(4, 4);
if (Temp != CoilNumber) return false;
Temp = Data.Substring(8, 4);
if(OnOFF)
{
if (Temp != "FF00") return false;
}
else
{
if (Temp != "0000") return false;
}
return true;
}
public bool[] ReadAllX()
{
bool[] X = new bool[16];
string Massage = MyModbus.BulidMassage(1, 2, "0200", "0010");
MyModbus.Send(Massage);
string Data = string.Empty;
MyModbus.Receive(out Data);
string Temp = Data.Substring(6, 2);
byte Value = Convert.ToByte(Temp);
for (int idx = 0; idx < X.Length; idx++)
{
X[idx] = (Value & (0x01 << idx)) > 0x00 ? true : false;
}
return X;
}
public bool[] ReadAllM()
{
bool[] X = new bool[16];
string Massage = MyModbus.BulidMassage(1, 2, "0800", "0008");
MyModbus.Send(Massage);
string Data = string.Empty;
MyModbus.Receive(out Data);
string Temp = Data.Substring(6, 2);
byte Value = Convert.ToByte(Temp);
for (int idx = 0; idx < X.Length; idx++)
{
X[idx] = (Value & (0x01 << idx)) > 0x00 ? true : false;
}
return X;
}
public bool SetM(int Number, bool OnOFF)
{
string CoilNumber = "08" + Number.ToString("X2");
string Massage = MyModbus.BulidMassage(1, 5, CoilNumber, OnOFF ? "FF00" : "0000");
MyModbus.Send(Massage);
string Data = string.Empty;
MyModbus.Receive(out Data);
string Temp = Data.Substring(4, 4);
if (Temp != CoilNumber) return false;
Temp = Data.Substring(8, 4);
if (OnOFF)
{
if (Temp != "FF00") return false;
}
else
{
if (Temp != "0000") return false;
}
return true;
}
}