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