using System; using System.Text; using System.Threading; using System.IO; using System.Runtime.InteropServices; using System.Collections.Generic; using System.Xml.Serialization; namespace SA_LTT.Module { public enum DTK_MODE_TYPE { DM_GPASCII = 0, DM_GETSENDS_0 = 1, DM_GETSENDS_1 = 2, DM_GETSENDS_2 = 3, DM_GETSENDS_3 = 4, DM_GETSENDS_4 = 5, DM_SECURE_SHELL = 10 }; public enum DTK_STATUS { DS_Ok = 0, DS_Exception = 1, DS_TimeOut = 2, DS_Connected = 3, DS_NotConnected = 4, DS_Failed = 5, DS_GetSendMode = 6, DS_InvalidDevice = 11, DS_InvalidCommand = 12, DS_InvalidResponse = 13, DS_DataRemains = 21, DS_CmdLengthExceeds = 23, DS_ResLengthExceeds = 24, DS_RunningDownload = 41, DS_RunningRead = 42, DS_DATimeOut = 102, DS_DANotConnected = 104, DS_DAFailed = 105, }; public enum DTK_RESET_TYPE { DR_Reset = 0, DR_FullReset = 1 }; public enum DTK_DOWNLOAD_TYPE { DT_Progress = 0, DT_StringA = 1, DT_StringW = 2 }; public enum DTK_DOWNLOAD_MODE { DM_File_Download = 0, DM_File_DownExec = 1, DM_File_DownExecDel = 2, DM_File_DirectBuffer = 6, DM_File_DownAuto = 11 }; public enum MotionDirection { Plus, Minus, Stop } public enum SimulCommand { //충돌방지 Alarm STOP, JOGP, JOGN, ABS, REL, enMax, } public enum AxisType { SERVO = 0, STEPPING, LINEAR, } public enum AxisStatus { TriggerMove, HomeInProgress, NLimit_HW, PLimit_HW, FeWarn, //Alarm FeFatal, //Alarm LimitStop, //Alarm AmpFault, NLimit_SW, PLimit_SW, I2TFault, //Alarm TriggerNotFound, AmpWarn, EncLoss, //Alarm Bit_14, Bit_15, HomeComplete, DesVelZero, ClosedRoop, InPos, ServoOn, Bit_21, BlockRequest, PhaseFound, TriggerSpeedSel, GantryHomed, SpindleMotor2, SpindleMotor1, Bit_28, Bit_29, Bit_30, Bit_31, enMax, } public enum PmacAxis { Y_Axis, X_Axis, T_Axis, enMax, } public enum EnTeachData { LoadPosX = 0, CenterPosX, BeamProfileX, PowerMeterX, AlignX, TestX, enMaxX, LoadPosY = 0, CenterPosY, BeamProfileY, PowerMeterY, AlignY, TestY, enMaxY, LoadPosT = 0, CenterPosT, BeamProfileT, PowerMeterT, AlignT, TestT, enMaxT, } public struct COPYDATASTRUCT { public IntPtr dwData; public UInt32 cbData; [MarshalAs(UnmanagedType.LPStr)] public string lpData; } public class PowerPmacCtrl { const string dllName = "PowerPmac32.dll"; // 32Bit 플랫폼일 때 활성화 //const string dllName = "PowerPmac64.dll"; // 64Bit 플랫폼일 때 활성화 public delegate void PDOWNLOAD_PROGRESS(Int32 nPercent); public delegate void PDOWNLOAD_MESSAGE_A(String lpMessage); public delegate void PRECEIVE_PROC_A(String lpReveive); public const UInt32 WM_MESSAGE_DOWNLOAD = 0x1216; public const UInt32 WM_MESSAGE_RECEIVE = 0x1217; private string _ip; private UInt32 _ipAddress; private uint _deviceID = 9999; private bool m_bConnected = false; private static object _objLock = new object(); Equipment _equipment; #region 오픈 라이브러리 // 인자를 NULL로 할 경우 DTKDeviceSelect 함수를 사용하여 장치를 연결해야 한다. [DllImport(dllName)] public static extern UInt32 DTKPowerPmacOpen(UInt32 dwIPAddress, UInt32 uMode); // 라이브리리 클로즈 [DllImport(dllName)] public static extern UInt32 DTKPowerPmacClose(UInt32 uDeviceID); // 등록된 디바이스 갯수 [DllImport(dllName)] public static extern UInt32 DTKGetDeviceCount(out Int32 pnDeviceCount); // IP Address 확인 [DllImport(dllName)] public static extern UInt32 DTKGetIPAddress(UInt32 uDeviceID, out UInt32 pdwIPAddress); // 장치를 연결 [DllImport(dllName)] public static extern UInt32 DTKConnect(UInt32 uDeviceID); // 장치를 해제 [DllImport(dllName)] public static extern UInt32 DTKDisconnect(UInt32 uDeviceID); // 장치가 연결되었는지 확인 [DllImport(dllName)] public static extern UInt32 DTKIsConnected(UInt32 uDeviceID, out Int32 pbConnected); // Echo Mode 설정 [DllImport(dllName)] public static extern UInt32 DTKSetEchoMode(UInt32 uDeviceID, UInt32 uEchoMode); // Echo Mode 확인 [DllImport(dllName)] public static extern UInt32 DTKGetEchoMode(UInt32 uDeviceID, out UInt32 puEchoMode); [DllImport(dllName)] public static extern UInt32 DTKGetResponseA(UInt32 uDeviceID, Byte[] lpCommand, Byte[] lpResponse, Int32 nLength); [DllImport(dllName)] public static extern UInt32 DTKSendCommandA(UInt32 uDeviceID, Byte[] lpCommand); [DllImport(dllName)] public static extern UInt32 DTKAbort(UInt32 uDeviceID); [DllImport(dllName)] public static extern UInt32 DTKDownloadA(UInt32 uDeviceID, Byte[] lpDownload, UInt32 uDowoload, IntPtr hDownloadWnd, PDOWNLOAD_PROGRESS lpDownloadProgress, PDOWNLOAD_MESSAGE_A lpDownloadMessage); [DllImport(dllName)] public static extern UInt32 DTKSetReceiveA(UInt32 uDeviceID, IntPtr hReceiveWnd, PRECEIVE_PROC_A lpReveiveProc); // 아래의 함수군은 CPU 통신셋업후 사용 가능 [DllImport(dllName)] public static extern UInt32 DTKGetUserMem(UInt32 uDeviceID, UInt32 uAddress, Int32 nSize, SByte[] pValue); [DllImport(dllName)] public static extern UInt32 DTKSetUserMem(UInt32 uDeviceID, UInt32 uAddress, Int32 nSize, SByte[] pValue); [DllImport(dllName)] public static extern UInt32 DTKGetUserMemChar(UInt32 uDeviceID, Int32 nIndex, out Byte pchValue); [DllImport(dllName)] public static extern UInt32 DTKSetUserMemChar(UInt32 uDeviceID, Int32 nIndex, Byte chValue); [DllImport(dllName)] public static extern UInt32 DTKGetUserMemShort(UInt32 uDeviceID, Int32 nIndex, out short pnValue); [DllImport(dllName)] public static extern UInt32 DTKSetUserMemShort(UInt32 uDeviceID, Int32 nIndex, short nValue); [DllImport(dllName)] public static extern UInt32 DTKGetUserMemInteger(UInt32 uDeviceID, Int32 nIndex, out Int32 pnValue); [DllImport(dllName)] public static extern UInt32 DTKSetUserMemInteger(UInt32 uDeviceID, Int32 nIndex, Int32 nValue); [DllImport(dllName)] public static extern UInt32 DTKGetUserMemUInteger(UInt32 uDeviceID, Int32 nIndex, out UInt32 puValue); [DllImport(dllName)] public static extern UInt32 DTKSetUserMemUInteger(UInt32 uDeviceID, Int32 nIndex, UInt32 uValue); [DllImport(dllName)] public static extern UInt32 DTKGetUserMemFloat(UInt32 uDeviceID, Int32 nIndex, out float pfVlaue); [DllImport(dllName)] public static extern UInt32 DTKSetUserMemFloat(UInt32 uDeviceID, Int32 nIndex, float fValue); [DllImport(dllName)] public static extern UInt32 DTKGetUserMemDouble(UInt32 uDeviceID, Int32 nIndex, out Double pdValue); [DllImport(dllName)] public static extern UInt32 DTKSetUserMemDouble(UInt32 uDeviceID, Int32 nIndex, Double dValue); #endregion public PowerPmacCtrl(Equipment equipment) { _equipment = equipment; //축정보 Load LoadMotorData(); ThreadInit(); ThreadStart(); } Thread PmacThread; Thread SimulationThread; private void ThreadInit() { PmacThread = new Thread(DataUpdate); //SimulationThread = new Thread(Simulation_Th); } private void ThreadStart() { //if (!_parentForm.m_bSimulationMode) PmacThread.Start(); //else // SimulationThread.Start(); } private int GetDeviceID(string ip, DTK_MODE_TYPE type) { try { _ip = ip; string[] strIP = _ip.Split('.'); _ipAddress = (Convert.ToUInt32(strIP[0]) << 24) | (Convert.ToUInt32(strIP[1]) << 16) | (Convert.ToUInt32(strIP[2]) << 8) | Convert.ToUInt32(strIP[3]); uint deviceID = DTKPowerPmacOpen(_ipAddress, (uint)type); return (int)deviceID; } catch(Exception e) { EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace); return -1; } } private bool Connect(string ip, DTK_MODE_TYPE type = DTK_MODE_TYPE.DM_GPASCII) { if (IsOpen()) return true; int deviceID = GetDeviceID(ip, type); if(deviceID == -1) { return false; } uint result = PowerPmacCtrl.DTKConnect((uint)deviceID); if((DTK_STATUS)result == DTK_STATUS.DS_Ok) { //성공 _deviceID = (uint)deviceID; m_bConnected = true; return true; } else { if((DTK_STATUS)result == DTK_STATUS.DS_Connected) { //이미 연결되어 있음 } else if ((DTK_STATUS)result == DTK_STATUS.DS_Failed) { //연결 실패 m_bConnected = false; } else if ((DTK_STATUS)result == DTK_STATUS.DS_InvalidDevice) { //유효하지 않은 장치 번호 m_bConnected = false; } PowerPmacCtrl.DTKPowerPmacClose((uint)deviceID); return false; } } public bool DisConnect() { if(_deviceID == 9999) { return false; } uint result = PowerPmacCtrl.DTKDisconnect(_deviceID); m_bConnected = false; if ((DTK_STATUS)result == DTK_STATUS.DS_Ok) { //성공 DTKPowerPmacClose(_deviceID); return true; } else { if ((DTK_STATUS)result == DTK_STATUS.DS_Failed) { //연결 종료 실패 } else if ((DTK_STATUS)result == DTK_STATUS.DS_InvalidDevice) { //유효하지 않은 장치 번호 } return false; } } public bool Open() { return Connect("192.168.0.200"); } public bool IsOpen() { return m_bConnected; } public bool PMACSendData(string Command, ref string sResponse) { bool bResult = false; try { Monitor.Enter(_objLock); if (IsOpen() == false) { return false; } byte[] commandBytes = Encoding.ASCII.GetBytes(Command); byte[] receivedBytes = new byte[1024]; uint result = PowerPmacCtrl.DTKGetResponseA(_deviceID, commandBytes, receivedBytes, receivedBytes.GetLength(0)); if ((DTK_STATUS)result == DTK_STATUS.DS_Ok) { sResponse = Encoding.Default.GetString(receivedBytes).TrimEnd('\0'); bResult = true; } else { if ((DTK_STATUS)result == DTK_STATUS.DS_NotConnected) { //통신모드가 GetSend 상태임 _equipment.alarmManager.Occur(AlarmCode.AL_0300_POWER_PMAC_NOT_CONNECTED); } else if ((DTK_STATUS)result == DTK_STATUS.DS_InvalidDevice) { //유효하지 않은 장치 번호 _equipment.alarmManager.Occur(AlarmCode.AL_0301_POWER_PMAC_INVALID_DEVICE); } else if ((DTK_STATUS)result == DTK_STATUS.DS_InvalidCommand) { //유효하지 않은 명령어 (NULL) _equipment.alarmManager.Occur(AlarmCode.AL_0302_POWER_PMAC_INVALID_COMMAND); } else if ((DTK_STATUS)result == DTK_STATUS.DS_InvalidResponse) { //유효하지 않은 응답 버퍼(NULL) _equipment.alarmManager.Occur(AlarmCode.AL_0303_POWER_PMAC_INVALID_RESPONSE); } else if ((DTK_STATUS)result == DTK_STATUS.DS_DataRemains) { //수신 버퍼에 데이터가 남아 있음 _equipment.alarmManager.Occur(AlarmCode.AL_0304_POWER_PMAC_DATA_REAMINS); } else if ((DTK_STATUS)result == DTK_STATUS.DS_CmdLengthExceeds) { //명령어 데이터 길이 초과 _equipment.alarmManager.Occur(AlarmCode.AL_0305_POWER_PMAC_CMD_LENGTH_EXCEEDS); } else if ((DTK_STATUS)result == DTK_STATUS.DS_ResLengthExceeds) { //응답 데이터 길이 초과 _equipment.alarmManager.Occur(AlarmCode.AL_0306_POWER_PMAC_RES_LENGTH_EXCEEDS); } else if ((DTK_STATUS)result == DTK_STATUS.DS_RunningDownload) { //다운로드 중 _equipment.alarmManager.Occur(AlarmCode.AL_0307_POWER_PMAC_RUNNING_DOWNLOAD); } else if (result >= 1000) { //통신 오류 (기술 지원 요청) _equipment.alarmManager.Occur(AlarmCode.AL_0308_POWER_PMAC_ERROR); } sResponse = string.Empty; bResult = false; } } catch (Exception ex) { EquipmentLogManager.Instance.WriteExceptionLog(ex.StackTrace + "\r\n" + ex.Message); } finally { Monitor.Exit(_objLock); } return bResult; } private double[] m_dAxisActualPos = new double[(int)PmacAxis.enMax]; private double[] m_dAxisHomePos = new double[(int)PmacAxis.enMax]; private double[] m_dAxisActualVel = new double[(int)PmacAxis.enMax]; private bool[,] m_bAxisStatus = new bool[(int)PmacAxis.enMax, (int)AxisStatus.enMax]; private int[] m_nUmacAddress = new int[(int)PmacAxis.enMax]; private int[] m_nAxisPMacNo = new int[(int)PmacAxis.enMax]; private int[] m_nAxisEnumNo = new int[(int)PmacAxis.enMax]; private int[] m_nIValueAxisNo = new int[(int)PmacAxis.enMax]; private double[] m_dScaleFactor = new double[(int)PmacAxis.enMax]; private int[] m_nAxisTimeOut = new int[(int)PmacAxis.enMax]; private int[] m_nAxisHommingTimeOut = new int[(int)PmacAxis.enMax]; private double[] m_dAxisHommingSpeed = new double[(int)PmacAxis.enMax]; private string[] m_strAxisName = new string[(int)PmacAxis.enMax]; private double[] m_dAxisSWPlusLimit = new double[(int)PmacAxis.enMax]; private double[] m_dAxisSWMinusLimit = new double[(int)PmacAxis.enMax]; private double[] m_dTargetPos = new double[(int)PmacAxis.enMax]; private double[] m_dTargetSpeed = new double[(int)PmacAxis.enMax]; private double[] m_dTeachPosX = new double[(int)EnTeachData.enMaxX]; private double[] m_dTeachPosY = new double[(int)EnTeachData.enMaxY]; private double[] m_dTeachPosT = new double[(int)EnTeachData.enMaxT]; private double[] m_dTeachVelX = new double[(int)EnTeachData.enMaxX]; private double[] m_dTeachVelY = new double[(int)EnTeachData.enMaxY]; private double[] m_dTeachVelT = new double[(int)EnTeachData.enMaxT]; private double[] m_dTeachAccX = new double[(int)EnTeachData.enMaxX]; private double[] m_dTeachAccY = new double[(int)EnTeachData.enMaxY]; private double[] m_dTeachAccT = new double[(int)EnTeachData.enMaxT]; public void SetAxisHomePos(PmacAxis axis, double dPos) { m_dAxisHomePos[(int)axis] = dPos; } public double GetAxisHomePos(PmacAxis axis) { return m_dAxisHomePos[(int)axis]; } public void SetAxisActualPos(PmacAxis axis, double dPos) { m_dAxisActualPos[(int)axis] = dPos; } public double GetAxisActualPos(PmacAxis axis) { return m_dAxisActualPos[(int)axis]; } public void SetAxisActualSpeed(PmacAxis axis, double dVel) { m_dAxisActualVel[(int)axis] = dVel; } public double GetAxisActualSpeed(PmacAxis axis) { return m_dAxisActualVel[(int)axis]; } public void SetAxisStatus(PmacAxis axis, AxisStatus statusName, bool bstatusValue) { m_bAxisStatus[(int)axis, (int)statusName] = bstatusValue; } public bool GetAxisStatus(PmacAxis axis, AxisStatus statusName) { return m_bAxisStatus[(int)axis, (int)statusName]; } public double GetAxisTargetPos(PmacAxis axis) { return m_dTargetPos[(int)axis]; } public double GetAxisTargetSpeed(PmacAxis axis) { return m_dTargetSpeed[(int)axis]; } public double GetMotorScaleFactor(PmacAxis axis) { return m_dScaleFactor[(int)axis]; } private void SetAxisName(PmacAxis axis, string strName) { m_strAxisName[(int)axis] = strName; } public string GetAxisName(PmacAxis axis) { return m_strAxisName[(int)axis]; } private void SetAxisPMacNum(PmacAxis axis, int axisNo) { m_nAxisPMacNo[(int)axis] = axisNo; } public int GetAxisPMacNum(PmacAxis axis) { return m_nAxisPMacNo[(int)axis]; } private void SetAxisEnumNum(PmacAxis axis, int axisNo) { m_nAxisEnumNo[(int)axis] = axisNo; } public int GetAxisEnumNum(PmacAxis axis) { return m_nAxisEnumNo[(int)axis]; } //private void SetIValueAxisNum(int axis, int axisNo) //{ // m_nIValueAxisNo[axis] = axisNo; //} //public int GetIValueAxisNum(UmacAxis axis) //{ // return m_nIValueAxisNo[(int)axis]; //} private void SetMotorScaleFactor(PmacAxis axis, double dValue) { m_dScaleFactor[(int)axis] = dValue; } public int GetAxisTimeOutSecond(PmacAxis axis) { return m_nAxisTimeOut[(int)axis]; } private void SetAxisTimeOutSecond(PmacAxis axis, int nMillisecond) { m_nAxisTimeOut[(int)axis] = nMillisecond; } public int GetAxisHommingTimeOutSecond(PmacAxis axis) { return m_nAxisHommingTimeOut[(int)axis]; } private void SetAxisHommingTimeOutSecond(PmacAxis axis, int nMillisecond) { m_nAxisHommingTimeOut[(int)axis] = nMillisecond; } public double GetAxisHommingSpeed(PmacAxis axis) { return m_dAxisHommingSpeed[(int)axis]; } private void SetAxisHommingSpeed(PmacAxis axis, double dSpeed) { m_dAxisHommingSpeed[(int)axis] = dSpeed; } public double GetAxisSWPlusLimit(PmacAxis axis) { return m_dAxisSWPlusLimit[(int)axis]; } private void SetAxisSWPlusLimit(PmacAxis axis, double dMaxPos) { m_dAxisSWPlusLimit[(int)axis] = dMaxPos; } public double GetAxisSWMinusLimit(PmacAxis axis) { return m_dAxisSWMinusLimit[(int)axis]; } private void SetAxisSWMinusLimit(PmacAxis axis, double dMinPos) { m_dAxisSWMinusLimit[(int)axis] = dMinPos; } public double[] GetAxisTeachData(PmacAxis axis, EnTeachData teach) { double[] dTeach = new double[3]; switch(axis) { case PmacAxis.X_Axis: dTeach[0] = m_dTeachPosX[(int)teach]; dTeach[1] = m_dTeachVelX[(int)teach]; dTeach[2] = m_dTeachAccX[(int)teach]; break; case PmacAxis.Y_Axis: dTeach[0] = m_dTeachPosY[(int)teach]; dTeach[1] = m_dTeachVelY[(int)teach]; dTeach[2] = m_dTeachAccY[(int)teach]; break; case PmacAxis.T_Axis: dTeach[0] = m_dTeachPosT[(int)teach]; dTeach[1] = m_dTeachVelT[(int)teach]; dTeach[2] = m_dTeachAccT[(int)teach]; break; default: break; } return dTeach; } private void SetAxisTeachData(PmacAxis axis, EnTeachData teach, double[] dData) { switch (axis) { case PmacAxis.X_Axis: m_dTeachPosX[(int)teach] = dData[0]; m_dTeachVelX[(int)teach] = dData[1]; m_dTeachAccX[(int)teach] = dData[2]; break; case PmacAxis.Y_Axis: m_dTeachPosY[(int)teach] = dData[0]; m_dTeachVelY[(int)teach] = dData[1]; m_dTeachAccY[(int)teach] = dData[2]; break; case PmacAxis.T_Axis: m_dTeachPosT[(int)teach] = dData[0]; m_dTeachVelT[(int)teach] = dData[1]; m_dTeachAccT[(int)teach] = dData[2]; break; default: break; } } public List m_AxisAllList = new List(); public string LoadMotorData() { string strRtn = ""; double[] dTemp = new double[3]; try { string sIO_path = Equipment.settingFilePath; string strDir = sIO_path + @"MotorData\"; if (!Directory.Exists(strDir) && strDir != string.Empty) { Directory.CreateDirectory(strDir); } string strFilePath = strDir + "MotorData" + ".xml"; using (FileStream fs = new FileStream(strFilePath, FileMode.Open)) { XmlSerializer xs = new XmlSerializer(typeof(List)); m_AxisAllList = xs.Deserialize(fs) as List; strRtn = "Servo Data Load Success! BoardNo:"; } for (int i = 0; i < (int)PmacAxis.enMax; i++) { SetAxisPMacNum((PmacAxis)i, m_AxisAllList[i].AxisNo); SetAxisEnumNum((PmacAxis)i, m_AxisAllList[i].EnumAxisNo); SetAxisName((PmacAxis)i, m_AxisAllList[i].Name); SetMotorScaleFactor((PmacAxis)i, m_AxisAllList[i].Scale); SetAxisTimeOutSecond((PmacAxis)i, m_AxisAllList[i].Timeout); SetAxisHommingTimeOutSecond((PmacAxis)i, m_AxisAllList[i].HommingTimeout); SetAxisHommingSpeed((PmacAxis)i, m_AxisAllList[i].HommingSpeed); SetAxisSWPlusLimit((PmacAxis)i, m_AxisAllList[i].SWPlusLimit); SetAxisSWMinusLimit((PmacAxis)i, m_AxisAllList[i].SWMinusLimit); for (int j = 0; j < m_AxisAllList[i].TeachList.Count; j++) { dTemp[0] = m_AxisAllList[i].TeachList[j].Position; dTemp[1] = m_AxisAllList[i].TeachList[j].Speed; dTemp[2] = m_AxisAllList[i].TeachList[j].Accel; SetAxisTeachData((PmacAxis)i, (EnTeachData)j, dTemp); } } } catch (System.Exception ex) { strRtn = "Servo Data Load Fail! BoardNo:" + " " + ex.Message; } return strRtn; } public bool SaveMotorData() { bool bRtn = false; string strRtn = ""; try { string sIO_path = Equipment.settingFilePath; string strDir = sIO_path + @"MotorData\"; if (!Directory.Exists(strDir) && strDir != string.Empty) { Directory.CreateDirectory(strDir); } string strFilePath = strDir + "MotorData" + ".xml"; using (FileStream fs = new FileStream(strFilePath, FileMode.Create)) { XmlSerializer xs = new XmlSerializer(typeof(List)); xs.Serialize(fs, m_AxisAllList); bRtn = true; strRtn = "Servo Data Save Success! "; } } catch (System.Exception ex) { strRtn = "Servo Data Save Fail! BoardNo:" + " " + ex.Message; bRtn = false; } return bRtn; } private void ParsingAxisData(PmacAxis axis, string strData) { string[] strParsingData; string[] strParsingData2; string strStatus; uint nStatus; uint nBit = 0x80000000; uint nBitResult = 0; int nCnt = 0; double dActPos, dHomePos; double dPos, dVel; bool bStatus = false; strParsingData = strData.Split('\n'); //Pos //ActPos strParsingData2 = strParsingData[nCnt].Split('='); dActPos = Convert.ToDouble(strParsingData2[1]); nCnt++; //HomePos strParsingData2 = strParsingData[nCnt].Split('='); dHomePos = Convert.ToDouble(strParsingData2[1]); SetAxisHomePos(axis, dHomePos); nCnt++; //CalculatedPos dPos = dActPos - dHomePos; dPos = dPos / GetMotorScaleFactor(axis); dPos = Math.Round(dPos, 4); SetAxisActualPos(axis, dPos); //Speed strParsingData2 = strParsingData[nCnt].Split('='); dVel = Convert.ToDouble(strParsingData2[1]); dVel = dVel * 5000.0 / GetMotorScaleFactor(axis); dVel = Math.Round(dVel, 4); SetAxisActualSpeed(axis, dVel); nCnt++; //Status strParsingData2 = strParsingData[nCnt].Split('='); strStatus = strParsingData2[1].Replace("$", ""); strStatus = strStatus.Replace("\r", ""); nStatus = Convert.ToUInt32(strStatus, 16); nCnt++; for (int i = 0; i < (int)AxisStatus.enMax; i++) { if (i == (int)AxisStatus.HomeComplete || i == (int)AxisStatus.HomeInProgress) continue; nBitResult = nStatus & nBit; bStatus = nBitResult == nBit ? true : false; SetAxisStatus(axis, (AxisStatus)i, bStatus); nBit = nBit / 2; } //Home Complete strParsingData2 = strParsingData[nCnt].Split('='); bStatus = Convert.ToInt32(strParsingData2[1]) == 1; SetAxisStatus(axis, AxisStatus.HomeComplete, bStatus); nCnt++; //Home Progress strParsingData2 = strParsingData[nCnt].Split('='); bStatus = Convert.ToInt32(strParsingData2[1]) == 1; SetAxisStatus(axis, AxisStatus.HomeInProgress, bStatus); nCnt++; } public void DataUpdate() { while (_equipment.IsDisposed == false) { try { bool dataCheck = true; if (/*!_parentForm.m_bSimulationMode && */IsOpen()) { for (int i = 0; i < (int)PmacAxis.enMax; i++) { dataCheck &= GetCtrlData(PmacAxis.Y_Axis + i); Thread.Sleep(10); } if (dataCheck == false) { DisConnect(); } else { AlarmCheck(); } continue; } else { m_bConnected = false; //if (!_parentForm.m_bSimulationMode) if(Open() == false) { _equipment.alarmManager.Occur(AlarmCode.AL_0060_POWER_PMAC_DISCONNECTED); } } } catch (Exception ex) { EquipmentLogManager.Instance.WriteExceptionLog(ex.StackTrace + "\r\n" + ex.Message); } } } private void AlarmCheck() { if (GetAxisStatus(PmacAxis.Y_Axis, AxisStatus.NLimit_HW)) { _equipment.alarmManager.Occur(AlarmCode.AL_0320_MOTOR_Y_NEGATIVE_LIMIT); } if (GetAxisStatus(PmacAxis.Y_Axis, AxisStatus.PLimit_HW)) { _equipment.alarmManager.Occur(AlarmCode.AL_0321_MOTOR_Y_POSITIVE_LIMIT); } if (GetAxisStatus(PmacAxis.X_Axis, AxisStatus.NLimit_HW)) { _equipment.alarmManager.Occur(AlarmCode.AL_0340_MOTOR_X_NEGATIVE_LIMIT); } if (GetAxisStatus(PmacAxis.X_Axis, AxisStatus.PLimit_HW)) { _equipment.alarmManager.Occur(AlarmCode.AL_0341_MOTOR_X_POSITIVE_LIMIT); } if (GetAxisStatus(PmacAxis.X_Axis, AxisStatus.NLimit_HW)) { _equipment.alarmManager.Occur(AlarmCode.AL_0360_MOTOR_T_NEGATIVE_LIMIT); } if (GetAxisStatus(PmacAxis.X_Axis, AxisStatus.PLimit_HW)) { _equipment.alarmManager.Occur(AlarmCode.AL_0361_MOTOR_T_POSITIVE_LIMIT); } } private bool GetCtrlData(PmacAxis axis) { try { bool bResult = false; //ActPos, HomePos, ActVel, Status string strMsg = string.Format($"Motor[{(GetAxisPMacNum(axis))}].ActPos Motor[{(GetAxisPMacNum(axis))}].HomePos Motor[{(GetAxisPMacNum(axis))}].ActVel Motor[{(GetAxisPMacNum(axis))}].Status[0] Mtr_StCompHome({(GetAxisPMacNum(axis))}) Mtr_StIngHome({(GetAxisPMacNum(axis))})"); string strReturnMsg = ""; bResult = PMACSendData(strMsg, ref strReturnMsg); ParsingAxisData(axis, strReturnMsg); return true; } catch (Exception ex) { EquipmentLogManager.Instance.WriteExceptionLog(ex.StackTrace + "\r\n" + ex.Message); return false; } } public bool ServoOnOff(PmacAxis axis, bool bOn) { string strCmd = ""; if (bOn) strCmd = string.Format($"Mtr_Cmd({ GetAxisPMacNum(axis)})=Mtr_010_ExeServoOn"); else strCmd = string.Format($"Mtr_Cmd({ GetAxisPMacNum(axis)})=Mtr_020_ExeServoOff"); string sReceive = null; //if (!MotionInterlockCheck(AxisID, Pos)) // return false; try { PMACSendData(strCmd, ref sReceive); } catch (Exception ex) { EquipmentLogManager.Instance.WriteExceptionLog(ex.StackTrace + "\r\n" + ex.Message); } return true; } //public AlarmCode SetHommingSpeed_Limit(PmacAxis axis) //{ // AlarmCode eResult = AlarmCode.AL_0000_OK; // string strCmd = string.Format($"Mtr_SetHomeJVel({GetAxisNum(axis)})"); // string sReceive = null; // //if (!MotionInterlockCheck(AxisID, Pos)) // // return false; // try // { // PMACSendData(strCmd, ref sReceive); // } // catch (Exception ee) // { // //_parentForm.WriteToDebugLog(string.Format("UMacCtrl: MoveAbs_AxisNum{0}", axis) + ee.ToString()); // } // return eResult; //} public bool StartHomming(PmacAxis axis) { string strCmd = string.Format($"Mtr_Cmd({ GetAxisPMacNum(axis)})=Mtr_030_ExeHome"); string sReceive = null; //if (!MotionInterlockCheck(AxisID, Pos)) // return false; try { PMACSendData(strCmd, ref sReceive); } catch (Exception ex) { EquipmentLogManager.Instance.WriteExceptionLog(ex.StackTrace + "\r\n" + ex.Message); } return true; } public bool ClearError(PmacAxis axis) { string strCmd = string.Format($"Mtr_Cmd({ GetAxisPMacNum(axis)})=Mtr_090_ExeErrClear"); string sReceive = null; //if (!MotionInterlockCheck(AxisID, Pos)) // return false; try { PMACSendData(strCmd, ref sReceive); } catch (Exception ex) { EquipmentLogManager.Instance.WriteExceptionLog(ex.StackTrace + "\r\n" + ex.Message); } return true; } public void ClearErrorAll() { ClearError(PmacAxis.X_Axis); ClearError(PmacAxis.Y_Axis); ClearError(PmacAxis.T_Axis); } public bool MoveAbs(PmacAxis AxisID, double dPos, double dVel, double dAcc/* = 300*/) { // Position, Speed에 대한 Convert값을 계산해서 보내야 한다. double dPosToCnt = dPos * GetMotorScaleFactor(AxisID) /*+ GetAxisHomePos(AxisID)*/; double dSpeedToCnt = dVel * GetMotorScaleFactor(AxisID) / 1000.0; m_dTargetPos[(int)AxisID] = dPos; m_dTargetSpeed[(int)AxisID] = dVel; ////SimulationMode //if (_parentForm.m_bSimulationMode) //{ // m_SimulCommand[(int)AxisID] = SimulCommand.ABS; // return eResult; //} //eResult = MotionInterlockCheck(AxisID, dPos); //if (eResult != Alarm_List.AL_OK) // return eResult; string strCmd = string.Format("Motor[{0}].JogTa={1} Motor[{0}].JogSpeed={2} #{0}J={3}", GetAxisPMacNum(AxisID), dAcc, dSpeedToCnt, dPosToCnt); string sReceive = null; //if (!MotionInterlockCheck(AxisID, Pos)) // return false; try { PMACSendData(strCmd, ref sReceive); } catch (Exception ex) { EquipmentLogManager.Instance.WriteExceptionLog(ex.StackTrace + "\r\n" + ex.Message); } //return true; //if (GetAxisStatus(AxisID, AxisStatus.Error)) // eResult = Alarm_List.AL_STAGE_Y_AXIS_ALARM + axis; return true; } public bool MoveRel(PmacAxis AxisID, double Pos, double Vel, double Acc/* = 300*/) { // Position, Speed에 대한 Convert값을 계산해서 보내야 한다. double dAddPos = Pos + GetAxisActualPos(AxisID); double dPosToCnt = dAddPos * GetMotorScaleFactor(AxisID); double dSpeedToCnt = Vel * GetMotorScaleFactor(AxisID) / 1000.0; m_dTargetPos[(int)AxisID] = dAddPos; m_dTargetSpeed[(int)AxisID] = Vel; //SimulationMode - 쓰려면 살려두고! //if (_parentForm.m_bSimulationMode) //{ // m_SimulCommand[(int)AxisID] = SimulCommand.REL; // return eResult; //} string strCmd = string.Format("Motor[{0}].JogTa={1} Motor[{0}].JogSpeed={2} #{0}J={3}", GetAxisPMacNum(AxisID), Acc, dSpeedToCnt, dPosToCnt); string sReceive = null; //나중에 인터락 추가하면 여기에!!! //eResult = MotionInterlockCheck(AxisID, dAddPos); //if (eResult != AlarmCode.AL_0000_OK) // return eResult; try { PMACSendData(strCmd, ref sReceive); } catch (Exception ex) { EquipmentLogManager.Instance.WriteExceptionLog(ex.StackTrace + "\r\n" + ex.Message); } //if (GetAxisStatus(AxisID, AxisStatus.Error)) // eResult = Alarm_List.AL_STAGE_Y_AXIS_ALARM + axis; return true; //return true; } public bool MoveJog(PmacAxis AxisID, double Vel, MotionDirection dir) { int axis = (int)AxisID; double dSpeedToCnt = Vel * GetMotorScaleFactor(AxisID) / 1000.0; string sReceive = null; //SimulationMode //if (_parentForm.m_bSimulationMode) //{ // if (dir == MotionDirection.Plus) // { // m_dTargetSpeed[(int)AxisID] = Vel; // m_SimulCommand[(int)AxisID] = SimulCommand.JOGP; // } // else // { // m_dTargetSpeed[(int)AxisID] = -Vel; // m_SimulCommand[(int)AxisID] = SimulCommand.JOGN; // } // return eResult; //} // set Speed string strCmd = string.Format("Motor[{0}].JogSpeed={1}", GetAxisPMacNum(AxisID), dSpeedToCnt); PMACSendData(strCmd, ref sReceive); // Jog move if (dir == MotionDirection.Plus) strCmd = string.Format("#{0}J+", GetAxisPMacNum(AxisID)); else if (dir == MotionDirection.Minus) strCmd = string.Format("#{0}J-", GetAxisPMacNum(AxisID)); return PMACSendData(strCmd, ref sReceive); } public bool MoveStop(PmacAxis AxisID) { string sReceive = null; //대곤 제공 방식으로 쓰자! string strCmd = string.Format("Mtr_Cmd({0})=Mtr_080_ExeStop", GetAxisPMacNum(AxisID)); PMACSendData(strCmd, ref sReceive); return true; } public bool MoveXYTStop() { MoveStop(PmacAxis.X_Axis); MoveStop(PmacAxis.Y_Axis); MoveStop(PmacAxis.T_Axis); return true; } public bool IsLoadPosition() { bool isMotorXLoadPosition = InpositionCheck(m_AxisAllList[(int)PmacAxis.X_Axis].TeachList[(int)EnTeachData.LoadPosX].Position, GetAxisActualPos(PmacAxis.X_Axis)); bool isMotorYLoadPosition = InpositionCheck(m_AxisAllList[(int)PmacAxis.Y_Axis].TeachList[(int)EnTeachData.LoadPosY].Position, GetAxisActualPos(PmacAxis.Y_Axis)); bool isMotorTLoadPosition = InpositionCheck(m_AxisAllList[(int)PmacAxis.T_Axis].TeachList[(int)EnTeachData.LoadPosT].Position, GetAxisActualPos(PmacAxis.T_Axis)); return isMotorXLoadPosition && isMotorYLoadPosition && isMotorTLoadPosition; } public bool IsCenterPosition() { bool isMotorXCenterPosition = InpositionCheck(m_AxisAllList[(int)PmacAxis.X_Axis].TeachList[(int)EnTeachData.CenterPosX].Position, GetAxisActualPos(PmacAxis.X_Axis)); bool isMotorYCenterPosition = InpositionCheck(m_AxisAllList[(int)PmacAxis.Y_Axis].TeachList[(int)EnTeachData.CenterPosY].Position, GetAxisActualPos(PmacAxis.Y_Axis)); bool isMotorTCenterPosition = InpositionCheck(m_AxisAllList[(int)PmacAxis.T_Axis].TeachList[(int)EnTeachData.CenterPosT].Position, GetAxisActualPos(PmacAxis.T_Axis)); return isMotorXCenterPosition && isMotorYCenterPosition && isMotorTCenterPosition; } public bool IsPowerMeterPosition() { bool isMotorXPowerMeterPosition = InpositionCheck(m_AxisAllList[(int)PmacAxis.X_Axis].TeachList[(int)EnTeachData.PowerMeterX].Position, GetAxisActualPos(PmacAxis.X_Axis)); bool isMotorYPowerMeterPosition = InpositionCheck(m_AxisAllList[(int)PmacAxis.Y_Axis].TeachList[(int)EnTeachData.PowerMeterY].Position, GetAxisActualPos(PmacAxis.Y_Axis)); bool isMotorTPowerMeterPosition = InpositionCheck(m_AxisAllList[(int)PmacAxis.T_Axis].TeachList[(int)EnTeachData.PowerMeterT].Position, GetAxisActualPos(PmacAxis.T_Axis)); return isMotorXPowerMeterPosition && isMotorYPowerMeterPosition && isMotorTPowerMeterPosition; } public bool IsAlignPosition() { bool isMotorXAlignPosition = InpositionCheck(m_AxisAllList[(int)PmacAxis.X_Axis].TeachList[(int)EnTeachData.AlignX].Position, GetAxisActualPos(PmacAxis.X_Axis)); bool isMotorYAlignPosition = InpositionCheck(m_AxisAllList[(int)PmacAxis.Y_Axis].TeachList[(int)EnTeachData.AlignY].Position, GetAxisActualPos(PmacAxis.Y_Axis)); bool isMotorTAlignPosition = InpositionCheck(m_AxisAllList[(int)PmacAxis.T_Axis].TeachList[(int)EnTeachData.AlignT].Position, GetAxisActualPos(PmacAxis.T_Axis)); return isMotorXAlignPosition && isMotorYAlignPosition && isMotorTAlignPosition; } public bool IsBeamProfilePosition() { bool isMotorXBeamProfilePosition = InpositionCheck(m_AxisAllList[(int)PmacAxis.X_Axis].TeachList[(int)EnTeachData.BeamProfileX].Position, GetAxisActualPos(PmacAxis.X_Axis)); bool isMotorYBeamProfilePosition = InpositionCheck(m_AxisAllList[(int)PmacAxis.Y_Axis].TeachList[(int)EnTeachData.BeamProfileY].Position, GetAxisActualPos(PmacAxis.Y_Axis)); bool isMotorTBeamProfilePosition = InpositionCheck(m_AxisAllList[(int)PmacAxis.T_Axis].TeachList[(int)EnTeachData.BeamProfileT].Position, GetAxisActualPos(PmacAxis.T_Axis)); return isMotorXBeamProfilePosition && isMotorYBeamProfilePosition && isMotorTBeamProfilePosition; } public bool InpositionCheck(double tagetPosition, double currentPosition, double inpositionRange = 1) { if(tagetPosition - inpositionRange <= currentPosition && currentPosition <= tagetPosition + inpositionRange) { return true; } else { return false; } } //public bool WriteRead(string command, out string receivedData) //{ // /* 2022 09 23 : Test // * command : motor[1].ActPos motor[1].ActVel motor[1].AmpFault motor[1].HomeComplete motor[1].InPos motor[1].AmpEna motor[1].ServoCtrl // * receivedData : Motor[1].ActPos=3659750.146484375\r\nMotor[1].ActVel=0\r\nMotor[1].AmpFault=0\r\nMotor[1].HomeComplete=1\r\nMotor[1].InPos=0\r\nMotor[1].AmpEna=0\r\nMotor[1].ServoCtrl=0\r\n // */ // byte[] commandBytes = Encoding.ASCII.GetBytes(command); // byte[] receivedBytes = new byte[1024]; // uint result = PowerPmac.DTKGetResponseA(_deviceID, commandBytes, receivedBytes, receivedBytes.GetLength(0)); // if ((DTK_STATUS)result == DTK_STATUS.DS_Ok) // { // receivedData = Encoding.Default.GetString(receivedBytes).TrimEnd('\0'); // return true; // } // else // { // if ((DTK_STATUS)result == DTK_STATUS.DS_NotConnected) // { // //통신모드가 GetSend 상태임 // } // else if ((DTK_STATUS)result == DTK_STATUS.DS_InvalidDevice) // { // //유효하지 않은 장치 번호 // } // else if ((DTK_STATUS)result == DTK_STATUS.DS_InvalidCommand) // { // //유효하지 않은 명령어 (NULL) // } // else if ((DTK_STATUS)result == DTK_STATUS.DS_InvalidResponse) // { // //유효하지 않은 응답 버퍼(NULL) // } // else if ((DTK_STATUS)result == DTK_STATUS.DS_DataRemains) // { // //수신 버퍼에 데이터가 남아 있음 // } // else if ((DTK_STATUS)result == DTK_STATUS.DS_CmdLengthExceeds) // { // //명령어 데이터 길이 초과 // } // else if ((DTK_STATUS)result == DTK_STATUS.DS_ResLengthExceeds) // { // //응답 데이터 길이 초과 // } // else if ((DTK_STATUS)result == DTK_STATUS.DS_RunningDownload) // { // //다운로드 중 // } // else if (result >= 1000) // { // //통신 오류 (기술 지원 요청) // } // receivedData = string.Empty; // return false; // } //} } [Serializable] public class AxisInfo { public AxisInfo() { } public AxisInfo(int nAxisNo_1Base) { _AxisNo = nAxisNo_1Base; _EnumAxisNo = nAxisNo_1Base; _UseAxis = false; _AxisType = AxisType.SERVO; _Name = ""; _HommingCmd = ""; _HomeEndCmd = ""; _PlcNo = 0; _dScale = 0; _dSWPlusLimit = 100000; _dSWMinusLimit = 0; _nTimeout = 10000; } private int _AxisNo; private int _EnumAxisNo; private bool _UseAxis; private AxisType _AxisType; private string _Name; private string _HommingCmd; private string _HomeEndCmd; private int _PlcNo; private double _dScale; private double _dSWPlusLimit; private double _dSWMinusLimit; private int _nTimeout; private int _nHommingTimeout; private double _dHommingSpeed; private List _TeachData = new List(); public int EnumAxisNo { get { return _EnumAxisNo; } set { _EnumAxisNo = value; } } public int AxisNo { get { return _AxisNo; } set { _AxisNo = value; } } //public bool UseAxis //{ // get { return _UseAxis; } // set { _UseAxis = value; } //} public AxisType AxisType { get { return _AxisType; } set { _AxisType = value; } } public string Name { get { return _Name; } set { _Name = value; } } public string HommingCmd { get { return _HommingCmd; } set { _HommingCmd = value; } } public string HomeEndCmd { get { return _HomeEndCmd; } set { _HomeEndCmd = value; } } public double Scale { get { return _dScale; } set { _dScale = value; } } public double SWPlusLimit { get { return _dSWPlusLimit; } set { _dSWPlusLimit = value; } } public double SWMinusLimit { get { return _dSWMinusLimit; } set { _dSWMinusLimit = value; } } public int Timeout { get { return _nTimeout; } set { _nTimeout = value; } } public int HommingTimeout { get { return _nHommingTimeout; } set { _nHommingTimeout = value; } } public double HommingSpeed { get { return _dHommingSpeed; } set { _dHommingSpeed = value; } } public List TeachList { get { return _TeachData; } set { _TeachData = value; } } } [Serializable] public class Teach_Data { public Teach_Data() { _Teach_Name = ""; _dPositon = 0; _dSpeed = 0; _dAccel = 0; } private string _Teach_Name; private double _dPositon; private double _dSpeed; private double _dAccel; public string Name { get { return _Teach_Name; } set { _Teach_Name = value; } } public double Position { get { return _dPositon; } set { _dPositon = value; } } public double Speed { get { return _dSpeed; } set { _dSpeed = value; } } public double Accel { get { return _dAccel; } set { _dAccel = value; } } } }