模擬三菱FX2N系列PLC的串列埠通訊(實測通過)
軟體開發背景:由於專案需要,上位機軟體與三菱FX2N系列PLC的串列埠交換資料時,但手頭上又沒有PLC硬體,所以開發了這樣一個工具來當PLC使用。
/*
功能:模擬PLC的資料通訊作者:
日期:2013-05-01
說明:
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;
namespace CommAssist
{
public partial class Form1 : Form
{
public delegate void Displaydelegate(byte[] InputBuf);
Byte[] OutputBuf = new Byte[128];
Byte[] CommRcvBuf = new Byte[128];
int RcvCount = 0;
bool bFlagRcvOK=false;
bool RcvFlag = false;
SerialPort Comm = new SerialPort("com7", 19200, Parity.None, 8, StopBits.One);
public Displaydelegate disp_delegate;
public Form1()
{
disp_delegate = new Displaydelegate(DispUI);
InitializeComponent();
int mytemp;
comboBox1.SelectedItem = "com7";
Comm.DataReceived += new SerialDataReceivedEventHandler(Comm_DataReceived);
string[] ports = SerialPort.GetPortNames();
Array.Sort(ports);
comboBox1.Items.AddRange(ports);
comboBox1.SelectedIndex = comboBox1.Items.Count > 0 ? 0 : -1;
}
public void DispUI(byte[] InputBuf)
{
//textBox1.Text = Convert.ToString(InputBuf);
int i;
byte GetData;
for (i = 0; i < InputBuf[0]; i++)
{
if (!bFlagRcvOK)
{
GetData = InputBuf[1+i];
switch (RcvCount)
{
case 0: if (GetData == 0x05)
{
CommRcvBuf[RcvCount] = GetData;
RcvCount++;
}
else
RcvCount = 0;
break;
case 1: if (GetData == 0x30)
{
CommRcvBuf[RcvCount] = GetData;
RcvCount++;
}
else if (GetData == 0x05)
{
}
else
{
RcvCount = 0;
}
break;
case 2: if (GetData == 0x31)
{
CommRcvBuf[RcvCount] = GetData;
RcvCount++;
}
else
RcvCount = 0;
break;
case 3: if (GetData == 0x46)
{
CommRcvBuf[RcvCount] = GetData;
RcvCount++;
}
else
RcvCount = 0;
break;
case 4: if (GetData == 0x46)
{
CommRcvBuf[RcvCount] = GetData;
RcvCount++;
}
else
RcvCount = 0;
break;
default:
RcvFlag = true;
break;
}
if (RcvFlag) // receive valid data
{
RcvFlag = false;
CommRcvBuf[RcvCount] = GetData;
RcvCount++;
if (RcvCount >= 17)
{
//MessageBox.Show("收到串列埠資料"); test
//BtnTest_Click();
this.BtnTest_Click(null,null);
bFlagRcvOK = false; // 錯誤溢位處理
RcvCount = 0;
}
}
}
else
break;
}
ASCIIEncoding encoding = new ASCIIEncoding();
textBox1.Text= encoding.GetString(InputBuf);
//return (constructedString);
}
private void BtnTest_Click(object sender, EventArgs e) // 返回主機
{
int i;
string buf;
byte temp;
Byte[] sum = new Byte[10];
try
{
OutputBuf[0] = 0x02;
OutputBuf[1] = 0x30;
OutputBuf[2] = 0x31;
OutputBuf[3] = 0x46;
OutputBuf[4] = 0x46;
//-------------
OutputBuf[5] = 0x30;
OutputBuf[6] = 0x31;
OutputBuf[7] = 0x30;
OutputBuf[8] = 0x31;
OutputBuf[9] = 0x30;
OutputBuf[10] = 0x31;
OutputBuf[11] = 0x30;
OutputBuf[12] = 0x31;
OutputBuf[13] = 0x30;
OutputBuf[14] = 0x31;
OutputBuf[15] = 0x30;
OutputBuf[16] = 0x31;
OutputBuf[17] = 0x30;
OutputBuf[18] = 0x31;
OutputBuf[19] = 0x30;
OutputBuf[20] = 0x31;
OutputBuf[21] = 0x03;
sum[0] = 0;
for (i = 0; i < 21; i++)
sum[0] +=OutputBuf[i+1];
string str = BitConverter.ToString(sum);
OutputBuf[22] = (byte)str[0];
OutputBuf[23] = (byte)str[1];
Comm.Write(OutputBuf,0,24);
}
catch (TimeoutException ex) //異常處理
{
MessageBox.Show(ex.ToString());
}
}
void Comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int count,i;
Byte[] InputBuf = new Byte[128];
System.Threading.Thread.Sleep(20);
try
{
count = Comm.BytesToRead;
Comm.Read(InputBuf,0,Comm.BytesToRead);
for (i = 0; i < count; i++)
{
InputBuf[count - i] = InputBuf[count - i-1];
}
InputBuf[0] = (byte)count;
//InputBuf = UnicodeEncoding.Default.GetBytes(strRD);
//System.Threading.Thread.Sleep(50);
this.Invoke(disp_delegate, InputBuf);
}
catch (TimeoutException ex) //超時處理
{
MessageBox.Show(ex.ToString());
}
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) //選擇串列埠的處理過程
{
bool b_OpenFlag = Comm.IsOpen;
if (b_OpenFlag == true)
{
Comm.Close();
Comm.PortName = comboBox1.SelectedItem.ToString();
Comm.Open();
}
else
{
Comm.PortName = comboBox1.SelectedItem.ToString();
}
}
private void OpenSerialPort_Click(object sender, EventArgs e) //點選“開啟串列埠”按鈕的操作
{
if (OpenSerialPort.Text == "關閉串列埠")
{
Comm.Close();
OpenSerialPort.Text = "開啟串列埠";
}
else
{
Comm.Open();
OpenSerialPort.Text = "關閉串列埠";
}
}
}
}
相關文章
- 串列埠資料抓取及串列埠通訊模擬串列埠
- 小型plc串列埠通訊簡介串列埠
- 通過串列埠進行通訊 :串列埠
- 上位機開發之三菱Q系列PLC通訊實踐
- 串列埠通訊串列埠
- android ndk 虛擬串列埠通訊Android串列埠
- 串列埠通訊 (轉)串列埠
- FX-3U PLC串列埠與PC通訊除錯串列埠除錯
- linux 串列埠通訊Linux串列埠
- 串列埠通訊協議串列埠協議
- Android 串列埠通訊Android串列埠
- C# 串列埠通訊C#串列埠
- 11. 串列埠通訊串列埠
- 串列埠通訊型別串列埠型別
- (10)uart串列埠通訊串列埠
- VC++ 的串列埠通訊 (轉)C++串列埠
- 樹莓派已經通過網路連線通過串列埠通訊在串列埠除錯小助手列印與操作樹莓派串列埠除錯
- 安卓串列埠通訊疑問安卓串列埠
- java串列埠通訊例項 -Java串列埠
- VC++ 串列埠通訊(轉)C++串列埠
- 串列埠無法正常通訊串列埠
- C#串列埠通訊遇到的坑C#串列埠
- AndroidSerialPort:安卓串列埠通訊庫Android安卓串列埠
- 串列埠通訊gui介面顯示串列埠GUI
- ROS環境下串列埠通訊ROS串列埠
- Android藍芽串列埠通訊Android藍芽串列埠
- ros中使用serial包實現串列埠通訊ROS串列埠
- 打工筆記--------------------------c#實現串列埠通訊筆記C#串列埠
- C#實現掃碼槍串列埠通訊C#串列埠
- .NET Compact Framework下的串列埠通訊Framework串列埠
- STM32串列埠通訊串列埠
- C#串列埠通訊程式SerialPort類C#串列埠
- 用VB除錯串列埠通訊 (轉)除錯串列埠
- Java實現RS485串列埠通訊Java串列埠
- Arduino下的STM32的串列埠通訊UI串列埠
- 串列埠通訊與其他通訊方式相比有什麼優勢?串列埠
- 串列埠通訊系列六-串列埠與上位機通訊呼叫Flash及Flash視訊切換(非互動)串列埠
- 通過JLINK實現串列埠顯示除錯串列埠除錯