UDP 實(shí)現(xiàn) OMRON 的讀寫
生成讀OMRON數(shù)據(jù)命令方法:
/// <summary>
/// 生成讀取命令
/// </summary>
/// <param name="byPlcDot">plc節(jié)點(diǎn)號(hào)</param>
/// <param name="byLocalDot">本機(jī)節(jié)點(diǎn)號(hào)</param>
/// <param name="index">讀的地址的 數(shù)據(jù)區(qū) 例如:D600</param>
/// <param name="WordNumber">讀取的 數(shù)據(jù)的個(gè)數(shù) 15 表示 D600-D615</param>
/// <param name="addressType">讀取的地址 plc D區(qū):0x82 plc H區(qū):0xB2</param>
/// <returns>生成的命令</returns>
public static byte[] CmdOmlonReadData(byte byPlcDot, byte byLocalDot, int index, int WordNumber, OMLONADDRESS addressType)
{
byte[] cmdData = new byte[32];
cmdData[0] = 0x80;
cmdData[1] = 0x00;
cmdData[2] = 0x02;
cmdData[3] = 0x00; //PLC網(wǎng)絡(luò)號(hào)
cmdData[4] = byPlcDot; //PLC節(jié)點(diǎn)號(hào)
cmdData[5] = 0x00; //PLC單元號(hào)
cmdData[6] = 0x00; //上位機(jī)網(wǎng)絡(luò)號(hào)
cmdData[7] = byLocalDot; //上位機(jī)節(jié)點(diǎn)號(hào)
cmdData[8] = 0x00;
cmdData[9] = 0x03; //SID
cmdData[10] = 0x01; //讀命令
cmdData[11] = 0x01; //讀命令
cmdData[12] = (byte)addressType;
cmdData[13] = (byte)(index / 256); //起始地址
cmdData[14] = (byte)(index % 256); //起始地址
cmdData[15] = 0x00;
cmdData[16] = (byte)(WordNumber / 256); //讀取字?jǐn)?shù)
cmdData[17] = (byte)(WordNumber % 256); //讀取字?jǐn)?shù)
return cmdData;
}
寫OMRON數(shù)據(jù):
/// <summary>
/// 寫OMLON PLC地址數(shù)據(jù)
/// </summary>
/// <param name="cmdData">生成的命令</param>
/// <param name="byPlcDot">plc 節(jié)點(diǎn)</param>
/// <param name="byLocalDot">本機(jī) 節(jié)點(diǎn)</param>
/// <param name="index">地址的 數(shù)據(jù)區(qū) 例如:D600</param>
/// <param name="WriteNumber">個(gè)數(shù)</param>
/// <param name="writeValue">需要寫入的數(shù)據(jù)</param>
/// <param name="addressType">地址 plc D區(qū):0x82 plc H區(qū):0xB2</param>
/// <returns></returns>
public static int CmdOmlonWriteData(byte[] cmdData, byte byPlcDot, byte byLocalDot, int index, int WriteNumber, byte[] writeValue, OMLONADDRESS addressType)
{
int commandLength = 0;
cmdData[0] = 0x80;
cmdData[1] = 0x00;
cmdData[2] = 0x02;
cmdData[3] = 0x00; //PLC網(wǎng)絡(luò)號(hào)
cmdData[4] = byPlcDot; //PLC節(jié)點(diǎn)號(hào)
cmdData[5] = 0x00; //PLC單元號(hào)
cmdData[6] = 0x00; //上位機(jī)網(wǎng)絡(luò)號(hào)
cmdData[7] = byLocalDot; //上位機(jī)節(jié)點(diǎn)號(hào)
cmdData[8] = 0x00;
cmdData[9] = 0x03; //SID
cmdData[10] = 0x01; //寫命令
cmdData[11] = 0x02; //寫命令
cmdData[12] = (byte)addressType;
cmdData[13] = (byte)(index / 256); //起始地址
cmdData[14] = (byte)(index % 256); //起始地址
cmdData[15] = 0x00;
cmdData[16] = (byte)(WriteNumber / 256); //寫的個(gè)數(shù)
cmdData[17] = (byte)(WriteNumber % 256); //寫的個(gè)數(shù)
for (int n = 0; n < WriteNumber * 2; n++)
{
cmdData[18 + n] = writeValue[n];
}
commandLength = 18 + 2 * WriteNumber;
return commandLength;
}
UDP 發(fā)送請(qǐng)求
private Queue<UdpData> sendDataList = new Queue<UdpData>(); //發(fā)送數(shù)據(jù)緩沖區(qū)
public void SendData()
{
try
{
udpSend.Connect(remoteEP);
}
catch
{
MessageBox.Show("連接錯(cuò)誤 " + remoteEP.ToString(), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
connectSuccess = true;
byte[] writeValue = new byte[16];
Byte[] sendBytes = { 1, 1 };
while (true)
{
if (cts.Token.IsCancellationRequested)
{
break;
}
bool sendBuffer = false;
// 上鎖線程安全
lock (sendDataLock)
{
if (sendDataList.Count > 0) //如果隊(duì)列里面有需要發(fā)送的數(shù)據(jù) 則發(fā)送
{
UdpData getData = sendDataList.Dequeue();
sendBuffer = true;
udpSend.BeginSend(getData.buffer, getData.length, new AsyncCallback(SendCallback), udpSendState);
}
}
if (sendBuffer == false) // 發(fā)送讀取的命令
{
udpSend.BeginSend(readAgvPlcCommand, 18, readCallback, udpSendState);
ReceiveMessages();
}
if (sendBuffer == false)
Thread.Sleep(4000);
else
Thread.Sleep(100);
}
}
public void addSendBuffer(ReadWriteType readWriteType, byte[] data)
{
UdpData pData = new UdpData();
if (readWriteType == ReadWriteType.WRITE_AGV_D600)
{
pData.length = CmdOmlonWriteData(pData.buffer, byPlcDot, localDot, 601, 1, data, OMLONADDRESS.D);
}
Console.WriteLine(pData.buffer);
//Queue<T> 不是線程安全的
lock (sendDataLock)
{
sendDataList.Enqueue(pData);
}
}
// 發(fā)送回調(diào)函數(shù)
public void SendCallback(IAsyncResult iar)
{
UdpState udpState = iar.AsyncState as UdpState;
if (iar.IsCompleted)
{
udpState.udpClient.EndSend(iar);
}
}
// 接收函數(shù)
public void ReceiveMessages()
{
lock (this)
{
try
{
udpSend.BeginReceive(receiveCallback, udpReceiveState);
}
catch (SocketException e)
{
string strException = string.Format("SocketException:{0}", e);
}
Thread.Sleep(100);
}
}
//讀數(shù)據(jù)接收回調(diào)函數(shù)
public void ReceiveCallback(IAsyncResult iar)
{
UdpState udpState = iar.AsyncState as UdpState;
if (iar.IsCompleted)
{
Byte[] receiveBytes = udpState.udpClient.EndReceive(iar, ref udpReceiveState.ipEndPoint);
if (receiveBytes.Length >= 44) // 讀數(shù)據(jù)返回
{
DataForm mainform = g_em as DataForm;
if (bUpdateFirst == true)
{
mi = new MyInvoke(UpdateForm);
bUpdateFirst = false;
}
if (mainform.InvokeRequired)
{
mainform.BeginInvoke(mi, receiveBytes);
//mainform.BeginInvoke((MethodInvoker)(() =>
//{
// string strData = "";
// DataForm mainForm = g_em as DataForm;
// strData = "";
// for (int n = 0; n < receiveBytes.Length; n++)
// strData = strData + " " + (receiveBytes[n]).ToString("X2");
// mainForm.lstData.Items.Insert(0, strData);
// strData = DateTime.Now.ToString("HH:mm:ss ");
// mainForm.lstData.Items.Insert(0, strData);
// Console.WriteLine(strData);
//}));
}
Console.WriteLine();
}
else if (receiveBytes.Length >= 10) // 寫數(shù)據(jù)返回
{
readWriteType = ReadWriteType.READ_AGV_PLC; ////恢復(fù)為讀命令
}
}
}
UdpData 于 UdpState
public class UdpState
{
public UdpClient udpClient = null;
public IPEndPoint ipEndPoint = null;
public const int BufferSize = 1024;
public byte[] buffer = new byte[BufferSize];
public int counter = 0;
}
public class UdpData
{
public byte[] buffer = new byte[1024];
public int recvValue = 0;
public int length = 0;
}