using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Timers; using System.Web.UI.WebControls.WebParts; using ProductionControl.Utils; using static System.Windows.Forms.VisualStyles.VisualStyleElement.Rebar; namespace ProductionControl.Device { public class SmallAxisDev : IDisposable { #region 导入C函数 #if (!DEBUG) const string dllName = "PMSOpticalDll.dll"; #else const string dllName = "PMSOpticalDlld.dll"; #endif [DllImport(dllName, CharSet = CharSet.Ansi, EntryPoint = "PMSOptical_OpenSocket", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr PMSOptical_OpenSocket(string ip, int nPort); [DllImport(dllName, CharSet = CharSet.Ansi, EntryPoint = "PMSOptical_OpenComm", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr PMSOptical_OpenComm(string comname, int nBaud); [DllImport(dllName, CharSet = CharSet.Ansi, EntryPoint = "PMSOptical_IsOpened", CallingConvention = CallingConvention.Cdecl)] public static extern bool PMSOptical_IsOpened(IntPtr ptr, ref bool bIsOpened); [DllImport(dllName, CharSet = CharSet.Ansi, EntryPoint = "PMSOptical_Close", CallingConvention = CallingConvention.Cdecl)] public static extern bool PMSOptical_Close(ref IntPtr ptr); [DllImport(dllName, CharSet = CharSet.Ansi, EntryPoint = "PMSOptical_GoHome", CallingConvention = CallingConvention.Cdecl)] public static extern bool PMSOptical_GoHome(IntPtr ptr); [DllImport(dllName, CharSet = CharSet.Ansi, EntryPoint = "PMSOptical_IsHomed", CallingConvention = CallingConvention.Cdecl)] public static extern bool PMSOptical_IsHomed(IntPtr ptr, ref bool bIsHomed); [DllImport(dllName, CharSet = CharSet.Ansi, EntryPoint = "PMSOptical_MoveTo", CallingConvention = CallingConvention.Cdecl)] public static extern bool PMSOptical_MoveTo(IntPtr ptr, int nPulse); [DllImport(dllName, CharSet = CharSet.Ansi, EntryPoint = "PMSOptical_Stop", CallingConvention = CallingConvention.Cdecl)] public static extern bool PMSOptical_Stop(IntPtr ptr); [DllImport(dllName, CharSet = CharSet.Ansi, EntryPoint = "PMSOptical_JogStart", CallingConvention = CallingConvention.Cdecl)] public static extern bool PMSOptical_JogStart(IntPtr ptr, int nJogSpeed); [DllImport(dllName, CharSet = CharSet.Ansi, EntryPoint = "PMSOptical_JogStop", CallingConvention = CallingConvention.Cdecl)] public static extern bool PMSOptical_JogStop(IntPtr ptr); [DllImport(dllName, CharSet = CharSet.Ansi, EntryPoint = "PMSOptical_GetPos", CallingConvention = CallingConvention.Cdecl)] public static extern bool PMSOptical_GetPos(IntPtr ptr, ref int nCurPluse); [DllImport(dllName, CharSet = CharSet.Ansi, EntryPoint = "PMSOptical_GetMaxPos", CallingConvention = CallingConvention.Cdecl)] public static extern bool PMSOptical_GetMaxPos(IntPtr ptr, ref int nMaxPluse); [DllImport(dllName, CharSet = CharSet.Ansi, EntryPoint = "PMSOptical_GetStatus", CallingConvention = CallingConvention.Cdecl)] public static extern bool PMSOptical_GetStatus(IntPtr ptr, ref int nStatus); [DllImport(dllName, CharSet = CharSet.Ansi, EntryPoint = "PMSOptical_WaitForOpticalFinished", CallingConvention = CallingConvention.Cdecl)] public static extern void PMSOptical_WaitForOpticalFinished(IntPtr ptr, int nTimeOut); #endregion public Action WarningEvent; public Action PPUChangeEvent; public Action StateChangeEvent; /// /// 最大倍数总的脉冲数 /// public int MaxPPU { get; private set; } /// /// 是否打开设备成功 /// public bool IsInit { get { if (pHandle == IntPtr.Zero) return false; bool bIsOpened = false; PMSOptical_IsOpened(pHandle, ref bIsOpened); return bIsOpened; } } private System.Timers.Timer timer = new System.Timers.Timer(); private IntPtr pHandle; private int PrePPU; public bool PreRunState; private bool _isDebug = false; public SmallAxisDev(bool isDebug) { _isDebug = isDebug; } public SmallAxisDev() { } public bool start(string comName, int baud) { try { if(!IsInit) pHandle = PMSOptical_OpenComm(comName, baud); if (IsInit) { //获取回零状态并状态栏显示 bool bIsHomed = false; PMSOptical_IsHomed(pHandle, ref bIsHomed); if (!bIsHomed) { Thread.Sleep(100); PMSOptical_WaitForOpticalFinished(pHandle, 10000); PMSOptical_IsHomed(pHandle, ref bIsHomed); if (!bIsHomed) throw new Exception("镜头电机复位失败!"); } } PrePPU = 0; PreRunState = false; this.getMaxPPU(); this.getCurrPPU(); this.isMoving(); // if (_isDebug) { timer.Elapsed += Timer_Elapsed; timer.Interval = 1000; timer.Start(); } return true; } catch (Exception ex) { WarningEvent?.Invoke(WarningEnum.High, ex.Message); return false; } } public void stop() { try { if (_isDebug) { timer.Elapsed -= Timer_Elapsed; timer.Stop(); } Thread.Sleep(200); PMSOptical_Close(ref pHandle); } catch { } } private void Timer_Elapsed(object sender, ElapsedEventArgs e) { if (!IsInit) return; getCurrPPU(); isMoving(); } public bool home(bool await=false) { if (!IsInit) return false; PMSOptical_GoHome(pHandle); if (await) { PMSOptical_WaitForOpticalFinished(pHandle, 10000); //判断是否回零并设置按钮状态 bool bIsHomed = false; PMSOptical_IsHomed(pHandle, ref bIsHomed); if (!bIsHomed) return false; getCurrPPU(); } return true; } public void gotoPos(int ppu,bool await=true) { if (!IsInit) return; if (ppu < 0 || ppu > MaxPPU) return; PMSOptical_MoveTo(pHandle, ppu); if (await) { PMSOptical_WaitForOpticalFinished(pHandle, 10000); getCurrPPU(); } } public bool isMoving() { if (!IsInit) return false; int nStatus = 1; //注意,这里建议nStatus初始化为1 //返回0为运动状态,1为停止状态,2为初始化失败 Thread.Sleep(20); //获取状态并刷新界面 PMSOptical_GetStatus(pHandle, ref nStatus); bool state = 0 == nStatus; if (PreRunState != state) { StateChangeEvent?.Invoke(state); PreRunState = state; } return state; } //获取最大脉冲 public int getMaxPPU() { if (!IsInit) return -1; int nMaxPos = 0; PMSOptical_GetMaxPos(pHandle, ref nMaxPos); MaxPPU = nMaxPos; return nMaxPos; } //获取当前脉冲 public int getCurrPPU() { if (!IsInit) return -1; int nCurPos = 0; PMSOptical_GetPos(pHandle, ref nCurPos); if (PrePPU != nCurPos) { PPUChangeEvent?.Invoke(PrePPU, nCurPos); PrePPU = nCurPos; } return nCurPos; } private byte[] subBuff(byte[] buff, int start, int length) { byte[] res = new byte[length]; for (int i = start; i < buff.Length && i < start + length; i++) res[i - start] = buff[i]; return res; } public void Dispose() { stop(); } } }