using log4net; using System; using System.Collections; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DIT.Framework.Module { /// /// Model : PMC-2HS-232 /// Home : www.autonics.com /// public class Autonics_PMC_2HS : SerialModule { #region 파라미터 /// /// Exception Log /// private ILog ExceptionLog = LogManager.GetLogger("Autonics_PMC_2HS_Exception"); /// /// Exception Log를 기록하기 위한 메서드 /// /// Error Message private void WriteExceptionLog(string msg) { if (UseExceptionLog) ExceptionLog.Debug(msg); } /// /// X축의 Status /// public MotorStatus Status_X { get { return status_x; } private set { status_x = value; } } private MotorStatus status_x; /// /// Y축의 Status /// public MotorStatus Status_Y { get { return status_y; } private set { status_y = value; } } private MotorStatus status_y; /// /// Parallel의 Status /// public ParallelStatus Status_Parallel { get { return status_parallel; } private set { status_parallel = value; } } private ParallelStatus status_parallel; /// /// X축 현재위치 /// public int PosX { get { return posx; } private set { posx = value; } } private int posx; /// /// Y축 현재위치 /// public int PosY { get { return posy; } private set { posy = value; } } private int posy; /// /// X축 현재 Speed /// public int SpeedX { get { return speedx; } private set { speedx = value; } } private int speedx; /// /// Y축 현재 Speed /// public int SpeedY { get { return speedy; } private set { speedy = value; } } private int speedy; #endregion /// /// Autonics_PMC_2HS의 생성자. /// /// Port이름 ex)COM6, COM13 /// 전송속도 ex)4800, 9600, 19200 /// 바이트 당 데이터 비트의 표준길이 ex)5, 6, 7, 8 /// 패리티 검사 프로토콜 ex)Ports.Parity.None /// 비트당 정지비트의 표준 개수 ex)Ports.StopBits.One /// 직렬 전송을 위한 핸드셰이킹 ex)Ports.Handshake.None public Autonics_PMC_2HS(string PortName, int BaudRate, int DataBits = 8, Parity Parity = Parity.None, StopBits StopBits = StopBits.One, Handshake Handshake = Handshake.None) : base(PortName, BaudRate, DataBits, Parity, StopBits, Handshake) { SetEncodeType(Encoding.ASCII); Status_X = new MotorStatus(); Status_Y = new MotorStatus(); Status_Parallel = new ParallelStatus(); } /// /// Serial에서 받은 명령어 처리 메서드 /// /// Recv받은 Data private void OnRecvData(byte[] recvData) { try { string[] str = Encoding.ASCII.GetString(recvData).Split(' '); switch (str[0]) { case "ERD": string[] proc_str; proc_str = str[1].Split('X'); int ia = int.Parse(proc_str[1]); BitArray bits = new BitArray(new int[] { ia }); break; case "INR": // X모터값 if (str[1].Contains("X")) { string x_motor = str[1].Split('X')[1].Split(',')[0]; string parallel = str[2].Split('\r')[0]; Status_X.StatusChange(x_motor); Status_Parallel.StatusChange(parallel); } // Y모터값 else if (str[1].Contains("Y")) { string y_motor = str[1].Split('Y')[1].Split(',')[0]; string parallel = str[2].Split('\r')[0]; Status_Y.StatusChange(y_motor); Status_Parallel.StatusChange(parallel); } break; case "SPD": string proc_data = Encoding.Default.GetString(recvData); string[] speeds = proc_data.Split('D'); string[] speed = speeds[1].Split(','); int spd = 0; if (int.TryParse(speed[0], out spd)) SpeedX = spd; if (int.TryParse(speed[1], out spd)) SpeedY = spd; break; case "POS": string[] poss = str[1].Split(','); PosX = Convert.ToInt32(poss[0], 16); PosY = Convert.ToInt32(poss[1].Split('\r')[0], 16); break; } } catch(Exception ex) { WriteExceptionLog(ex.Message); } } #region 명령어 /// /// X축 HOME /// public void Home_X() { string cmd = $"HOM X{CR}"; SendData(Encoding.ASCII.GetBytes(cmd)); } /// /// Y축 HOME /// public void Home_Y() { string cmd = $"HOM Y{CR}"; SendData(Encoding.ASCII.GetBytes(cmd)); } /// /// X축 HOME Stop /// public void Home_X_Stop() { string cmd = $"OGE X{CR}"; SendData(Encoding.ASCII.GetBytes(cmd)); } /// /// Y축 HOME Stop /// public void Home_Y_Stop() { string cmd = $"OGE Y{CR}"; SendData(Encoding.ASCII.GetBytes(cmd)); } /// /// X축 실제 위치 클리어 /// public void X_Pos_Clear() { string cmd = $"CLR X{CR}"; SendData(Encoding.ASCII.GetBytes(cmd)); } /// /// Y축 실제 위치 클리어 /// public void Y_Pos_Clear() { string cmd = $"CLR Y{CR}"; SendData(Encoding.ASCII.GetBytes(cmd)); } /// /// X축 내부 프로그램 지정 번지부터 실행 /// /// 번지 public void Proc_X_Run(int value) { string cmd = $"PRG X{value}{CR}"; SendData(Encoding.ASCII.GetBytes(cmd)); } /// /// Y축 내부 프로그램 지정 번지부터 실행 /// /// 번지 public void Proc_Y_Run(int value) { string cmd = $"PRG Y{value}{CR}"; SendData(Encoding.ASCII.GetBytes(cmd)); } /// /// X축 내부 프로그램 지정 번지 실행 /// /// 번지 public void Proc_X_Step(int value) { string cmd = $"PST X{value}{CR}"; SendData(Encoding.ASCII.GetBytes(cmd)); } /// /// Y축 내부 프로그램 지정 번지 실행 /// /// 번지 public void Proc_Y_Step(int value) { string cmd = $"PST Y{value}{CR}"; SendData(Encoding.ASCII.GetBytes(cmd)); } /// /// X축 내부 프로그램 일시정지 /// public void Proc_X_Stop() { string cmd = $"PSP X{CR}"; SendData(Encoding.ASCII.GetBytes(cmd)); } /// /// Y축 내부 프로그램 일시정지 /// public void Proc_Y_Stop() { string cmd = $"PSP Y{CR}"; SendData(Encoding.ASCII.GetBytes(cmd)); } /// /// X축 속도 설정 /// /// 속도 public void Set_Speed_X(int value) { string cmd = $"SPD {value}{CR}"; SendData(Encoding.ASCII.GetBytes(cmd)); } /// /// Y축 속도 설정 /// /// 속도 public void Set_Speed_Y(int value) { string cmd = $"SPD ,{value}{CR}"; SendData(Encoding.ASCII.GetBytes(cmd)); } /// /// X축 +위치로 이동 /// public void Move_X_Plus() { string cmd = $"JOG +X{CR}"; SendData(Encoding.ASCII.GetBytes(cmd)); } /// /// X축 -위치로 이동 /// public void Move_X_Minus() { string cmd = $"JOG -X{CR}"; SendData(Encoding.ASCII.GetBytes(cmd)); } /// /// Y축 +위치로 이동 /// public void Move_Y_Plus() { string cmd = $"JOG +Y{CR}"; SendData(Encoding.ASCII.GetBytes(cmd)); } /// /// Y축 -위치로 이동 /// public void Move_Y_Minus() { string cmd = $"JOG -Y{CR}"; SendData(Encoding.ASCII.GetBytes(cmd)); } /// /// X축 절대이동 /// /// 이동 위치 public void Move_X_ABS(int value) { string cmd = $"PAB {value}{CR}"; SendData(Encoding.ASCII.GetBytes(cmd)); } /// /// Y축 절대이동 /// /// 이동 위치 public void Move_Y_ABS(int value) { string cmd = $"PAB ,{value}{CR}"; SendData(Encoding.ASCII.GetBytes(cmd)); } /// /// X축 정지 /// public void Stop_X() { string cmd = $"PSP X{CR}"; SendData(Encoding.ASCII.GetBytes(cmd)); } /// /// Y축 정지 /// public void Stop_Y() { string cmd = $"PSP Y{CR}"; SendData(Encoding.ASCII.GetBytes(cmd)); } /// /// 드라이브 속도 변경 /// /// 1~4 public void Speed_Setting(int value) { string cmd = $"SSM X{value}{CR}"; SendData(Encoding.ASCII.GetBytes(cmd)); } /// /// 드라이브 속도 변경 /// /// X 축 속도 /// Y 축 속도 public void Speed_Setting(int x_value, int y_value) { string cmd = $"SPD {x_value},{y_value}{CR}"; SendData(Encoding.ASCII.GetBytes(cmd)); } /// /// X축 에러 값 요청 /// public void Request_Error_X() { string cmd = $"ERD X{CR}"; byte[] recvData = SendWaitData(Encoding.ASCII.GetBytes(cmd)); if (recvData == null) return; OnRecvData(recvData); } /// /// Y축 에러 값 요청 /// public void Request_Error_Y() { string cmd = $"ERD Y{CR}"; byte[] recvData = SendWaitData(Encoding.ASCII.GetBytes(cmd)); if (recvData == null) return; OnRecvData(recvData); } /// /// X축 현재 상태 요청 /// public void Request_State_X() { string cmd = $"INR X{CR}"; byte[] recvData = SendWaitData(Encoding.ASCII.GetBytes(cmd)); if (recvData == null) return; OnRecvData(recvData); } /// /// Y축 현재 상태 요청 /// public void Request_State_Y() { string cmd = $"INR Y{CR}"; byte[] recvData = SendWaitData(Encoding.ASCII.GetBytes(cmd)); if (recvData == null) return; OnRecvData(recvData); } /// /// PMC 본체의 버전 정보 요청 /// public void Request_Ver() { string cmd = $"VER{CR}"; byte[] recvData = SendWaitData(Encoding.ASCII.GetBytes(cmd)); if (recvData == null) return; OnRecvData(recvData); } /// /// X축과 Y축의 현재 위치 요청 /// public void Request_Pos() { string cmd = $"POS{CR}"; byte[] recvData = SendWaitData(Encoding.ASCII.GetBytes(cmd)); if (recvData == null) return; OnRecvData(recvData); } /// /// X축과 Y축의 현재 속도 요청 /// public void Request_Speed() { string cmd = $"SPD{CR}"; byte[] recvData = SendWaitData(Encoding.ASCII.GetBytes(cmd)); if (recvData == null) return; OnRecvData(recvData); } #endregion #region Motor의 상태를 확인하기 위한 Class /// /// Motor의 상태 클래스 /// public class MotorStatus { #region 프로퍼티 /// /// 서보 위치 결정 완료 /// public bool Inpos { get; private set; } /// /// 서보 알람 /// public bool Alarm { get; private set; } /// /// 엔코더 Z상 /// public bool Stop2 { get; private set; } /// /// 원점 /// public bool Stop1 { get; private set; } /// /// 원점 근접 /// public bool Stop0 { get; private set; } /// /// +방향 리미트 /// public bool Lmt_Plus { get; private set; } /// /// -방향 리미트 /// public bool Lmt_Minus { get; private set; } /// /// 긴급정지 /// public bool EMG { get; private set; } /// /// 드라이브 상태(1 : 드라이브 중 0 :종료) /// public bool DRV { get; private set; } /// /// 에러 발생 상태(1 : 에러) /// public bool ERR { get; private set; } /// /// 자동 원점복귀 상태 (1:동작중) /// public bool HOM { get; private set; } /// /// 드라이브 동작, 원점출력 동작 등(1:ON) /// public bool RUN { get; private set; } /// /// 일시 정지중(1 : 일시정지중) /// public bool PAUSE { get; private set; } /// /// (CN3) 의 nDRIVE 신호(1:ON) /// public bool DRIVE { get; private set; } /// /// (CN3)의 nError 신호(1:ON) /// public bool ERROR { get; private set; } /// /// (CN4, 5)의 nOUT0 신호(1:ON) /// public bool OUT0 { get; private set; } #endregion /// /// Status 변경 /// /// public void StatusChange(string data) { BitArray bit = new BitArray(new int[] { Convert.ToInt32(data, 16) }); Stop0 = bit[0]; Stop1 = bit[1]; Stop2 = bit[2]; Inpos = bit[3]; Lmt_Plus = bit[4]; Lmt_Minus = bit[5]; Alarm = bit[6]; EMG = bit[7]; DRV = bit[8]; ERR = bit[9]; HOM = bit[10]; RUN = bit[11]; PAUSE = bit[12]; OUT0 = bit[13]; DRIVE = bit[14]; ERROR = bit[15]; } } /// /// Parallel 상태 클래스 /// public class ParallelStatus { #region /// /// 원점 복귀 시작 명령 /// public bool Home { get; private set; } /// /// 드라이브 시작명령 /// public bool Strobe { get; private set; } /// /// X축 지정/스캔Y+ /// public bool X { get; private set; } /// /// Y축지정/스캔Y- /// public bool Y { get; private set; } /// /// 레지스터 지정0/ 런+/스캔+ /// public bool RegSL0 { get; private set; } /// /// 레지스터 지정1/ 런-/스캔+ /// public bool RegSL1 { get; private set; } /// /// 레지스터 지정 2/ 드라이브 속도 지정0 /// public bool RegSL2 { get; private set; } /// /// 레지스터 지정3/ 드라이브 속도 지정1 /// public bool RegSL3 { get; private set; } /// /// 레지스터 지정4/ 스캔 지정 /// public bool RegSL4 { get; private set; } /// /// 레지스터 지정5/ 드라이브 정지 /// public bool RegSL5 { get; private set; } /// /// 동작 모드 지정0 /// public bool Mode0 { get; private set; } /// /// 동작 모드 지정1 /// public bool Mode1 { get; private set; } /// /// 0 : 비동작 1:동작 /// public bool PowerOnHome { get; private set; } /// /// 0 : 비동작 1:동작 /// public bool PowerOnProgram { get; private set; } #endregion /// /// Status 변경 /// /// public void StatusChange(string data) { BitArray bit = new BitArray(new int[] { Convert.ToInt32(data, 16) }); Home = bit[0]; Strobe = bit[1]; X = bit[2]; Y = bit[3]; Mode0 = bit[4]; Mode1 = bit[5]; RegSL0 = bit[8]; RegSL1 = bit[9]; RegSL2 = bit[10]; RegSL3 = bit[11]; RegSL4 = bit[12]; RegSL5 = bit[13]; } } #endregion } }