diff --git a/WaferAlignment.sln b/WaferAlignment.sln new file mode 100644 index 0000000..a4027fc --- /dev/null +++ b/WaferAlignment.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 18 +VisualStudioVersion = 18.0.11205.157 d18.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WaferAlignment", "WaferAlignment\WaferAlignment.csproj", "{941B8ABC-436F-457D-95DA-A79E23C8CA5D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {941B8ABC-436F-457D-95DA-A79E23C8CA5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {941B8ABC-436F-457D-95DA-A79E23C8CA5D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {941B8ABC-436F-457D-95DA-A79E23C8CA5D}.Debug|x64.ActiveCfg = Debug|x64 + {941B8ABC-436F-457D-95DA-A79E23C8CA5D}.Debug|x64.Build.0 = Debug|x64 + {941B8ABC-436F-457D-95DA-A79E23C8CA5D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {941B8ABC-436F-457D-95DA-A79E23C8CA5D}.Release|Any CPU.Build.0 = Release|Any CPU + {941B8ABC-436F-457D-95DA-A79E23C8CA5D}.Release|x64.ActiveCfg = Release|x64 + {941B8ABC-436F-457D-95DA-A79E23C8CA5D}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/WaferAlignment/App.config b/WaferAlignment/App.config new file mode 100644 index 0000000..4bfa005 --- /dev/null +++ b/WaferAlignment/App.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/WaferAlignment/CalibForm.Designer.cs b/WaferAlignment/CalibForm.Designer.cs new file mode 100644 index 0000000..aa94a2e --- /dev/null +++ b/WaferAlignment/CalibForm.Designer.cs @@ -0,0 +1,39 @@ +namespace WaferAlignment +{ + partial class CalibForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(800, 450); + this.Text = "CalibForm"; + } + + #endregion + } +} \ No newline at end of file diff --git a/WaferAlignment/CalibForm.cs b/WaferAlignment/CalibForm.cs new file mode 100644 index 0000000..726754e --- /dev/null +++ b/WaferAlignment/CalibForm.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace WaferAlignment +{ + public partial class CalibForm : Form + { + public CalibForm() + { + InitializeComponent(); + } + } +} diff --git a/WaferAlignment/Camera.cs b/WaferAlignment/Camera.cs new file mode 100644 index 0000000..0b75418 --- /dev/null +++ b/WaferAlignment/Camera.cs @@ -0,0 +1,539 @@ +using HslCommunication; +using HslCommunication.Profinet.Siemens; +using MvCamCtrl.NET; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Timers; +using System.Windows.Forms; + +namespace WaferAlignment +{ + public class Camera + { + private bool _isConnected = false; + + public bool IsConnected + { + get { return _isConnected; } + set { _isConnected = value; } + } + + private bool _isStarted = false; + + public bool IsStarted + { + get { return _isStarted; } + set { _isStarted = value; } + } + public event Action OutputImageEvent; + private float expo = 8; + private uint imgHeight = 4000; + private MyCamera _dev; + private CancellationTokenSource _startAcqToken; + private CancellationTokenSource _stopAcqToken; + private Task _imageAcquisitionTask; + private static Object BufForDriverLock = new Object(); + private IntPtr m_BufForDriver = IntPtr.Zero; + private UInt32 m_nBufSizeForDriver = 0; + private MyCamera.MV_FRAME_OUT_INFO_EX m_stFrameInfo = new MyCamera.MV_FRAME_OUT_INFO_EX(); + [DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)] + public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count); + public void Connect() + { + IntPtr devIPtr; + try + { + MyCamera.MV_CC_DEVICE_INFO_LIST m_stDeviceList = new MyCamera.MV_CC_DEVICE_INFO_LIST(); + MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE, ref m_stDeviceList); + if (m_stDeviceList.nDeviceNum > 0) + { + devIPtr = m_stDeviceList.pDeviceInfo[0]; + } + else + { + throw new Exception("未找到相机连接!"); + } + } + catch (Exception ex) + { + throw new Exception("相机查找失败!"); + } + + MyCamera.MV_CC_DEVICE_INFO devInfo = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(devIPtr, typeof(MyCamera.MV_CC_DEVICE_INFO)); + if (_dev != null) + { + throw new Exception("相机连接失败,原因:该设备实例已存在"); + } + _dev = new MyCamera(); + if (_dev == null) + { + throw new Exception("相机连接失败,原因:该设备实例化失败"); + } + int status = _dev.MV_CC_CreateDevice_NET(ref devInfo); + if (status != MyCamera.MV_OK) + { + throw new Exception(String.Format("相机连接失败,原因:设备创建失败")); + } + status = _dev.MV_CC_OpenDevice_NET(); + if (status != MyCamera.MV_OK) + { + throw new Exception(String.Format("相机连接失败,原因:设备启动失败")); + } + int nPacketSize = _dev.MV_CC_GetOptimalPacketSize_NET(); + if (nPacketSize > 0) + { + status = _dev.MV_CC_SetIntValue_NET("GevSCPSPacketSize", (uint)nPacketSize); + if (status != MyCamera.MV_OK) + { + throw new Exception(String.Format("相机连接失败,原因:获取本地包大小失败")); + } + } + else + { + throw new Exception(String.Format("相机连接失败,原因:获取本地包大小失败")); + } + + // 连续采集 + int nRet; + nRet = _dev.MV_CC_SetEnumValue_NET("AcquisitionMode", (uint)MyCamera.MV_CAM_ACQUISITION_MODE.MV_ACQ_MODE_CONTINUOUS); + // 手动曝光 + nRet = _dev.MV_CC_SetEnumValue_NET("ExposureAuto", (uint)MyCamera.MV_CAM_EXPOSURE_AUTO_MODE.MV_EXPOSURE_AUTO_MODE_OFF); + // 行触发关闭 + //nRet = _dev.MV_CC_SetEnumValue_NET("TriggerSelector", 9); + //nRet = _dev.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_OFF); + // 帧触发打开,软件触发 + nRet = _dev.MV_CC_SetEnumValue_NET("TriggerSelector", 6); + nRet = _dev.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON); + nRet = _dev.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_COUNTER0); + nRet = _dev.MV_CC_SetFloatValue_NET("ExposureTime", expo); + //nRet = _dev.MV_CC_SetIntValue_NET("Width", 1600); + //nRet = _dev.MV_CC_SetIntValue_NET("Height", 1200); + //nRet = _dev.MV_CC_SetIntValue_NET("OffsetX", 1760); + //nRet = _dev.MV_CC_SetIntValue_NET("OffsetY", 1448); + + _isConnected = true; + } + + public void Disconnect() + { + if (_dev != null) + { + // 关闭设备 + _dev.MV_CC_CloseDevice_NET(); + _dev.MV_CC_DestroyDevice_NET(); + _dev = null; + _isConnected = false; + } + } + + public void Start() + { + if (_dev == null) + { + _isStarted = false; + MessageBox.Show("相机启动失败,相机未连接"); + return; + } + ImageAcquisitionStart(); + m_stFrameInfo.nFrameLen = 0;//取流之前先清除帧长度 + m_stFrameInfo.enPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Undefined; + _dev.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_COUNTER0); + int nRet = _dev.MV_CC_StartGrabbing_NET(); + if (MyCamera.MV_OK != nRet) + { + ImageAcquisitionStop(); + _isStarted = false; + MessageBox.Show("相机启动失败,清除缓存区失败"); + return; + } + _isStarted = true; + } + public void SoftwareGrab() + { + _dev.MV_CC_StopGrabbing_NET(); + _dev.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE); + _dev.MV_CC_StartGrabbing_NET(); + _dev.MV_CC_TriggerSoftwareExecute_NET(); + Thread.Sleep(100); + } + + public void Stop() + { + if (_dev == null) + { + _isStarted = false; + MessageBox.Show("相机停止失败,相机未连接"); + return; + } + ImageAcquisitionStop(); + int nRet = _dev.MV_CC_StopGrabbing_NET(); + if (nRet != MyCamera.MV_OK) + { + _isStarted = false; + MessageBox.Show("相机停止失败"); + return; + } + _isStarted = false; + + } + + private void ImageAcquisitionStart() + { + _startAcqToken = new CancellationTokenSource(); + _imageAcquisitionTask = new Task(() => ImageAcquisitionProcess(), _startAcqToken.Token); + _imageAcquisitionTask.Start(); + } + private void ImageAcquisitionStop() + { + try + { + _startAcqToken.Cancel(); + Thread.Sleep(20); + _imageAcquisitionTask.Wait(_stopAcqToken.Token); + _imageAcquisitionTask.Dispose(); + } + catch (OperationCanceledException ex) + { + _imageAcquisitionTask.Dispose(); + } + } + private void ImageAcquisitionProcess() + { + _stopAcqToken = new CancellationTokenSource(); + MyCamera.MV_FRAME_OUT stFrameInfo = new MyCamera.MV_FRAME_OUT(); + while (true) + { + if (_startAcqToken.IsCancellationRequested) + break; + int nRet = _dev.MV_CC_GetImageBuffer_NET(ref stFrameInfo, 1000); + Console.WriteLine("-----------------------Get Image Buffer:" + "Width[" + Convert.ToString(stFrameInfo.stFrameInfo.nWidth) + "] , Height[" + Convert.ToString(stFrameInfo.stFrameInfo.nHeight) + + "] ,Trigger[" + Convert.ToString(stFrameInfo.stFrameInfo.nTriggerIndex) + "], FrameNum[" + Convert.ToString(stFrameInfo.stFrameInfo.nFrameNum) + "]"); + + if (nRet == MyCamera.MV_OK) + { + lock (BufForDriverLock) + { + if (m_BufForDriver == IntPtr.Zero || stFrameInfo.stFrameInfo.nFrameLen > m_nBufSizeForDriver) + { + if (m_BufForDriver != IntPtr.Zero) + { + Marshal.Release(m_BufForDriver); + m_BufForDriver = IntPtr.Zero; + } + + m_BufForDriver = Marshal.AllocHGlobal((Int32)stFrameInfo.stFrameInfo.nFrameLen); + if (m_BufForDriver == IntPtr.Zero) + { + return; + } + m_nBufSizeForDriver = stFrameInfo.stFrameInfo.nFrameLen; + } + + m_stFrameInfo = stFrameInfo.stFrameInfo; + CopyMemory(m_BufForDriver, stFrameInfo.pBufAddr, stFrameInfo.stFrameInfo.nFrameLen); + } + + if (RemoveCustomPixelFormats(stFrameInfo.stFrameInfo.enPixelType)) + { + _dev.MV_CC_FreeImageBuffer_NET(ref stFrameInfo); + continue; + } + //从缓存区获取图片 + IntPtr pTemp = IntPtr.Zero; + MyCamera.MvGvspPixelType enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Undefined; + if (m_stFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8) + { + pTemp = m_BufForDriver; + enDstPixelType = m_stFrameInfo.enPixelType; + } + else + { + //ErrorMsgEvent(DeviceName + " -> 图像格式错误"); + } + + _dev.MV_CC_FreeImageBuffer_NET(ref stFrameInfo); + + //************************Mono8 转 Bitmap******************************* + Bitmap bmp = new Bitmap(m_stFrameInfo.nWidth, m_stFrameInfo.nHeight, m_stFrameInfo.nWidth * 1, PixelFormat.Format8bppIndexed, pTemp); + ColorPalette cp = bmp.Palette; + + for (int i = 0; i < 256; i++) + { + cp.Entries[i] = Color.FromArgb(i, i, i); + } + bmp.Palette = cp; + OutputImageEvent(bmp); + } + else + { + Thread.Sleep(10); + } + } + _stopAcqToken.Cancel(); + } + private bool RemoveCustomPixelFormats(MyCamera.MvGvspPixelType enPixelFormat) + { + Int32 nResult = ((int)enPixelFormat) & (unchecked((Int32)0x80000000)); + if (0x80000000 == nResult) + { + return true; + } + else + { + return false; + } + } + //public Bitmap Trigger() + //{ + // if (_dev == null) + // { + // throw new Exception(String.Format("相机触发失败,原因:该设备未连接")); + // } + // _dev.MV_CC_SetEnumValue_NET("TriggerSelector", 6); + // int nRet = _dev.MV_CC_SetCommandValue_NET("TriggerSoftware"); + // if (MyCamera.MV_OK != nRet) + // { + // throw new Exception(String.Format("相机触发失败")); + // } + + // MyCamera.MV_FRAME_OUT stFrameInfo = new MyCamera.MV_FRAME_OUT(); + // nRet = _dev.MV_CC_GetImageBuffer_NET(ref stFrameInfo, 1000); + // if (nRet == MyCamera.MV_OK) + // { + // lock (BufForDriverLock) + // { + // if (m_BufForDriver == IntPtr.Zero || stFrameInfo.stFrameInfo.nFrameLen > m_nBufSizeForDriver) + // { + // if (m_BufForDriver != IntPtr.Zero) + // { + // Marshal.Release(m_BufForDriver); + // m_BufForDriver = IntPtr.Zero; + // } + + // m_BufForDriver = Marshal.AllocHGlobal((Int32)stFrameInfo.stFrameInfo.nFrameLen); + // if (m_BufForDriver == IntPtr.Zero) + // { + // return null; + // } + // m_nBufSizeForDriver = stFrameInfo.stFrameInfo.nFrameLen; + // } + + // m_stFrameInfo = stFrameInfo.stFrameInfo; + // CopyMemory(m_BufForDriver, stFrameInfo.pBufAddr, stFrameInfo.stFrameInfo.nFrameLen); + // } + + // if (RemoveCustomPixelFormats(stFrameInfo.stFrameInfo.enPixelType)) + // { + // _dev.MV_CC_FreeImageBuffer_NET(ref stFrameInfo); + // return null; + // } + // //从缓存区获取图片 + // IntPtr pTemp = IntPtr.Zero; + // MyCamera.MvGvspPixelType enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Undefined; + // if (m_stFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8) + // { + // pTemp = m_BufForDriver; + // enDstPixelType = m_stFrameInfo.enPixelType; + // } + + // _dev.MV_CC_FreeImageBuffer_NET(ref stFrameInfo); + + // //************************Mono8 转 Bitmap******************************* + // Bitmap bmp = new Bitmap(m_stFrameInfo.nWidth, m_stFrameInfo.nHeight, m_stFrameInfo.nWidth * 1, PixelFormat.Format8bppIndexed, pTemp); + // ColorPalette cp = bmp.Palette; + // for (int i = 0; i < 256; i++) + // { + // cp.Entries[i] = Color.FromArgb(i, i, i); + // } + // bmp.Palette = cp; + // return bmp; + // } + // else + // { + // return null; + // } + + //} + + //private bool RemoveCustomPixelFormats(MyCamera.MvGvspPixelType enPixelFormat) + //{ + // Int32 nResult = ((int)enPixelFormat) & (unchecked((Int32)0x80000000)); + // if (0x80000000 == nResult) + // { + // return true; + // } + // else + // { + // return false; + // } + //} + } + + public class SiemensS7 + { + private SiemensS7Net _s7; + private string _ip; + public bool OK { get; private set; } + private System.Timers.Timer _reconnectTimer; + + public SiemensS7(string ip) + { + OK = false; + _ip = ip; + + _reconnectTimer = new System.Timers.Timer(5000); // 设置定时器为5秒 + _reconnectTimer.Elapsed += ReconnectTimerElapsed; + _reconnectTimer.AutoReset = true; + } + //public void Connect() + //{ + // _s7 = new SiemensS7Net(SiemensPLCS.S1200); + // _s7.IpAddress = _ip; + // _s7.Port = 102; + // OperateResult operateResult = _s7.ConnectServer(); + // if (!operateResult.IsSuccess) + // { + // throw new Exception(string.Format("Siemens S7 S1200客户端连接失败")); + // } + //} + + + public void Connect() + { + _s7 = new SiemensS7Net(SiemensPLCS.S1200); + _s7.IpAddress = _ip; + _s7.Port = 102; + TryConnect(); + } + + private void TryConnect() + { + + OperateResult operateResult = _s7.ConnectServer(); + if (!operateResult.IsSuccess) + { + OK = false; + Console.WriteLine("Siemens S7 S1200客户端连接失败,5秒后重试..."); + _reconnectTimer.Start(); // 启动定时器 + } + else + { + OK = true; + Console.WriteLine("Siemens S7 S1200客户端连接成功"); + _reconnectTimer.Stop(); // 停止定时器 + } + } + + private void ReconnectTimerElapsed(object sender, ElapsedEventArgs e) + { + Console.WriteLine("尝试重新连接..."); + TryConnect(); + } + public void Disconnect() + { + if (_s7 == null) + { + throw new Exception(string.Format("Siemens S7 S1200通信未连接")); + } + OperateResult operateResult = _s7.ConnectClose(); + if (!operateResult.IsSuccess) + { + throw new Exception(string.Format("Siemens S7 S1200客户端断开失败")); + } + } + public bool GetValue(string address, out bool value) + { + if (_s7 == null) + { + throw new Exception(string.Format("Siemens S7 S1200通信未连接")); + } + OperateResult boolResult = _s7.ReadBool(address); + if (boolResult.IsSuccess) + { + value = boolResult.Content; + return true; + } + else + { + value = false; + return false; + } + } + public void SetValue(string address, bool value) + { + if (_s7 == null) + { + throw new Exception(string.Format("Siemens S7 S1200通信未连接")); + } + if (!_s7.Write(address, value).IsSuccess) + { + throw new Exception(string.Format("Siemens S7 S1500客户端发送数据失败")); + } + } + + public void SetValue(string address, int value) + { + if (_s7 == null) + { + throw new Exception(string.Format("Siemens S7 S1200通信未连接")); + } + if (!_s7.Write(address, value).IsSuccess) + { + throw new Exception(string.Format("Siemens S7 S1500客户端发送数据失败")); + } + } + + public void SetValue(string address, uint value) + { + if (_s7 == null) + { + throw new Exception(string.Format("Siemens S7 S1200通信未连接")); + } + if (!_s7.Write(address, value).IsSuccess) + { + throw new Exception(string.Format("Siemens S7 S1500客户端发送数据失败")); + } + } + + public void SetValue(string address, short value) + { + if (_s7 == null) + { + throw new Exception(string.Format("Siemens S7 S1200通信未连接")); + } + if (!_s7.Write(address, value).IsSuccess) + { + throw new Exception(string.Format("Siemens S7 S1500客户端发送数据失败")); + } + } + public void SetValue(string address, ushort value) + { + if (_s7 == null) + { + throw new Exception(string.Format("Siemens S7 S1200通信未连接")); + } + if (!_s7.Write(address, value).IsSuccess) + { + throw new Exception(string.Format("Siemens S7 S1500客户端发送数据失败")); + } + } + public void SetValue(string address, float value) + { + if (_s7 == null) + { + throw new Exception(string.Format("Siemens S7 S1200通信未连接")); + } + if (!_s7.Write(address, value).IsSuccess) + { + throw new Exception(string.Format("Siemens S7 S1500客户端发送数据失败")); + } + } + } +} diff --git a/WaferAlignment/CenterOfRotation.cs b/WaferAlignment/CenterOfRotation.cs new file mode 100644 index 0000000..7c61a34 --- /dev/null +++ b/WaferAlignment/CenterOfRotation.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Serialization; + +namespace WaferAlignment +{ + [XmlRootAttribute("CenterOfRotation", IsNullable = false)] + + public class CenterOfRotation + { + private double center_X = 0; + private double center_Y = 0; + [XmlElementAttribute("Center_X")] + public double Center_X + { + get { return center_X; } + set { center_X = value; } + } + [XmlElementAttribute("Center_Y")] + + public double Center_Y + { + get { return center_Y; } + set { center_Y = value; } + } + } +} diff --git a/WaferAlignment/ConfigStore.cs b/WaferAlignment/ConfigStore.cs new file mode 100644 index 0000000..a223eee --- /dev/null +++ b/WaferAlignment/ConfigStore.cs @@ -0,0 +1,63 @@ +using System; +using System.IO; +using System.Text; +using System.Xml; +using System.Xml.Serialization; + +namespace ConVX.VXData +{ + public class ConfigStore + { + + public object ReadConfigFromFile(Type objectType, string filePath) + { + try + { + + object mxml = new object(); + + XmlSerializer serializer = new XmlSerializer(objectType); + + StreamReader reader = new StreamReader(filePath); + + mxml = serializer.Deserialize(reader); + + reader.Close(); + return mxml; + + } + catch (Exception ex) + { + throw new Exception(ex.Message); + } + } + + public void WriteConfigToFile(object config, Type objectType, string filePath) + { + try + { + object mConfig = new object(); + mConfig = config; + XmlSerializer serializer = new XmlSerializer(objectType); + + XmlWriterSettings settings = new XmlWriterSettings(); + settings.Indent = true; + settings.Encoding = Encoding.Unicode; + + StringWriter txtwriter = new StringWriter(); + XmlWriter xmlwtr = XmlWriter.Create(txtwriter, settings); + serializer.Serialize(xmlwtr, mConfig); + + StreamWriter writer = new StreamWriter(filePath); + writer.Write(txtwriter.ToString()); + + writer.Close(); + txtwriter.Close(); + } + catch (Exception ex) + { + throw new Exception(ex.Message); + } + } + } +} diff --git a/WaferAlignment/DataPostbox.cs b/WaferAlignment/DataPostbox.cs new file mode 100644 index 0000000..d814cad --- /dev/null +++ b/WaferAlignment/DataPostbox.cs @@ -0,0 +1,138 @@ +using Cognex.VisionPro; +using System; +using System.Collections.Concurrent; +using System.Threading; +using System.Threading.Tasks; + +namespace ConVX.VXData +{ + public class DataPostbox + { + #region 字段 + /// + /// 图像队列:来存储数据信封(CogImage8Grey)的队列。 + /// + private ConcurrentQueue _queue; + /// + /// 判断线程状态 + /// + private AutoResetEvent _autoReset = null; + /// + /// 线程 + /// + private Task _task; + /// + /// 控制任务启动 + /// + private CancellationTokenSource RuningToken; + /// + /// 控制任务终止 + /// + private CancellationTokenSource StopToken; + /// + /// 最大队列容量 + /// + private int _maxQueueSize = 10; + #endregion + + #region 事件 + /// + /// 当有信件被派发时触发的事件。 + /// + public event Action DeliverLetterEvent; + /// + /// 当发生错误时触发的事件。 + /// + public event Action ErrorEvent; + #endregion + + #region 公开的方法 + /// + /// 构造函数 + /// + public DataPostbox() + { + _queue = new ConcurrentQueue(); + _autoReset = new AutoResetEvent(false);//线程非终止状态 + } + /// + /// 启动派发 + /// + public void Start() + { + RuningToken = new CancellationTokenSource();//创建启动 + _task = new Task(() => EnvelopeProcessing(), RuningToken.Token); + _task.Start();//线程启动 + } + /// + /// 停止派发 + /// + public async void Stop() + { + try + { + RuningToken.Cancel(); + _autoReset.Set();//为了避免线程正在执行或等待状态 + await _task; + } + catch (OperationCanceledException ex) + { + _task.Dispose(); + _task = null; + } + } + /// + /// 邮寄信件 + /// + /// 信息信件 + public void Mailing(CogImage8Grey envelope) + { + //if (_queue.Count > _maxQueueSize) + //{ + // ErrorEvent(string.Format("数据队列超出队列最大容量{0}", _maxQueueSize)); + //} + //else + //{ + // _queue.Enqueue(envelope); + // _autoReset.Set(); + //} + + _queue.Enqueue(envelope); + _autoReset.Set(); + } + #endregion + + #region 数据处理线程 + private void EnvelopeProcessing() + { + StopToken = new CancellationTokenSource(); + while (!RuningToken.IsCancellationRequested) + { + if (_queue.IsEmpty) + { + _autoReset.WaitOne(); + } + else + { + try + { + CogImage8Grey envelope; + if (_queue.TryDequeue(out envelope)) + { + DeliverLetterEvent(envelope); + } + Thread.Sleep(20); + } + catch (Exception ex) + { + ErrorEvent(string.Format("数据队列出队失败,原因:{0}", ex.Message.ToString())); + } + } + } + StopToken.Cancel(); + } + #endregion + + + } +} diff --git a/WaferAlignment/FlyTcpFramework.dll b/WaferAlignment/FlyTcpFramework.dll new file mode 100644 index 0000000..0a93f1e Binary files /dev/null and b/WaferAlignment/FlyTcpFramework.dll differ diff --git a/WaferAlignment/Form1.Designer.cs b/WaferAlignment/Form1.Designer.cs new file mode 100644 index 0000000..80069f2 --- /dev/null +++ b/WaferAlignment/Form1.Designer.cs @@ -0,0 +1,562 @@ +namespace WaferAlignment +{ + partial class Form1 + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows 窗体设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.cogRecordDisplay1 = new Cognex.VisionPro.CogRecordDisplay(); + this.lbl_Time = new System.Windows.Forms.Label(); + this.txt_Time = new System.Windows.Forms.TextBox(); + this.lbl_Times = new System.Windows.Forms.Label(); + this.txt_Times = new System.Windows.Forms.TextBox(); + this.lbl_RMS = new System.Windows.Forms.Label(); + this.txt_RMS = new System.Windows.Forms.TextBox(); + this.lbl_RotationR = new System.Windows.Forms.Label(); + this.txt_RR = new System.Windows.Forms.TextBox(); + this.lbl_CommunState = new System.Windows.Forms.Label(); + this.lbl_Commun = new System.Windows.Forms.Label(); + this.lbl_CameraState = new System.Windows.Forms.Label(); + this.lbl_Camera = new System.Windows.Forms.Label(); + this.lbl_DR = new System.Windows.Forms.Label(); + this.txt_DR = new System.Windows.Forms.TextBox(); + this.lbl_DY = new System.Windows.Forms.Label(); + this.txt_DY = new System.Windows.Forms.TextBox(); + this.lbl_DX = new System.Windows.Forms.Label(); + this.txt_DX = new System.Windows.Forms.TextBox(); + this.lbl_RotationY = new System.Windows.Forms.Label(); + this.txt_RY = new System.Windows.Forms.TextBox(); + this.lbl_RotationX = new System.Windows.Forms.Label(); + this.txt_RX = new System.Windows.Forms.TextBox(); + this.dataGridView1 = new System.Windows.Forms.DataGridView(); + this.Column1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.Column2 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.Column3 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.Column4 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.btn_RunTest = new System.Windows.Forms.Button(); + this.lbl_R = new System.Windows.Forms.Label(); + this.nud_SizeR = new System.Windows.Forms.NumericUpDown(); + this.lbl_Y = new System.Windows.Forms.Label(); + this.nud_SizeY = new System.Windows.Forms.NumericUpDown(); + this.lbl_X = new System.Windows.Forms.Label(); + this.nud_SizeX = new System.Windows.Forms.NumericUpDown(); + this.btn_Action = new System.Windows.Forms.Button(); + this.btn_ToZero = new System.Windows.Forms.Button(); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.cogRecordDisplay1)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nud_SizeR)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nud_SizeY)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nud_SizeX)).BeginInit(); + this.SuspendLayout(); + // + // splitContainer1 + // + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel2; + this.splitContainer1.Location = new System.Drawing.Point(0, 0); + this.splitContainer1.Name = "splitContainer1"; + this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.Controls.Add(this.cogRecordDisplay1); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.lbl_Time); + this.splitContainer1.Panel2.Controls.Add(this.txt_Time); + this.splitContainer1.Panel2.Controls.Add(this.lbl_Times); + this.splitContainer1.Panel2.Controls.Add(this.txt_Times); + this.splitContainer1.Panel2.Controls.Add(this.lbl_RMS); + this.splitContainer1.Panel2.Controls.Add(this.txt_RMS); + this.splitContainer1.Panel2.Controls.Add(this.lbl_RotationR); + this.splitContainer1.Panel2.Controls.Add(this.txt_RR); + this.splitContainer1.Panel2.Controls.Add(this.lbl_CommunState); + this.splitContainer1.Panel2.Controls.Add(this.lbl_Commun); + this.splitContainer1.Panel2.Controls.Add(this.lbl_CameraState); + this.splitContainer1.Panel2.Controls.Add(this.lbl_Camera); + this.splitContainer1.Panel2.Controls.Add(this.lbl_DR); + this.splitContainer1.Panel2.Controls.Add(this.txt_DR); + this.splitContainer1.Panel2.Controls.Add(this.lbl_DY); + this.splitContainer1.Panel2.Controls.Add(this.txt_DY); + this.splitContainer1.Panel2.Controls.Add(this.lbl_DX); + this.splitContainer1.Panel2.Controls.Add(this.txt_DX); + this.splitContainer1.Panel2.Controls.Add(this.lbl_RotationY); + this.splitContainer1.Panel2.Controls.Add(this.txt_RY); + this.splitContainer1.Panel2.Controls.Add(this.lbl_RotationX); + this.splitContainer1.Panel2.Controls.Add(this.txt_RX); + this.splitContainer1.Panel2.Controls.Add(this.dataGridView1); + this.splitContainer1.Panel2.Controls.Add(this.btn_RunTest); + this.splitContainer1.Panel2.Controls.Add(this.lbl_R); + this.splitContainer1.Panel2.Controls.Add(this.nud_SizeR); + this.splitContainer1.Panel2.Controls.Add(this.lbl_Y); + this.splitContainer1.Panel2.Controls.Add(this.nud_SizeY); + this.splitContainer1.Panel2.Controls.Add(this.lbl_X); + this.splitContainer1.Panel2.Controls.Add(this.nud_SizeX); + this.splitContainer1.Panel2.Controls.Add(this.btn_Action); + this.splitContainer1.Panel2.Controls.Add(this.btn_ToZero); + this.splitContainer1.Size = new System.Drawing.Size(885, 806); + this.splitContainer1.SplitterDistance = 558; + this.splitContainer1.TabIndex = 1; + // + // cogRecordDisplay1 + // + this.cogRecordDisplay1.ColorMapLowerClipColor = System.Drawing.Color.Black; + this.cogRecordDisplay1.ColorMapLowerRoiLimit = 0D; + this.cogRecordDisplay1.ColorMapPredefined = Cognex.VisionPro.Display.CogDisplayColorMapPredefinedConstants.None; + this.cogRecordDisplay1.ColorMapUpperClipColor = System.Drawing.Color.Black; + this.cogRecordDisplay1.ColorMapUpperRoiLimit = 1D; + this.cogRecordDisplay1.Dock = System.Windows.Forms.DockStyle.Fill; + this.cogRecordDisplay1.DoubleTapZoomCycleLength = 2; + this.cogRecordDisplay1.DoubleTapZoomSensitivity = 2.5D; + this.cogRecordDisplay1.Location = new System.Drawing.Point(0, 0); + this.cogRecordDisplay1.MouseWheelMode = Cognex.VisionPro.Display.CogDisplayMouseWheelModeConstants.Zoom1; + this.cogRecordDisplay1.MouseWheelSensitivity = 1D; + this.cogRecordDisplay1.Name = "cogRecordDisplay1"; + this.cogRecordDisplay1.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("cogRecordDisplay1.OcxState"))); + this.cogRecordDisplay1.Size = new System.Drawing.Size(885, 558); + this.cogRecordDisplay1.TabIndex = 0; + // + // lbl_Time + // + this.lbl_Time.AutoSize = true; + this.lbl_Time.Location = new System.Drawing.Point(655, 25); + this.lbl_Time.Name = "lbl_Time"; + this.lbl_Time.Size = new System.Drawing.Size(65, 12); + this.lbl_Time.TabIndex = 32; + this.lbl_Time.Text = "检测时间:"; + // + // txt_Time + // + this.txt_Time.Location = new System.Drawing.Point(741, 22); + this.txt_Time.Name = "txt_Time"; + this.txt_Time.ReadOnly = true; + this.txt_Time.Size = new System.Drawing.Size(129, 21); + this.txt_Time.TabIndex = 31; + // + // lbl_Times + // + this.lbl_Times.AutoSize = true; + this.lbl_Times.Location = new System.Drawing.Point(234, 15); + this.lbl_Times.Name = "lbl_Times"; + this.lbl_Times.Size = new System.Drawing.Size(89, 12); + this.lbl_Times.TabIndex = 30; + this.lbl_Times.Text = "整体检测时间:"; + // + // txt_Times + // + this.txt_Times.Location = new System.Drawing.Point(326, 12); + this.txt_Times.Name = "txt_Times"; + this.txt_Times.ReadOnly = true; + this.txt_Times.Size = new System.Drawing.Size(129, 21); + this.txt_Times.TabIndex = 29; + // + // lbl_RMS + // + this.lbl_RMS.AutoSize = true; + this.lbl_RMS.Location = new System.Drawing.Point(655, 133); + this.lbl_RMS.Name = "lbl_RMS"; + this.lbl_RMS.Size = new System.Drawing.Size(71, 12); + this.lbl_RMS.TabIndex = 28; + this.lbl_RMS.Text = "RMS偏差量:"; + // + // txt_RMS + // + this.txt_RMS.Location = new System.Drawing.Point(741, 130); + this.txt_RMS.Name = "txt_RMS"; + this.txt_RMS.ReadOnly = true; + this.txt_RMS.Size = new System.Drawing.Size(129, 21); + this.txt_RMS.TabIndex = 27; + // + // lbl_RotationR + // + this.lbl_RotationR.AutoSize = true; + this.lbl_RotationR.Location = new System.Drawing.Point(655, 106); + this.lbl_RotationR.Name = "lbl_RotationR"; + this.lbl_RotationR.Size = new System.Drawing.Size(77, 12); + this.lbl_RotationR.TabIndex = 26; + this.lbl_RotationR.Text = "拟合半径 R:"; + // + // txt_RR + // + this.txt_RR.Location = new System.Drawing.Point(741, 103); + this.txt_RR.Name = "txt_RR"; + this.txt_RR.ReadOnly = true; + this.txt_RR.Size = new System.Drawing.Size(129, 21); + this.txt_RR.TabIndex = 25; + // + // lbl_CommunState + // + this.lbl_CommunState.BackColor = System.Drawing.Color.Red; + this.lbl_CommunState.ForeColor = System.Drawing.Color.White; + this.lbl_CommunState.Location = new System.Drawing.Point(86, 45); + this.lbl_CommunState.Name = "lbl_CommunState"; + this.lbl_CommunState.Size = new System.Drawing.Size(89, 23); + this.lbl_CommunState.TabIndex = 24; + this.lbl_CommunState.Text = "未连接"; + this.lbl_CommunState.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // lbl_Commun + // + this.lbl_Commun.AutoSize = true; + this.lbl_Commun.Location = new System.Drawing.Point(15, 50); + this.lbl_Commun.Name = "lbl_Commun"; + this.lbl_Commun.Size = new System.Drawing.Size(59, 12); + this.lbl_Commun.TabIndex = 23; + this.lbl_Commun.Text = "PLC状态:"; + // + // lbl_CameraState + // + this.lbl_CameraState.BackColor = System.Drawing.Color.Red; + this.lbl_CameraState.ForeColor = System.Drawing.Color.White; + this.lbl_CameraState.Location = new System.Drawing.Point(86, 12); + this.lbl_CameraState.Name = "lbl_CameraState"; + this.lbl_CameraState.Size = new System.Drawing.Size(89, 23); + this.lbl_CameraState.TabIndex = 22; + this.lbl_CameraState.Text = "未连接"; + this.lbl_CameraState.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // lbl_Camera + // + this.lbl_Camera.AutoSize = true; + this.lbl_Camera.Location = new System.Drawing.Point(15, 17); + this.lbl_Camera.Name = "lbl_Camera"; + this.lbl_Camera.Size = new System.Drawing.Size(65, 12); + this.lbl_Camera.TabIndex = 21; + this.lbl_Camera.Text = "相机状态:"; + // + // lbl_DR + // + this.lbl_DR.AutoSize = true; + this.lbl_DR.Location = new System.Drawing.Point(655, 214); + this.lbl_DR.Name = "lbl_DR"; + this.lbl_DR.Size = new System.Drawing.Size(65, 12); + this.lbl_DR.TabIndex = 20; + this.lbl_DR.Text = "偏差量 R:"; + // + // txt_DR + // + this.txt_DR.Location = new System.Drawing.Point(741, 211); + this.txt_DR.Name = "txt_DR"; + this.txt_DR.ReadOnly = true; + this.txt_DR.Size = new System.Drawing.Size(129, 21); + this.txt_DR.TabIndex = 19; + // + // lbl_DY + // + this.lbl_DY.AutoSize = true; + this.lbl_DY.Location = new System.Drawing.Point(655, 187); + this.lbl_DY.Name = "lbl_DY"; + this.lbl_DY.Size = new System.Drawing.Size(65, 12); + this.lbl_DY.TabIndex = 18; + this.lbl_DY.Text = "偏差量 Y:"; + // + // txt_DY + // + this.txt_DY.Location = new System.Drawing.Point(741, 184); + this.txt_DY.Name = "txt_DY"; + this.txt_DY.ReadOnly = true; + this.txt_DY.Size = new System.Drawing.Size(129, 21); + this.txt_DY.TabIndex = 17; + // + // lbl_DX + // + this.lbl_DX.AutoSize = true; + this.lbl_DX.Location = new System.Drawing.Point(655, 160); + this.lbl_DX.Name = "lbl_DX"; + this.lbl_DX.Size = new System.Drawing.Size(65, 12); + this.lbl_DX.TabIndex = 16; + this.lbl_DX.Text = "偏差量 X:"; + // + // txt_DX + // + this.txt_DX.Location = new System.Drawing.Point(741, 157); + this.txt_DX.Name = "txt_DX"; + this.txt_DX.ReadOnly = true; + this.txt_DX.Size = new System.Drawing.Size(129, 21); + this.txt_DX.TabIndex = 15; + // + // lbl_RotationY + // + this.lbl_RotationY.AutoSize = true; + this.lbl_RotationY.Location = new System.Drawing.Point(655, 79); + this.lbl_RotationY.Name = "lbl_RotationY"; + this.lbl_RotationY.Size = new System.Drawing.Size(77, 12); + this.lbl_RotationY.TabIndex = 14; + this.lbl_RotationY.Text = "拟合中心 Y:"; + // + // txt_RY + // + this.txt_RY.Location = new System.Drawing.Point(741, 76); + this.txt_RY.Name = "txt_RY"; + this.txt_RY.ReadOnly = true; + this.txt_RY.Size = new System.Drawing.Size(129, 21); + this.txt_RY.TabIndex = 13; + // + // lbl_RotationX + // + this.lbl_RotationX.AutoSize = true; + this.lbl_RotationX.Location = new System.Drawing.Point(655, 52); + this.lbl_RotationX.Name = "lbl_RotationX"; + this.lbl_RotationX.Size = new System.Drawing.Size(77, 12); + this.lbl_RotationX.TabIndex = 12; + this.lbl_RotationX.Text = "拟合中心 X:"; + // + // txt_RX + // + this.txt_RX.Location = new System.Drawing.Point(741, 49); + this.txt_RX.Name = "txt_RX"; + this.txt_RX.ReadOnly = true; + this.txt_RX.Size = new System.Drawing.Size(129, 21); + this.txt_RX.TabIndex = 11; + // + // dataGridView1 + // + this.dataGridView1.AllowUserToAddRows = false; + this.dataGridView1.AllowUserToDeleteRows = false; + this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.Column1, + this.Column2, + this.Column3, + this.Column4}); + this.dataGridView1.Location = new System.Drawing.Point(181, 53); + this.dataGridView1.Name = "dataGridView1"; + this.dataGridView1.ReadOnly = true; + this.dataGridView1.RowTemplate.Height = 23; + this.dataGridView1.Size = new System.Drawing.Size(461, 188); + this.dataGridView1.TabIndex = 10; + // + // Column1 + // + this.Column1.HeaderText = "角度"; + this.Column1.Name = "Column1"; + this.Column1.ReadOnly = true; + // + // Column2 + // + this.Column2.HeaderText = "X"; + this.Column2.Name = "Column2"; + this.Column2.ReadOnly = true; + // + // Column3 + // + this.Column3.HeaderText = "Y"; + this.Column3.Name = "Column3"; + this.Column3.ReadOnly = true; + // + // Column4 + // + this.Column4.HeaderText = "检测时间"; + this.Column4.Name = "Column4"; + this.Column4.ReadOnly = true; + // + // btn_RunTest + // + this.btn_RunTest.Location = new System.Drawing.Point(481, 12); + this.btn_RunTest.Name = "btn_RunTest"; + this.btn_RunTest.Size = new System.Drawing.Size(161, 23); + this.btn_RunTest.TabIndex = 9; + this.btn_RunTest.Text = "启动检测"; + this.btn_RunTest.UseVisualStyleBackColor = true; + this.btn_RunTest.Click += new System.EventHandler(this.btn_RunTest_Click); + // + // lbl_R + // + this.lbl_R.AutoSize = true; + this.lbl_R.Location = new System.Drawing.Point(15, 193); + this.lbl_R.Name = "lbl_R"; + this.lbl_R.Size = new System.Drawing.Size(59, 12); + this.lbl_R.TabIndex = 7; + this.lbl_R.Text = "R轴位置:"; + // + // nud_SizeR + // + this.nud_SizeR.DecimalPlaces = 2; + this.nud_SizeR.Location = new System.Drawing.Point(80, 191); + this.nud_SizeR.Maximum = new decimal(new int[] { + 360, + 0, + 0, + 0}); + this.nud_SizeR.Minimum = new decimal(new int[] { + 360, + 0, + 0, + -2147483648}); + this.nud_SizeR.Name = "nud_SizeR"; + this.nud_SizeR.Size = new System.Drawing.Size(95, 21); + this.nud_SizeR.TabIndex = 8; + // + // lbl_Y + // + this.lbl_Y.AutoSize = true; + this.lbl_Y.Location = new System.Drawing.Point(15, 166); + this.lbl_Y.Name = "lbl_Y"; + this.lbl_Y.Size = new System.Drawing.Size(59, 12); + this.lbl_Y.TabIndex = 5; + this.lbl_Y.Text = "Y轴位置:"; + // + // nud_SizeY + // + this.nud_SizeY.DecimalPlaces = 2; + this.nud_SizeY.Location = new System.Drawing.Point(80, 164); + this.nud_SizeY.Minimum = new decimal(new int[] { + 100, + 0, + 0, + -2147483648}); + this.nud_SizeY.Name = "nud_SizeY"; + this.nud_SizeY.Size = new System.Drawing.Size(95, 21); + this.nud_SizeY.TabIndex = 6; + this.nud_SizeY.Value = new decimal(new int[] { + 1, + 0, + 0, + -2147483648}); + // + // lbl_X + // + this.lbl_X.AutoSize = true; + this.lbl_X.Location = new System.Drawing.Point(15, 139); + this.lbl_X.Name = "lbl_X"; + this.lbl_X.Size = new System.Drawing.Size(59, 12); + this.lbl_X.TabIndex = 3; + this.lbl_X.Text = "X轴位置:"; + // + // nud_SizeX + // + this.nud_SizeX.DecimalPlaces = 2; + this.nud_SizeX.Location = new System.Drawing.Point(80, 137); + this.nud_SizeX.Minimum = new decimal(new int[] { + 100, + 0, + 0, + -2147483648}); + this.nud_SizeX.Name = "nud_SizeX"; + this.nud_SizeX.Size = new System.Drawing.Size(95, 21); + this.nud_SizeX.TabIndex = 4; + this.nud_SizeX.Value = new decimal(new int[] { + 1, + 0, + 0, + 0}); + // + // btn_Action + // + this.btn_Action.Location = new System.Drawing.Point(14, 218); + this.btn_Action.Name = "btn_Action"; + this.btn_Action.Size = new System.Drawing.Size(161, 23); + this.btn_Action.TabIndex = 1; + this.btn_Action.Text = "执行动作"; + this.btn_Action.UseVisualStyleBackColor = true; + this.btn_Action.Click += new System.EventHandler(this.btn_Action_Click); + // + // btn_ToZero + // + this.btn_ToZero.Location = new System.Drawing.Point(17, 99); + this.btn_ToZero.Name = "btn_ToZero"; + this.btn_ToZero.Size = new System.Drawing.Size(161, 23); + this.btn_ToZero.TabIndex = 0; + this.btn_ToZero.Text = "三轴回零"; + this.btn_ToZero.UseVisualStyleBackColor = true; + this.btn_ToZero.Click += new System.EventHandler(this.btn_ToZero_Click); + // + // Form1 + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(885, 806); + this.Controls.Add(this.splitContainer1); + this.Name = "Form1"; + this.Text = "晶圆对位验证程序"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing); + this.Load += new System.EventHandler(this.Form1_Load); + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel2.ResumeLayout(false); + this.splitContainer1.Panel2.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); + this.splitContainer1.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.cogRecordDisplay1)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nud_SizeR)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nud_SizeY)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nud_SizeX)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.SplitContainer splitContainer1; + private Cognex.VisionPro.CogRecordDisplay cogRecordDisplay1; + private System.Windows.Forms.Button btn_ToZero; + private System.Windows.Forms.Label lbl_R; + private System.Windows.Forms.NumericUpDown nud_SizeR; + private System.Windows.Forms.Label lbl_Y; + private System.Windows.Forms.NumericUpDown nud_SizeY; + private System.Windows.Forms.Label lbl_X; + private System.Windows.Forms.NumericUpDown nud_SizeX; + private System.Windows.Forms.Button btn_Action; + private System.Windows.Forms.Button btn_RunTest; + private System.Windows.Forms.Label lbl_RotationY; + private System.Windows.Forms.TextBox txt_RY; + private System.Windows.Forms.Label lbl_RotationX; + private System.Windows.Forms.TextBox txt_RX; + private System.Windows.Forms.DataGridView dataGridView1; + private System.Windows.Forms.Label lbl_DY; + private System.Windows.Forms.TextBox txt_DY; + private System.Windows.Forms.Label lbl_DX; + private System.Windows.Forms.TextBox txt_DX; + private System.Windows.Forms.Label lbl_DR; + private System.Windows.Forms.TextBox txt_DR; + private System.Windows.Forms.Label lbl_CameraState; + private System.Windows.Forms.Label lbl_Camera; + private System.Windows.Forms.Label lbl_CommunState; + private System.Windows.Forms.Label lbl_Commun; + private System.Windows.Forms.Label lbl_RotationR; + private System.Windows.Forms.TextBox txt_RR; + private System.Windows.Forms.Label lbl_RMS; + private System.Windows.Forms.TextBox txt_RMS; + private System.Windows.Forms.Label lbl_Times; + private System.Windows.Forms.TextBox txt_Times; + private System.Windows.Forms.DataGridViewTextBoxColumn Column1; + private System.Windows.Forms.DataGridViewTextBoxColumn Column2; + private System.Windows.Forms.DataGridViewTextBoxColumn Column3; + private System.Windows.Forms.DataGridViewTextBoxColumn Column4; + private System.Windows.Forms.Label lbl_Time; + private System.Windows.Forms.TextBox txt_Time; + + } +} + diff --git a/WaferAlignment/Form1.cs b/WaferAlignment/Form1.cs new file mode 100644 index 0000000..2b027bd --- /dev/null +++ b/WaferAlignment/Form1.cs @@ -0,0 +1,1072 @@ +using Cognex.VisionPro; +using Cognex.VisionPro.Dimensioning; +using Cognex.VisionPro.ImageFile; +using Cognex.VisionPro.ToolBlock; +using Cognex.VisionPro.ImageProcessing; +using Cognex.VisionPro.Caliper; +using ConVX.VXData; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.Xml.Serialization; +using System.Diagnostics; +using Cognex.VisionPro.PMAlign; + + +namespace WaferAlignment +{ + public partial class Form1 : Form + { + Camera _cam; + SiemensS7 _s7; + DataPostbox ImageData; + TCP _tcp; + + string arSizeX = "DB7.DBD48"; + string arSizeY = "DB7.DBD52"; + string arSizeR = "DB7.DBD56"; + string arSpeedX = "DB7.DBD60"; + string arSpeedY = "DB7.DBD64"; + string arSpeedR = "DB7.DBD68"; + /// + /// 执行模式 + /// + string arMode = "DB7.DBW72";// + /// + /// 执行上面设置的动作 + /// + string arAction = "DB7.DBX74.0"; + /// + ///动作执行完成 + /// + string arOver = "DB7.DBX74.1"; + string arLED = "M3.0"; + /// + /// 偏转角度 + /// + string arAngle = "DB7.DBD76";//设置触发拍照的偏转角度 + + + + string vppPath; + CogToolBlock mTB; + CogToolBlock mTB_1; + CogToolBlock mTB_2; + + + float R = 11.25F;//1024->12 + //CogImage8Grey OutputImg; + + //旋转中心的坐标应将标定的数据保存后获取 + double circleCenterX; + double circleCenterY; + //XML文件读取与写入 + ConfigStore _ConfigStore = new ConfigStore(); + CenterOfRotation _center = new CenterOfRotation(); + //偏差量 + double deviationX; + double deviationY; + + // + string TCP_time = "0"; + string TCP_X = "0"; + string TCP_Y = "0"; + string TCP_R = "0"; + string TCP_RMS = "0"; + + bool OKorNG = false;//判断检查是否完成 + // + + + public Form1() + { + InitializeComponent(); + } + private void Form1_Load(object sender, EventArgs e) + { + + // 连接相机 + try + { + _cam = new Camera(); + _cam.Connect(); + _cam.OutputImageEvent += _cam_OutputImageEvent; + lbl_CameraState.BackColor = Color.Lime; + lbl_CameraState.Text = "已连接"; + } + catch (Exception ex) + { + lbl_CameraState.BackColor = Color.Red; + lbl_CameraState.Text = "连接失败"; + MessageBox.Show(ex.Message); + } + // 连接通信 + try + { + _s7 = new SiemensS7("192.168.1.10"); + _s7.Connect(); + while (!_s7.OK) + { + + } + _s7.SetValue(arSpeedX, (float)2);//5 + _s7.SetValue(arSpeedY, (float)2);//2 + _s7.SetValue(arSpeedR, (float)360);//100 + _s7.SetValue(arSizeX, (float)0); + _s7.SetValue(arSizeY, (float)0); + _s7.SetValue(arSizeR, (float)0); + _s7.SetValue(arAngle, Convert.ToSingle(R));//角度为10 + lbl_CommunState.BackColor = Color.Lime; + lbl_CommunState.Text = "已连接"; + } + catch (Exception ex) + { + lbl_CommunState.BackColor = Color.Red; + lbl_CommunState.Text = "连接失败"; + MessageBox.Show(ex.Message); + } + //链接TCP通信 + try + { + //通信初始化 + _tcp = new TCP(); + _tcp.DataReceived += _tcp_DataReceived; + _tcp.StartServer(); + + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + + } + try + { + // 加载VPP文件 + vppPath = Path.Combine(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "vpp", "ToolBlock.vpp"); + + mTB = CogSerializer.LoadObjectFromFile(vppPath) as CogToolBlock; + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + } + try + { + ImageData = new DataPostbox(); + + //启动 + ImageData.Start(); + // 注册事件处理程序到 DeliverLetterEvent 事件中 + ImageData.DeliverLetterEvent += MonitorSpot;//查找所有点 + ImageData.ErrorEvent += ImageData_ErrorEvent; + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + + } + + // 指定XML文件路径 + string filePath = Path.Combine(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "vpp", "CenterOfRotation.xml"); //@"D:\晶圆寻边机\XML文件\CenterOfRotation.xml"; + _center = _ConfigStore.ReadConfigFromFile(_center.GetType(), filePath) as CenterOfRotation; + circleCenterX = _center.Center_X; + circleCenterY = _center.Center_Y; + } + /// + /// 接收到TCP数据时,根据接收到的数据,进行不同操作 + /// + /// + /// + private void _tcp_DataReceived(object sender, DataReceivedEventArgs e) + { + if (this.InvokeRequired) + { + // 如果当前线程不是UI线程,则使用Invoke在UI线程上执行 + this.Invoke(new Action(_tcp_DataReceived), sender, e); + } + else + { + if (e.Data == "T0") + { + string str; + str = ToZero(); + _tcp.SendData(e.ClientIp, str); + } + else if (e.Data == "GET") + { + string str; + str = ToAction(); + _tcp.SendData(e.ClientIp, str); + } + else if (e.Data == "RUN") + { + SavePath = Path.Combine(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "SaveImage", DateTime.Now.ToString("yyyyMMdd_HHmmss")); + + ClearDisplay(); + string str; + str = RunTest(); + _tcp.SendData(e.ClientIp, str); + _tcp.SendData(e.ClientIp, "DetectionTime:" + TCP_time + " " + "X:" + TCP_X + " " + "Y:" + TCP_Y + " " + "Angle:" + TCP_R + " " + "RMS:" + TCP_RMS); + } + } + + + } + + void _cam_OutputImageEvent(Bitmap obj) + { + lstNasR.Add((acqNum + 1) * R); + acqNum++; + //lstNasR.Add((testNum) * R); + //保存图像 + //SaveImage(new CogImage8Grey(obj)); + ImageData.Mailing(new CogImage8Grey(obj)); + Images.Add(new CogImage8Grey(obj)); + + } + + void ImageData_ErrorEvent(string obj) + { + //throw new NotImplementedException(); + } + + + private void Form1_FormClosing(object sender, FormClosingEventArgs e) + { + try + { + if (_s7 != null) + { + _s7.Disconnect(); + } + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + } + + try + { + if(_cam.IsStarted) + { + _cam.Stop(); + } + if (_cam.IsConnected) + { + _cam.Disconnect(); + } + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + } + try + { + + //停止位 + ImageData.Stop(); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + + } + try + { + _tcp.StopServer(); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + } + } + private void btn_ToZero_Click(object sender, EventArgs e) + { + Task.Run(() => + { + this.splitContainer1.Invoke(new Action(() => this.splitContainer1.Panel2.Enabled = false)); + string str = ""; + str = ToZero(); + MessageBox.Show(str); + + this.splitContainer1.Invoke(new Action(() => this.splitContainer1.Panel2.Enabled = true)); + }); + } + + public string ToZero() + { + if (_s7 != null) + { + + _s7.SetValue(arMode, (ushort)4); + _s7.SetValue(arAction, true); + Thread.Sleep(20); + while (true) + { + bool value = false; + if (_s7.GetValue(arOver, out value)) + { + if (value) + { + _s7.SetValue(arAction, false); + break; + } + else + { + Thread.Sleep(20); + continue; + } + } + else + { + Thread.Sleep(20); + continue; + } + } + return "OK_T0"; + } + else + { + return "NG_T0"; + } + } + private void btn_Action_Click(object sender, EventArgs e) + { + Task.Run(() => + { + this.splitContainer1.Invoke(new Action(() => this.splitContainer1.Panel2.Enabled = false)); + string str = ""; + str = ToAction(); + MessageBox.Show(str); + + this.splitContainer1.Invoke(new Action(() => this.splitContainer1.Panel2.Enabled = true)); + }); + } + + public string ToAction() + { + if (_s7 != null) + { + + _s7.SetValue(arMode, (ushort)0); + _s7.SetValue(arSizeX, Convert.ToSingle(nud_SizeX.Value)); + _s7.SetValue(arSizeY, Convert.ToSingle(nud_SizeY.Value)); + _s7.SetValue(arSizeR, Convert.ToSingle(nud_SizeR.Value)); + _s7.SetValue(arAction, true); + Thread.Sleep(20); + while (true) + { + bool value = false; + if (_s7.GetValue(arOver, out value)) + { + if (value) + { + _s7.SetValue(arAction, false); + break; + } + else + { + Thread.Sleep(20); + continue; + } + } + else + { + Thread.Sleep(20); + continue; + } + } + return "OK_GET"; + + } + else + { + return "NG_GET"; + } + } + + List lstRotation; + List lstX; + List lstY; + List lstRadius; + List lstNasX; + List lstNasY; + List lstNasR; + List Images; + + int acqNum = 0; + int testNum = 0; + double angle = 0; + Stopwatch sw_1 = new Stopwatch();//检测找点时间 + Stopwatch sw_2 = new Stopwatch();//检测拟合圆时间 + double times = 0;//整体检测时间 + private void btn_RunTest_Click(object sender, EventArgs e) + { + SavePath = Path.Combine(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "SaveImage", DateTime.Now.ToString("yyyyMMdd_HHmmss")); + + ClearDisplay(); + ////--------------------------------------- + Task.Run(() => + { + this.splitContainer1.Invoke(new Action(() => this.splitContainer1.Panel2.Enabled = false)); + string str = ""; + str = RunTest(); + MessageBox.Show(str); + + this.splitContainer1.Invoke(new Action(() => this.splitContainer1.Panel2.Enabled = true)); + }); + + //--------------------------------------- + } + + public string RunTest() + { + if (!_cam.IsConnected) + { + return "CF_CAM";//启动检测失败,相机未连接 + + } + else + { + + //R轴回0 + if (_s7 != null) + { + _s7.SetValue(arMode, (ushort)3);//写入PLC控制模式 3 + Thread.Sleep(100); + _s7.SetValue(arAction, true);//写入PLC控制 行动开始 + Thread.Sleep(20); + while (true)//判断运动是否结束 + { + bool value = false; + if (_s7.GetValue(arOver, out value))//读取地址为arOver的结束数据是否成功 并返回读取结果 + { + if (value)//判断读取结束结果 + { + _s7.SetValue(arAction, false);//写入PLC控制 行动结束 + break; + } + else + { + Thread.Sleep(20); + continue; + } + } + else + { + Thread.Sleep(20); + continue; + } + } + } + Thread.Sleep(500); + + _cam.Start(); + if (!_cam.IsStarted) + { + return "SF_CAM";//启动检测失败,相机启动失败 + + } + else + { + angle = 0; + acqNum = 0; + testNum = 0; + lstRotation = new List(); + lstX = new List(); + lstY = new List(); + lstRadius = new List(); + lstNasX = new List(); + lstNasY = new List(); + lstNasR = new List(); + Images = new List(); + + sw_1 = new Stopwatch();//检测时间 + sw_2 = new Stopwatch();//检测时间 + deviationX = 0; + deviationY = 0; + times = 0; + //启动拍照 + + if (_s7 != null) + { + //_s7.SetValue(arOver, false); + //_s7.SetValue(arMode, (ushort)5);//写入PLC控制模式 5 启动拍照 + _s7.SetValue(arMode, (ushort)0);//写入PLC控制模式 0 启动拍照 + _s7.SetValue(arSizeR, 360F); + //Thread.Sleep(100); + _s7.SetValue(arAction, true);//写入PLC控制 行动开始 + + //Thread.Sleep(100); + while (true)//判断运动是否结束 + { + bool value = false; + if (_s7.GetValue(arOver, out value)) + { + if (value) + { + _s7.SetValue(arAction, false); + break; + } + else + { + Thread.Sleep(20); + continue; + } + } + else + { + Thread.Sleep(20); + continue; + } + } + //Thread.Sleep(100); + + } + + } + + _cam.SoftwareGrab(); + _cam.Stop(); + + while (testNum < acqNum) + { + Thread.Sleep(20); + } + FitCircle(); + + //////////三轴回零 + ////////if (_s7 != null) + ////////{ + //////// _s7.SetValue(arMode, (ushort)4); + //////// _s7.SetValue(arAction, true); + //////// Thread.Sleep(20); + //////// while (true) + //////// { + //////// bool value = false; + //////// if (_s7.GetValue(arOver, out value)) + //////// { + //////// if (value) + //////// { + //////// _s7.SetValue(arAction, false); + //////// break; + //////// } + //////// else + //////// { + //////// Thread.Sleep(20); + //////// continue; + //////// } + //////// } + //////// else + //////// { + //////// Thread.Sleep(20); + //////// continue; + //////// } + //////// } + //////// //MessageBox.Show("动作已完成!"); + ////////} + + ////////调整圆心到旋转中心 + + + //////if (_s7 != null) + //////{ + ////// double _angle = angle; + ////// //顺时针旋转 + ////// //if (_angle > 0) + ////// //{ + ////// // _angle = 360 - _angle; + ////// //} + ////// //else + ////// //{ + + ////// // _angle = -_angle; + ////// //} + ////// //逆时针旋转 + ////// if (_angle > 0) + ////// { + ////// _angle = _angle; + ////// } + ////// else + ////// { + + ////// _angle = 360 + _angle; + ////// } + + ////// _s7.SetValue(arMode, (ushort)0); + ////// _s7.SetValue(arSizeX, Convert.ToSingle((double)nud_SizeX.Value + deviationX)); + ////// _s7.SetValue(arSizeY, Convert.ToSingle((double)nud_SizeY.Value + deviationY)); + ////// _s7.SetValue(arSizeR, Convert.ToSingle(_angle)); + ////// _s7.SetValue(arAction, true); + ////// Thread.Sleep(20); + ////// while (true) + ////// { + ////// bool value = false; + ////// if (_s7.GetValue(arOver, out value)) + ////// { + ////// if (value) + ////// { + ////// _s7.SetValue(arAction, false); + ////// break; + ////// } + ////// else + ////// { + ////// Thread.Sleep(20); + ////// continue; + ////// } + ////// } + ////// else + ////// { + ////// Thread.Sleep(20); + ////// continue; + ////// } + ////// } + ////// //MessageBox.Show("动作已完成!"); + + //////} + Task.Run(() => { Save(); }); + } + if (OKorNG) + { + return "OK_RUN"; + + } + else + { + return "NG_RUN"; + } + } + + //所有点 + // 调整vpp中CogCaliperTool工具数据需要同时调整Y值与 for (double i = Y; i < 12; i = i + 0.5)中12的值 + private void MonitorSpot(CogImage8Grey outputImg) + { + sw_1 = new Stopwatch();//检测时间 + sw_1.Start(); + //double Y = -17; + //double X = 0; + double X = -15; + double Y = 0; + CogImage8Grey inputImg = new CogImage8Grey(); + CogGraphicCollection graphics = new CogGraphicCollection(); + CogImage8Grey _OutputImg = new CogImage8Grey(); + + inputImg = outputImg; + mTB_1 = mTB.Tools["CogToolBlock1"] as CogToolBlock; + mTB_2 = mTB.Tools["CogToolBlock2"] as CogToolBlock; + mTB_1.Inputs["InputImage"].Value = inputImg; + mTB_1.Run(); + _OutputImg = mTB_1.Outputs["OutputImage"].Value as CogImage8Grey; + + CogCaliperTool mCT = mTB_1.Tools["CogCaliperTool1"] as CogCaliperTool; + + + + //x′= cx + (x−cx)⋅cos(r)−(y−cy)⋅sin(r) + //y′= cy + (x−cx)⋅sin(r) + (y−cy)⋅cos(r)​ + + int _count = 0; + + for (double i = X; i < 14; i = i + 0.5) + { + mCT.InputImage = _OutputImg; + mCT.Region.CenterX = i; + mCT.Run(); + _count = mCT.Results.Count; + + if (_count != 0) + { + Y = mCT.Results[0].Edge0.PositionY; + //旋转角度 + double r = lstNasR[testNum] / 180 * Math.PI; + //旋转移动到实际位置 + lstNasX.Add(i * Math.Cos(r) - Y * Math.Sin(r) + circleCenterX * (1 - Math.Cos(r)) + circleCenterY * Math.Sin(r)); + lstNasY.Add(i * Math.Sin(r) + Y * Math.Cos(r) - circleCenterX * Math.Sin(r) + circleCenterY * (1 - Math.Cos(r))); + + CogPointMarker marker_1 = new CogPointMarker();//圆 + + marker_1.X = i; + marker_1.Y = Y; + marker_1.Color = CogColorConstants.Blue; + marker_1.Interactive = false; + graphics.Add(marker_1); + } + else + { + OKorNG = false; + testNum++; + return; + } + if (i == X) + { + double r = lstNasR[testNum] / 180 * Math.PI; + lstX.Add(i * Math.Cos(r) - Y * Math.Sin(r) + circleCenterX * (1 - Math.Cos(r)) + circleCenterY * Math.Sin(r)); + lstY.Add(i * Math.Sin(r) + Y * Math.Cos(r) - circleCenterX * Math.Sin(r) + circleCenterY * (1 - Math.Cos(r))); + } + + } + sw_1.Stop(); + TimeSpan ts = sw_1.Elapsed; + ImageDisplay(_OutputImg, graphics); + DataDisplay(lstNasR[testNum], lstNasX[0], lstNasY[0], ts.TotalMilliseconds); + testNum++; + times += ts.TotalMilliseconds; + OKorNG = true; + } + + //比较半径和点间距,拟合圆 + private void FitCircle() + { + if (OKorNG) + { + sw_2 = new Stopwatch();//检测时间 + sw_2.Start(); + int Image_i = -1; + // 调整vpp中CogCaliperTool工具数据需要同时调整step为x点数*2 + int step = 58; + CogPMAlignTool mPM = mTB_2.Tools["CogPMAlignTool2"] as CogPMAlignTool; + + + + CogImage8Grey outputImg = mTB_1.Outputs["OutputImage"].Value as CogImage8Grey; + //添加找圆工具的 忽略点数 和 RMS偏差量 + CogFitCircleTool fitCircle_1 = new CogFitCircleTool(); + CogFitCircleTool fitCircle_2 = new CogFitCircleTool(); + + + CogGraphicCollection graphics = new CogGraphicCollection(); + + fitCircle_1.InputImage = outputImg; + for (int i = 0; i < lstX.Count; i++) + { + fitCircle_1.RunParams.AddPoint(lstX[i], lstY[i]); + + //CogPointMarker marker_1 = new CogPointMarker();//圆 + + //marker_1.X = lstNasX[i]; + //marker_1.Y = lstNasY[i]; + //marker_1.Color = CogColorConstants.White; + //marker_1.Interactive = false; + //graphics.Add(marker_1); + + } + + //fitCircle_1.RunParams.NumToIgnore = 0; + fitCircle_1.Run(); + if (fitCircle_1.Result != null) + { + double _RMS = fitCircle_1.Result.RMSError; + CogCircle circle_1 = new CogCircle(fitCircle_1.Result.GetCircle()); + circle_1.Color = CogColorConstants.Cyan; + circle_1.Interactive = false; + + CogFitLineTool fitLine = new CogFitLineTool(); + + //晶圆圆心位置 + double _centerX = circle_1.CenterX; + double _centerY = circle_1.CenterY; + double _radius = circle_1.Radius; + + + fitCircle_2.InputImage = outputImg; + + CogDistancePointPointTool pTp = new CogDistancePointPointTool(); + pTp.InputImage = outputImg; + pTp.StartX = _centerX; + pTp.StartY = _centerY; + //double[] _DistanceMin = new double[lstNasX.Count]; + //int _distanceMin_i = 0; + for (int i = 0; i < lstNasX.Count; i += step) + { + + for (int j = i; j < i + step && j < lstNasX.Count; j++) + { + if (j < (i + step - 15))//忽略重合数据的末尾的15个点 + { + pTp.EndX = lstNasX[j]; + pTp.EndY = lstNasY[j]; + pTp.Run(); + double Distance = pTp.Distance; + if (Distance - _radius < 0.1 && Distance - _radius > -0.1) + { + fitCircle_2.RunParams.AddPoint(lstNasX[j], lstNasY[j]); + CogPointMarker marker_1 = new CogPointMarker();//圆 + + marker_1.X = lstNasX[j]; + marker_1.Y = lstNasY[j]; + marker_1.Color = CogColorConstants.Green; + marker_1.Interactive = false; + graphics.Add(marker_1); + } + else//忽略的点数 + { + if (!(Distance - _radius < 1 && Distance - _radius > -1)) + { + if (Image_i == -1) + { + Image_i = (int)(j / step); + } + } + + + CogPointMarker marker_1 = new CogPointMarker();//圆 + + marker_1.X = lstNasX[j]; + marker_1.Y = lstNasY[j]; + marker_1.Color = CogColorConstants.Yellow; + marker_1.Interactive = false; + graphics.Add(marker_1); + } + //_DistanceMin[i] = Distance; + } + else + { + CogPointMarker marker_1 = new CogPointMarker();//圆 + + marker_1.X = lstNasX[j]; + marker_1.Y = lstNasY[j]; + marker_1.Color = CogColorConstants.Red; + marker_1.Interactive = false; + //graphics.Add(marker_1); + } + } + + } + //忽略的拟合点数 + fitCircle_2.RunParams.NumToIgnore = 0; + fitCircle_2.Run(); + + double RMS = fitCircle_2.Result.RMSError; + CogCircle circle_2 = new CogCircle(fitCircle_2.Result.GetCircle()); + circle_2.Color = CogColorConstants.Cyan; + circle_2.Interactive = false; + //晶圆圆心位置 + double centerX = circle_2.CenterX; + double centerY = circle_2.CenterY; + double radius = circle_2.Radius; + + + double PM_X = 0; + double PM_Y = 0; + int _count = 0; + if (Image_i != -1) + { + mTB_2.Inputs["InputImage"].Value = Images[Image_i]; + mTB_2.Run(); + _count = mPM.Results.Count; + + if (_count != 0) + { + + double r = lstNasR[Image_i] / 180 * Math.PI; + PM_X = mPM.Results[0].GetPose().TranslationX * Math.Cos(r) - mPM.Results[0].GetPose().TranslationY * Math.Sin(r) + circleCenterX * (1 - Math.Cos(r)) + circleCenterY * Math.Sin(r); + PM_Y = mPM.Results[0].GetPose().TranslationX * Math.Sin(r) + mPM.Results[0].GetPose().TranslationY * Math.Cos(r) - circleCenterX * Math.Sin(r) + circleCenterY * (1 - Math.Cos(r)); + + } + } + //_distanceMin_i = DistanceMin(_DistanceMin); + + ////纳什口 + //CogLine line_ = new CogLine(); + //line_.SetFromStartXYEndXY(centerX, centerY, lstNasX[_distanceMin_i], lstNasY[_distanceMin_i]); + //line_.Color = CogColorConstants.Green; + //line_.Interactive = false; + //graphics.Add(line_); + //纳什口 + CogLine line_ = new CogLine(); + line_.SetFromStartXYEndXY(centerX, centerY, PM_X, PM_Y); + line_.Color = CogColorConstants.Green; + line_.Interactive = false; + graphics.Add(line_); + //角度值为0 + CogLine line_0 = new CogLine(); + line_0.SetXYRotation(centerX, centerY, 0); + line_0.Color = CogColorConstants.Blue; + line_0.Interactive = false; + graphics.Add(line_0); + CogAngleLineLineTool llTool = new CogAngleLineLineTool(); + llTool.InputImage = outputImg; + llTool.LineA = line_0; + llTool.LineB = line_; + llTool.Run(); + angle = CogMisc.RadToDeg(llTool.Angle); + + CogPointMarker marker_2 = new CogPointMarker();//圆心 + + marker_2.X = centerX; + marker_2.Y = centerY; + marker_2.Color = CogColorConstants.Green; + marker_2.Interactive = false; + graphics.Add(marker_2); + + CogPointMarker marker_3 = new CogPointMarker();//旋转圆心 + + marker_3.X = circleCenterX; + marker_3.Y = circleCenterY; + marker_3.Color = CogColorConstants.Orange; + marker_3.Interactive = false; + graphics.Add(marker_3); + graphics.Add(circle_2); + + + deviationX = centerX - circleCenterX; + deviationY = centerY - circleCenterY; + + sw_2.Stop(); + TimeSpan ts = sw_2.Elapsed; + + times += ts.TotalMilliseconds; + + + ImageDisplay(outputImg, graphics); + TCP_time = ts.TotalMilliseconds.ToString(); + TCP_X = centerX.ToString("F4"); + TCP_Y = centerY.ToString("F4"); + TCP_RMS = RMS.ToString("F4"); + TCP_R = angle.ToString("F4"); + ResultDisplay(times, ts.TotalMilliseconds, centerX, centerY, radius, RMS, deviationX, deviationY, angle); + + OKorNG = true; + } + else + { + //MessageBox.Show("检测结果为空。"); + OKorNG = false; + } + } + + + + } + //private int DistanceMin(double[] numbers) + //{ + // double number = numbers[0]; + // int num1 = 0; + // double num2 = ((IEnumerable)numbers).Sum() / (double)((IEnumerable)numbers).Count(); + // for (int index = 1; index < numbers.Length; ++index) + // { + // if (numbers[index] < number) + // { + // number = numbers[index]; + // num1 = index; + // } + // } + // //return Math.Abs(number - num2) > 0.0 ? num1 : -1; + // return num1; + //} + + + private void ResultDisplay(double Times,double Time, double X, double Y, double R, double RMS, double dX, double dY, double dR) + { + if (this.InvokeRequired) + { + this.BeginInvoke(new Action(() => ResultDisplay(Times,Time,X, Y, R, RMS, dX, dY, dR))); + return; + } + txt_Times.Text = Times.ToString(); + txt_Time.Text = Time.ToString(); + txt_RX.Text = X.ToString(); + txt_RY.Text = Y.ToString(); + txt_RR.Text = R.ToString(); + txt_RMS.Text = RMS.ToString(); + txt_DX.Text = dX.ToString(); + txt_DY.Text = dY.ToString(); + txt_DR.Text = dR.ToString(); + + } + private void ClearDisplay() + { + if (this.InvokeRequired) + { + this.BeginInvoke(new Action(() => ClearDisplay())); + return; + } + this.cogRecordDisplay1.InteractiveGraphics.Clear(); + this.cogRecordDisplay1.StaticGraphics.Clear(); + this.cogRecordDisplay1.Image = null; + } + + private void ImageDisplay(CogImage8Grey img, CogGraphicCollection graphics) + { + if (this.InvokeRequired) + { + this.BeginInvoke(new Action(() => ImageDisplay(img, graphics))); + return; + } + this.cogRecordDisplay1.Image = img; + this.cogRecordDisplay1.StaticGraphics.AddList(graphics, ""); + this.cogRecordDisplay1.Fit(true); + } + private void ImageDisplay(CogGraphicCollection graphics) + { + if (this.InvokeRequired) + { + this.BeginInvoke(new Action(() => ImageDisplay(graphics))); + return; + } + this.cogRecordDisplay1.StaticGraphics.AddList(graphics, ""); + this.cogRecordDisplay1.Fit(true); + } + private void ImageDisplay(CogImage8Grey img) + { + if (this.InvokeRequired) + { + this.BeginInvoke(new Action(() => ImageDisplay(img))); + return; + } + this.cogRecordDisplay1.Image = img; + this.cogRecordDisplay1.Fit(true); + } + + private void DataDisplay(double Rotation, double X, double Y, double Radius) + { + if (this.InvokeRequired) + { + this.BeginInvoke(new Action(() => DataDisplay(Rotation, X, Y, Radius))); + return; + } + int rowIndex = dataGridView1.Rows.Add(); + dataGridView1.Rows[rowIndex].Cells["Column1"].Value = Rotation; + dataGridView1.Rows[rowIndex].Cells["Column2"].Value = X; + dataGridView1.Rows[rowIndex].Cells["Column3"].Value = Y; + dataGridView1.Rows[rowIndex].Cells["Column4"].Value = Radius; + + } + string SavePath; + private void SaveImage(ICogImage img) + { + if (!Directory.Exists(SavePath)) + { + Directory.CreateDirectory(SavePath); + } + using (CogImageFile imgFile = new CogImageFile()) + { + imgFile.Open(Path.Combine(SavePath, DateTime.Now.ToString("yyyyMMdd_HHmmss_fff") + ".bmp"), CogImageFileModeConstants.Write); + imgFile.Append(img); + } + } + private void Save() + { + if (!Directory.Exists(SavePath)) + { + Directory.CreateDirectory(SavePath); + } + foreach (var item in Images) + { + using (CogImageFile imgFile = new CogImageFile()) + { + imgFile.Open(Path.Combine(SavePath, DateTime.Now.ToString("yyyyMMdd_HHmmss_fff") + ".bmp"), CogImageFileModeConstants.Write); + imgFile.Append(item); + } + } + } + } +} diff --git a/WaferAlignment/Form1.resx b/WaferAlignment/Form1.resx new file mode 100644 index 0000000..b3e563c --- /dev/null +++ b/WaferAlignment/Form1.resx @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACFTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5BeEhvc3QrU3RhdGUBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAtwAAAAIB + AAAAAQAAAAAAAAAAAAAAAKIAAAAAAQAAeFsAAKw5AAATAAoKZAALAAAACwAAAAsA//8DAAAAAAADAAEA + AAAFAAAAAAAAAAAABQAAAAAAAAAAAAUAAAAAAAAA8D8TAAAAwAALAP//CwD//xMAAIAAAAMAAwAAAAsA + //8LAAAAAAAAAAAA4D8AAAAAAADgPwAAAAAAAOA/AAAAAAAA4D8BAAAAAQAAAAsA//8LAAAACwAAAAsA + //8L + + + + True + + + True + + + True + + + True + + \ No newline at end of file diff --git a/WaferAlignment/HslCommunication.dll b/WaferAlignment/HslCommunication.dll new file mode 100644 index 0000000..f473c2b Binary files /dev/null and b/WaferAlignment/HslCommunication.dll differ diff --git a/WaferAlignment/Program.cs b/WaferAlignment/Program.cs new file mode 100644 index 0000000..3f5b84e --- /dev/null +++ b/WaferAlignment/Program.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace WaferAlignment +{ + static class Program + { + /// + /// 应用程序的主入口点。 + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new Form1()); + } + } +} diff --git a/WaferAlignment/Properties/AssemblyInfo.cs b/WaferAlignment/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..b4bb526 --- /dev/null +++ b/WaferAlignment/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的常规信息通过以下 +// 特性集控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("WaferAlignment")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("HP Inc.")] +[assembly: AssemblyProduct("WaferAlignment")] +[assembly: AssemblyCopyright("Copyright © HP Inc. 2024")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 使此程序集中的类型 +// 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, +// 则将该类型上的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("1e41d94a-8082-46d2-83cd-92d60d48d97a")] + +// 程序集的版本信息由下面四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, +// 方法是按如下所示使用“*”: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/WaferAlignment/Properties/Resources.Designer.cs b/WaferAlignment/Properties/Resources.Designer.cs new file mode 100644 index 0000000..038055c --- /dev/null +++ b/WaferAlignment/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace WaferAlignment.Properties { + using System; + + + /// + /// 一个强类型的资源类,用于查找本地化的字符串等。 + /// + // 此类是由 StronglyTypedResourceBuilder + // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 + // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen + // (以 /str 作为命令选项),或重新生成 VS 项目。 + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// 返回此类使用的缓存的 ResourceManager 实例。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WaferAlignment.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 重写当前线程的 CurrentUICulture 属性,对 + /// 使用此强类型资源类的所有资源查找执行重写。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/WaferAlignment/Properties/Resources.resx b/WaferAlignment/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/WaferAlignment/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/WaferAlignment/Properties/Settings.Designer.cs b/WaferAlignment/Properties/Settings.Designer.cs new file mode 100644 index 0000000..f8cb7c1 --- /dev/null +++ b/WaferAlignment/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace WaferAlignment.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.14.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/WaferAlignment/Properties/Settings.settings b/WaferAlignment/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/WaferAlignment/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/WaferAlignment/TCP.cs b/WaferAlignment/TCP.cs new file mode 100644 index 0000000..e7b0135 --- /dev/null +++ b/WaferAlignment/TCP.cs @@ -0,0 +1,290 @@ +using FlyTcpFramework; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; + +namespace WaferAlignment +{ + class TCP + { + // 用于通讯的本地连接的IP地址 + private string ipServer = "192.168.2.200"; + + // 定义IP服务器 + private TcpSvr m_Svc; + + // 允许连接的客户端IP地址列表 + private List allowedClientIps = new List { "192.168.2.100" }; + + // 接收数据事件的委托 + public event EventHandler DataReceived; + + // 用于存储客户端的字典 + private Dictionary clientDictionary = new Dictionary(); + + // 启动服务器 + public void StartServer() + { + try + { + ushort _port = 3000; + m_Svc = new TcpSvr(IPAddress.Parse(ipServer), _port, 10, new Coder(Coder.EncodingMothord.Default), AppDomain.CurrentDomain.BaseDirectory); + + // 订阅事件 + m_Svc.RecvData += new NetEvent(RecvData); + m_Svc.ClientConn += new NetEvent(ClientConnect); + m_Svc.ClientClose += new NetEvent(ClientClosed); + + // 启动服务器 + m_Svc.Start(); + + if (m_Svc.IsRun) + { + Console.WriteLine("Server已上线"); + } + else + { + Console.WriteLine("Server未能上线"); + } + } + catch (Exception ex) + { + throw new Exception("启动服务器失败!" + ex); + } + } + + // 停止服务器 + public void StopServer() + { + try + { + if (m_Svc != null) + { + // 取消订阅事件 + m_Svc.RecvData -= RecvData; + m_Svc.ClientConn -= ClientConnect; + m_Svc.ClientClose -= ClientClosed; + + // 停止服务器 + m_Svc.Stop(); + m_Svc = null; + + Console.WriteLine("Server已下线"); + } + } + catch (Exception ex) + { + throw new Exception("停止服务器失败!" + ex); + } + } + + // 服务器接收数据TCPIP + private void RecvData(object sender, NetEventArgs e) + { + try + { + //string info = Encoding.ASCII.GetString(e.Client.Datagram); // 解码为 ASCII 字符串 + string info = e.Client.Datagram; // 收到的数据 + string ip = ((IPEndPoint)e.Client.ClientSocket.RemoteEndPoint).Address.ToString(); + // 触发处理收到的数据 + OnDataReceived(new DataReceivedEventArgs(ip, info)); + } + catch (Exception ex) + { + throw new Exception("接收数据失败!" + ex.Message); + } + } + // 触发数据接收事件 + protected virtual void OnDataReceived(DataReceivedEventArgs e) + { + // 将空条件运算符改为传统的 null 检查 + EventHandler handler = DataReceived; + if (handler != null) + { + handler(this, e); + } + } + // 发送数据到指定客户端 + public void SendData(string clientIp, string data) + { + TcpClientState clientState; + if (clientDictionary.TryGetValue(clientIp, out clientState)) + { + byte[] dataBytes = Encoding.Default.GetBytes(data); + clientState.ClientSocket.Send(dataBytes); + Console.WriteLine("向客户端 {0} 发送数据: {1}", clientIp, data); + } + else + { + throw new Exception("客户端未连接"); + } + } + //// 触发数据接收事件 + //protected virtual void OnDataReceived(DataReceivedEventArgs e) + //{ + // DataReceived?.Invoke(this, e); + //} + + //// 发送数据到指定客户端 + //public void SendData(string clientIp, string data) + //{ + // if (clientDictionary.TryGetValue(clientIp, out TcpClientState clientState)) + // { + // byte[] dataBytes = Encoding.Default.GetBytes(data); + // clientState.ClientSocket.Send(dataBytes); + // Console.WriteLine($"向客户端 {clientIp} 发送数据: {data}"); + // } + // else + // { + // throw new Exception("客户端未连接"); + // } + //} + + // 客户端是否链接判断 + private void ClientConnect(object sender, NetEventArgs e) + { + try + { + string ip = ((IPEndPoint)e.Client.ClientSocket.RemoteEndPoint).Address.ToString(); + + // 检查客户端IP是否在允许列表中 + if (allowedClientIps.Contains(ip)) + { + TcpClientState clientState = new TcpClientState(e.Client.ClientSocket, ip); + clientDictionary[ip] = clientState; + //Console.WriteLine($"客户端 {ip} 已连接"); + } + else + { + // 拒绝不在允许列表中的客户端连接 + //Console.WriteLine($"拒绝客户端 {ip} 的连接"); + e.Client.ClientSocket.Close(); + } + } + catch (Exception ex) + { + throw new Exception("TCP连接失败!" + ex); + } + } + + // 客户端链接断开判断 + private void ClientClosed(object sender, NetEventArgs e) + { + try + { + string ip = ((IPEndPoint)e.Client.ClientSocket.RemoteEndPoint).Address.ToString(); + if (clientDictionary.ContainsKey(ip)) + { + clientDictionary.Remove(ip); + //Console.WriteLine($"客户端 {ip} 已断开"); + } + } + catch (Exception ex) + { + throw new Exception("通信断开失败!" + ex); + } + } + + ///// + ///// 客户端是否链接判断 + ///// + ///// + ///// + //void ClientConnect(object sender, NetEventArgs e) + //{ + // try + // { + // ip = ((IPEndPoint)e.Client.ClientSocket.RemoteEndPoint).Address.ToString(); + // if (ip == ip1) + // { + // //lb_ClientOnlineStatus.Text = "客户端已连接"; + // //lb_ClientOnlineStatus.BackColor = Color.GreenYellow; + // } + // } + // catch (Exception ex) + // { + // throw new Exception("TCP连接失败!"+ ex.Message); + + // } + + //} + + ///// + ///// 客户端链接断开判断 + ///// + ///// + ///// + //void ClientClosed(object sender, NetEventArgs e) + //{ + // try + // { + // ip = ((IPEndPoint)e.Client.ClientSocket.RemoteEndPoint).Address.ToString(); + // if (ip == ip1) + // { + // //lb_ClientOnlineStatus.Text = "客户端已断开"; + // //lb_ClientOnlineStatus.BackColor = Color.Yellow; + // } + // } + // catch (Exception ex) + // { + // throw new Exception("通信断开失败!"+ ex.Message); + + // } + + //} + + } + + public class DataReceivedEventArgs : EventArgs + { + public string ClientIp { get; private set;} + public string Data { get; private set; } + + public DataReceivedEventArgs(string clientIp, string data) + { + ClientIp = clientIp; + Data = data; + } + } + + public class TcpClientState + { + /// + /// 客户端的套接字 + /// + public Socket ClientSocket { get; private set; } + + /// + /// 客户端的IP地址 + /// + public string ClientIp { get; private set; } + + /// + /// 客户端连接的时间 + /// + public DateTime ConnectionTime { get; private set; } + + /// + /// 客户端的唯一标识符 + /// + public string ClientId { get; private set; } + + /// + /// 构造函数 + /// + /// 客户端的套接字 + /// 客户端的IP地址 + public TcpClientState(Socket clientSocket, string clientIp) + { + ClientSocket = clientSocket; + ClientIp = clientIp; + ConnectionTime = DateTime.Now; + ClientId = Guid.NewGuid().ToString(); + } + } +} diff --git a/WaferAlignment/WaferAlignment.csproj b/WaferAlignment/WaferAlignment.csproj new file mode 100644 index 0000000..66e7eaf --- /dev/null +++ b/WaferAlignment/WaferAlignment.csproj @@ -0,0 +1,150 @@ + + + + + Debug + AnyCPU + {941B8ABC-436F-457D-95DA-A79E23C8CA5D} + WinExe + Properties + WaferAlignment + WaferAlignment + v4.8 + 512 + true + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + true + bin\x64\Debug\ + DEBUG;TRACE + full + x64 + 7.3 + prompt + true + + + bin\x64\Release\ + TRACE + true + pdbonly + x64 + 7.3 + prompt + true + + + + + + + + + + + + + + + + + + + + .\FlyTcpFramework.dll + + + .\HslCommunication.dll + + + ..\..\..\..\..\..\Program Files (x86)\MVS\Development\DotNet\win64\net40\MvCameraControl.Net.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + Form + + + Form1.cs + + + + + + Form1.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + \ No newline at end of file