using SA_LTT.Base; using System; using System.Threading; namespace SA_LTT.Module { public class Attenuator : ComPort { public enum MotorRunState { Stopped, Accelerating, Decelerating, Running, } public enum MicroSteppingResolution : int { /// /// 1 Motor is driven in full steps mode.Waveplate holder turns once in 15600 steps. /// FullStep = 1, /// /// 2 Half step mode.Waveplate holder turns once in 31200 steps. /// HalfStep = 2 , /// /// 4 Quarter step mode.Waveplate holder turns once in 62400 steps. /// QuaterStep = 4, /// /// 8 Eight step mode.Waveplate holder turns once in 124800 steps. /// EightStep = 8, /// /// 16 Sixteen step mode.Waveplate holder turns once in 249600 steps. /// SixteenStep = 16, } private MotorRunState _motorState; private int _position; private int _speed; private int _accelerationValue; private int _decelerationValue; private MicroSteppingResolution _steppingResolution; private bool _motorEnable; private Equipment _equipment; private Thread t_statusUpdate; public double DegreePerSecondFromSpeed { get { return 14400000 / (78 * (int)SteppingResolution * (65535 - Speed)); } } public int Position { get { return _position; } private set { _position = value; } } public double Degree { get { return Math.Round(Position * GetDegreefromSteppingResolution(), 3); } } public int Speed { get { return _speed; } private set { _speed = value; } } public int AccelerationValue { get { return _accelerationValue; } private set { _accelerationValue = value; } } public int DecelerationValue { get { return _decelerationValue; } private set { _decelerationValue = value; } } public MicroSteppingResolution SteppingResolution { get { return _steppingResolution; } private set { _steppingResolution = value; } } public bool MotorEnable { get { return _motorEnable; } private set { _motorEnable = value; } } public MotorRunState MotorState { get { return _motorState; } private set { _motorState = value; } } public Attenuator(Equipment equipment) { serialPort.PortName = "COM11"; serialPort.BaudRate = 38400; serialPort.Parity = System.IO.Ports.Parity.None; serialPort.DataBits = 8; serialPort.StopBits = System.IO.Ports.StopBits.One; serialPort.ReadTimeout = 500; ReceiveWaitSeconds = 0.5; Terminator = "\n\r"; _steppingResolution = MicroSteppingResolution.FullStep; _equipment = equipment; t_statusUpdate = new Thread(statusUpdate); t_statusUpdate.Start(); } public void statusUpdate() { while (_equipment.IsDisposed == false) { try { Thread.Sleep(50); if (IsOpen) { ReadSettings(); ReadStatus(); } else { if (_equipment.alarmManager.OccurredAlarms.Exists(x => x.Code == AlarmCode.AL_0053_ATTENUATOR_DISCONNECTED)) { } else { if (Open() == false) { _equipment.alarmManager.Occur(AlarmCode.AL_0053_ATTENUATOR_DISCONNECTED); } } } } catch (Exception e) { EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace); } } } public void Home() { Write("zp"); } public void Stop() { Write("st"); } public void MoveAbsolute(float angle) { int position = (int)(angle / GetDegreefromSteppingResolution()); Write($"g {position}"); } public void MoveAbsolute(int position) { Write($"g {position}"); } public void MoveRelative(double angle) { int position = (int)(angle / GetDegreefromSteppingResolution()); Write($"m {position}"); } public void MoveRelative(int position) { Write($"m {position}"); } public void JogPositive() { Write($"m 2147483646"); } public void JogNegative() { Write($"m -2147483646"); } public bool IsAttenuatorAngleCorrect(float angle) { if (Position == (int)(angle / GetDegreefromSteppingResolution())) { return true; } else { return false; } } public void SetMicroSteppingResolution(MicroSteppingResolution steppingResolution) { if (steppingResolution == MicroSteppingResolution.SixteenStep) { Write($"r 6"); } else { Write($"r {(int)steppingResolution}"); } } public double GetDegreefromSteppingResolution() { double degree = 360.0 / (78 * (int)SteppingResolution * 200); return degree; } public double GetDegreePerSecondFromSpeed(int speed) { double degreePerSecond = 14400000 / (78 * (int)SteppingResolution * (65535 - speed)); return degreePerSecond; } public int GetSpeedFromDegreePerSecond(double degreePerSecond) { int speed = (int)Math.Ceiling(65535 - 14400000 / (degreePerSecond * 78 * (int)SteppingResolution)); return speed; } /// /// 0 is turn off. /// /// public void SetAcceleration(int acceleration) { if(acceleration > 255) { acceleration = 255; } else if (acceleration < 0) { acceleration = 0; } Write($"a {acceleration}"); } /// /// 0 is turn off /// /// public void SetDeceleration(int deceleration) { if (deceleration > 255) { deceleration = 255; } else if (deceleration < 0) { deceleration = 0; } Write($"d {deceleration}"); } public void SetSpeed(int speed) { if (speed > 65000) { speed = 65000; } else if (speed < 1) { speed = 1; } Write($"s {speed}"); } public void SaveSetting() { Write("ss"); } public void ReadStatus() { string receivedData; if (WriteRead("o", out receivedData)) { string[] status = receivedData.Split(';'); if (status.Length < 2) return; MotorState = (MotorRunState)Enum.Parse(typeof(MotorRunState), status[0]); int position; int.TryParse(status[1], out position); this.Position = position; } else { } } public void ReadSettings() { try { string receivedData; if (WriteRead("pc", out receivedData)) { string[] settings = receivedData.Split(';'); if (settings.Length < 25) return; bool operatingMode = settings[0] == "1" ? true : false; MotorState = (MotorRunState)Enum.Parse(typeof(MotorRunState), settings[1]); AccelerationValue = int.Parse(settings[2]); DecelerationValue = int.Parse(settings[3]); Speed = int.Parse(settings[4]); int motionCurrentValue = int.Parse(settings[5]); int idleCurrentValue = int.Parse(settings[6]); int stepDirCurrentvalue = int.Parse(settings[7]); if (settings[8] == "6") { SteppingResolution = MicroSteppingResolution.SixteenStep; } else { SteppingResolution = (MicroSteppingResolution)Enum.Parse(typeof(MicroSteppingResolution), settings[8]); } MotorEnable = settings[9] == "1" ? true : false; // settings[11] 필요 없을듯. // settings[12] 필요 없을듯. Zero position 올 때마다 zp:[integerValue] 리턴해 주는거. 굳이 ..? // settings[13] Reserved // settings[14] Reserved // settings[15] Reserved // settings[16] 필요 없을듯. // settings[21] Reserved // settings[22] Reserved // settings[23] Reserved } } catch(Exception e) { EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace); } } public new bool Write(string command) { lock (this) { //base.Write(command + '\r'); //return true; Terminator = null; string data = base.WriteRead(command + '\r'); if (data.StartsWith(command.Split(' ')[0])) { return true; } else { return false; } } } public bool WriteRead(string command, out string receivedData) { lock (this) { Terminator = "\n\r"; string data = base.WriteRead(command + '\r'); if (data.StartsWith(command.Split(' ')[0])) { receivedData = data.Remove(0, command.Split(' ')[0].Length).Replace("\n\r", ""); return true; } else { receivedData = string.Empty; return false; } } } } }