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
}
}