using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace SA_LTT.Module { public class FFU : ComPort { #region define Packet /// /// Start /// public readonly byte STX = 0x02; /// /// Read Mode /// public readonly byte MODE_Read = 0x8a; /// /// Control Mode /// public readonly byte MODE_Control = 0x89; /// /// Default /// public readonly byte MODE2 = 0x9f; /// /// MCUL32 의 ID값 /// public byte MCUL_ID = 0x81; /// /// Defualt /// public readonly byte DPU_ID = 0x9f; /// /// FFU Controller(LCU)의 첫번째 ID 값 /// ID가 1인 경우 10000001 (0x81) /// public byte Start_LCU_ID = 0x81; /// /// FFU Controller(LCU)의 마지막 ID 값 /// ID가 5인 경우 10000101 (0x85) /// public byte End_LCU_ID = 0x81; /// /// {MODE1+MODE2+ … + mmAq HSV} => 하위바이트 /// //public byte Check_Sum { get; set; } /// /// End /// public readonly byte EXT = 0x03; #endregion /// /// Channel, FFU Status /// public Dictionary FFU_Status { get; } private Equipment _equipment; private Thread t_statusUpdate; public FFU(Equipment equipment) { serialPort.PortName = "COM8"; serialPort.BaudRate = 9600; serialPort.Parity = System.IO.Ports.Parity.None; serialPort.DataBits = 8; serialPort.StopBits = System.IO.Ports.StopBits.One; Terminator = null; FFU_Status = new Dictionary(); FFU_Status.Add(1, new FFUStatus(1)); _equipment = equipment; t_statusUpdate = new Thread(statusUpdate); t_statusUpdate.Start(); } public void statusUpdate() { while (_equipment.IsDisposed == false) { try { Thread.Sleep(50); if (IsOpen) { foreach(int key in FFU_Status.Keys) { // Todo. Command 설정. ReadFFUStatus(key); } } else { if (_equipment.alarmManager.OccurredAlarms.Exists(x => x.Code == AlarmCode.AL_0055_FFU_DISCONNECTED)) { } else { if (Open() == false) { _equipment.alarmManager.Occur(AlarmCode.AL_0055_FFU_DISCONNECTED); } } } } catch (Exception e) { EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace); } } } public bool ReadFFUStatus(int address) { try { if (!FFU_Status.ContainsKey(address)) return false; byte Start_LCU_ID = (byte)(address | 0x80); byte End_LCU_ID = (byte)(address | 0x80); List datas = new List(); datas.Clear(); datas.Add(MODE_Control); datas.Add(MODE2); datas.Add(MCUL_ID); datas.Add(DPU_ID); datas.Add(Start_LCU_ID); datas.Add(End_LCU_ID); datas.Add(GetCheckSum(datas.ToArray())); datas.Insert(0, STX); datas.Add(EXT); byte[] rcvData; //Todo. Write read 반환 값 Test 해야 댐. //if (WriteRead(datas.ToArray(), out rcvData)) //{ // FFU_Status[address].SetData_PV(rcvData[6]); // FFU_Status[address].ChangeStatus(rcvData[7]); // FFU_Status[address].SetData_SV(rcvData[8]); // FFU_Status[address].SetmmAq(rcvData[9], rcvData[10]); // return true; //} //else // return false; return true; } catch (Exception e) { EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace); return false; } } public bool WritemmAqSV(double mmAq) { mmAq *= 100; try { if (!FFU_Status.ContainsKey(1)) return false; int a = (int)(mmAq); string data = a.ToString("x"); byte daH, daL; if (data.Length > 4) return false; if (data.Length == 4) { daH = Convert.ToByte(data.Substring(0, 2), 16); daL = Convert.ToByte(data.Substring(2, 2), 16); } else if (data.Length == 3) { daH = Convert.ToByte(data.Substring(0, 1), 16); daL = Convert.ToByte(data.Substring(1, 2), 16); } else { daH = 0x00; daL = Convert.ToByte(data, 16); } List datas = new List(); datas.Clear(); datas.Add(MODE_Control); //89 datas.Add(MODE2); //9f datas.Add(MCUL_ID); //81 datas.Add(DPU_ID); //9f datas.Add(Start_LCU_ID); //81 datas.Add(End_LCU_ID); //82 datas.Add(daL); //01 datas.Add(daH); //00 datas.Add(daL); //00 datas.Add(daH); //00 datas.Add(daL); //32 datas.Add(daH); //00 datas.Add(GetCheckSum(datas.ToArray())); //7e datas.Insert(0, STX); //02 datas.Add(EXT); //03 string recvData; if (WriteRead(datas.ToArray(), out recvData)) { byte[] bytesData = Encoding.Default.GetBytes(recvData); foreach (byte bb in recvData) { if (bb == 0xb9) return true; } } return false; } catch (Exception e) { EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace); return false; } } /// /// Check Sum 계산 Method /// /// Command byte 배열 /// public byte GetCheckSum(byte[] datas) { int sum = 0; foreach (byte data in datas) { sum += data; } string proc_data = sum.ToString("x"); proc_data = proc_data.Substring(proc_data.Length - 2, 2); byte value = Convert.ToByte(proc_data, 16); return value; } public bool WriteRead(string command, out string receivedData) { 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; } } public bool WriteRead(byte[] command, out string receivedData) { string data = base.WriteRead(command); receivedData = data; return true; } } /// /// MCUL32에 연결되어 있는 FFU Status /// public class FFUStatus { public enum AL_ST_Datas { Remote_Control_Mode = 0x80, Local_Control_Mode = 0x81, Thermal_Relay_Alarm = 0x82,//Not used Open_the_door = 0x84,//Not used Setting_Alarm = 0x88,//(SV>Max or SVHSV or PV /// FFU Controller(LCU)의 ID 값 /// public int LCU_ID { get; private set; } /// /// LCU의 지령 속도 값(RPM) 0 ~ 1400RPM (0x00 ~ 0x8C) /// public int Data_SV { get; private set; } /// /// LCU의 현재 속도 값(RPM) /// public int Data_PV { get; private set; } /// /// 압력센서 값 (단위 : mmAq) /// public double mmAq { get; private set; } /// /// 압력센서 값 Low /// public byte mmAqLSV { get; private set; } /// /// 압력센서 값 High /// public byte mmAqHSV { get; private set; } #endregion #region Change Datas /// /// Alarm, Status 변경 Method /// /// AL_ST byte Data public void ChangeStatus(byte AL_ST) { try { if ((AL_ST & (byte)AL_ST_Datas.Remote_Control_Mode) == (byte)AL_ST_Datas.Remote_Control_Mode) Remote_Control_Mode = true; else Remote_Control_Mode = false; if ((AL_ST & (byte)AL_ST_Datas.Local_Control_Mode) == (byte)AL_ST_Datas.Local_Control_Mode) Local_Control_Mode = true; else Local_Control_Mode = false; if ((AL_ST & (byte)AL_ST_Datas.Thermal_Relay_Alarm) == (byte)AL_ST_Datas.Thermal_Relay_Alarm) Thermal_Relay_Alarm = true; else Thermal_Relay_Alarm = false; if ((AL_ST & (byte)AL_ST_Datas.Open_the_door) == (byte)AL_ST_Datas.Open_the_door) Open_the_door = true; else Open_the_door = false; if ((AL_ST & (byte)AL_ST_Datas.Setting_Alarm) == (byte)AL_ST_Datas.Setting_Alarm) Setting_Alarm = true; else Setting_Alarm = false; if ((AL_ST & (byte)AL_ST_Datas.RPM_Alarm) == (byte)AL_ST_Datas.RPM_Alarm) RPM_Alarm = true; else RPM_Alarm = false; if ((AL_ST & (byte)AL_ST_Datas.Auto_controlling_for_Over_Current) == (byte)AL_ST_Datas.Auto_controlling_for_Over_Current) Auto_controlling_for_Over_Current = true; else Auto_controlling_for_Over_Current = false; if ((AL_ST & (byte)AL_ST_Datas.Over_Current_Alarm) == (byte)AL_ST_Datas.Over_Current_Alarm) Over_Current_Alarm = true; else Over_Current_Alarm = false; if ((AL_ST & (byte)AL_ST_Datas.No_Connection_LCU) == (byte)AL_ST_Datas.No_Connection_LCU) No_Connection_LCU = true; else No_Connection_LCU = false; } catch (Exception) { } } /// /// Data SV 변경. /// /// Data_SV byte Data public void SetData_SV(byte Data_SV) { this.Data_SV = Data_SV * 10; } /// /// Data PV 변경. /// /// Data_PV byte Data public void SetData_PV(byte Data_PV) { this.Data_PV = Data_PV * 10; } /// /// mmAq Data 변경 /// /// 압력센서 값(하위 바이트) /// 압력센서 값(상위 바이트) public void SetmmAq(byte mmAqLSV, byte mmAqHSV) { try { this.mmAqHSV = mmAqHSV; this.mmAqLSV = mmAqLSV; string proc_mmAq = $"{mmAqHSV.ToString("x")}{mmAqLSV.ToString("x")}"; this.mmAq = Convert.ToInt32(proc_mmAq, 16) / 100.0; } catch (Exception) { } } #endregion } }