AdTecRF.cs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966
  1. using System;
  2. using System.Threading.Tasks;
  3. using System.Collections;
  4. using System.Text.RegularExpressions;
  5. using Aitex.Core.Common.DeviceData;
  6. using Aitex.Core.RT.DataCenter;
  7. using Aitex.Core.RT.Event;
  8. using Aitex.Core.RT.IOCore;
  9. using Aitex.Core.RT.Log;
  10. using Aitex.Core.RT.OperationCenter;
  11. using Aitex.Core.RT.SCCore;
  12. using Aitex.Core.RT.Tolerance;
  13. using Aitex.Core.Util;
  14. using Aitex.Core.RT.Device;
  15. using MECF.Framework.Common.Communications;
  16. using MECF.Framework.Common.DataCenter;
  17. using MECF.Framework.Common.Device.Bases;
  18. using MECF.Framework.Common.Equipment;
  19. using Venus_Core;
  20. using System.Collections.Generic;
  21. using System.Diagnostics;
  22. using System.Net.Sockets;
  23. using Venus_RT.Modules;
  24. using System.Windows.Interop;
  25. using Venus_RT.Modules.PMs;
  26. namespace Venus_RT.Devices
  27. {
  28. #region RFG
  29. static class AdTecRfMessage
  30. {
  31. public static string ANALOG = "";
  32. public const string EOF = "\r";
  33. public const char DELIMITER = ' ';
  34. public const string MANUAL = "MANUAL";
  35. public const string RS232 = "***";
  36. public const string SET_POWER = " W";
  37. public const string RF_ON = "G";
  38. public const string RF_OFF = "S";
  39. public const string ERR_RES = "N";
  40. public const string QUERY = "Q";
  41. public const string RESET = "RESET";
  42. public const string CHK_COMM = "HS";
  43. }
  44. class AdTecGenerator : RfPowerBase
  45. {
  46. // ----------------------------Fields--------------------------
  47. //
  48. private int QUERY_INTERVAL = 5000;
  49. private const string INFO_PATTERN = @"(\d{7})\s(\d{5})\s(\d{5})\s(\d{5})\s(\d{5})";
  50. private double _total;
  51. private double _fromLast;
  52. private bool _bRFPowerOn = false;
  53. private readonly AsyncSerialPort _serial;
  54. private readonly DeviceTimer _timerQueryStatus = new DeviceTimer();
  55. private readonly DeviceTimer _timerTotal = new DeviceTimer();
  56. private readonly DeviceTimer _timerFromLast = new DeviceTimer();
  57. private readonly DeviceTimer _timerRFTurnOn = new DeviceTimer();
  58. private DateTime _powerOnStartTime;
  59. private TimeSpan _powerOnElapsedTime;
  60. private readonly RD_TRIG _rfOnTrigger = new RD_TRIG();
  61. private readonly R_TRIG _ErrTrigger = new R_TRIG();
  62. private readonly R_TRIG _trigPMNeeded = new R_TRIG();
  63. private readonly RD_TRIG _trigOnOff = new RD_TRIG();
  64. private ToleranceChecker _checkerPower;
  65. private ToleranceChecker _checkerReflectPower;
  66. private readonly double _scPowerAlarmTime;
  67. private readonly double _scPowerAlarmRange;
  68. private readonly double _scPowerWarningTime;
  69. private readonly double _scPowerWarningRange;
  70. private readonly double _scReflectPowerAlarmTime;
  71. private readonly double _scReflectPowerAlarmRange;
  72. private readonly double _scPowerRange;
  73. private readonly DIAccessor _diIntlk;
  74. private StatsDataItemRFAndPump _statRFOnTime = new StatsDataItemRFAndPump();
  75. private readonly VenusDevice _device;
  76. private Stopwatch monitorStopwatch = new Stopwatch();
  77. private JetPMBase _chamber;
  78. //private bool _intrtlockFlag = false;
  79. public bool ConnectedStatus { get; set; }
  80. public override float ScalePower => (float)_scPowerRange;
  81. public GeneratorStatus Status { get; set; }
  82. public string LastPMTime
  83. {
  84. get
  85. {
  86. return _statRFOnTime != null ? _statRFOnTime.LastPMTime.ToString() : "";
  87. }
  88. }
  89. public float DaysFromLastPM
  90. {
  91. get
  92. {
  93. return _statRFOnTime == null ? 0 : _statRFOnTime.fromLastPM;
  94. }
  95. set
  96. {
  97. if (_statRFOnTime != null)
  98. _statRFOnTime.fromLastPM = value;
  99. }
  100. }
  101. public float TotalDays
  102. {
  103. get
  104. {
  105. return _statRFOnTime != null ? _statRFOnTime.Total : 0;
  106. }
  107. set
  108. {
  109. if (_statRFOnTime != null)
  110. _statRFOnTime.Total = value;
  111. }
  112. }
  113. public double PMIntervalDays
  114. {
  115. get
  116. {
  117. return _statRFOnTime != null ? _statRFOnTime.PMInterval : 0;
  118. }
  119. }
  120. public bool IsPMNeeded
  121. {
  122. get
  123. {
  124. return DaysFromLastPM > PMIntervalDays;
  125. }
  126. }
  127. public bool EnableAlarm
  128. {
  129. get
  130. {
  131. return _statRFOnTime == null || _statRFOnTime.AlarmEnable;
  132. }
  133. }
  134. public override bool IsPowerOn
  135. {
  136. get => Status == GeneratorStatus.ON;
  137. set { }
  138. }
  139. public override bool IsError
  140. {
  141. get => Status == GeneratorStatus.ERROR;
  142. set { }
  143. }
  144. [Subscription("PowerOnTime")]
  145. public string PowerOnTime
  146. {
  147. get
  148. {
  149. if (_bRFPowerOn)
  150. _powerOnElapsedTime = DateTime.Now - _powerOnStartTime;
  151. return $"{(int)_powerOnElapsedTime.TotalHours:00}:{_powerOnElapsedTime.Minutes:00}:{(_powerOnElapsedTime.Seconds > 0 ? (_powerOnElapsedTime.Seconds + 1) : 0):00}";
  152. }
  153. }
  154. public bool RFInterlock => _diIntlk == null || _diIntlk.Value;
  155. private float _forwardPower;
  156. public override float ForwardPower
  157. {
  158. get
  159. {
  160. return _forwardPower;
  161. }
  162. set
  163. {
  164. _forwardPower = CalibrationData(value, false);
  165. }
  166. }
  167. public new AITRfData DeviceData =>
  168. new AITRfData
  169. {
  170. Module = Module,
  171. DeviceName = Name,
  172. ScalePower = ScalePower,
  173. ForwardPower = ForwardPower,
  174. ReflectPower = ReflectPower,
  175. IsRfOn = IsPowerOn,
  176. PowerSetPoint = PowerSetPoint,
  177. PowerOnElapsedTime = PowerOnTime,
  178. IsInterlockOk = RFInterlock,
  179. WorkMode = (int)RfMode.ContinuousWaveMode,
  180. DisplayName = "Source RF",
  181. };
  182. // --------------------------Constructor-----------------------
  183. //
  184. public AdTecGenerator(ModuleName mod, VenusDevice device) : base(mod.ToString(), device.ToString())
  185. {
  186. var portNum = SC.GetStringValue(device == VenusDevice.Rf ? $"{mod}.Rf.Port" : $"{mod}.BiasRf.Port");
  187. this.Status = GeneratorStatus.Unknown;
  188. _device = device;
  189. _serial = new AsyncSerialPort(portNum, 9600, 8, System.IO.Ports.Parity.None, System.IO.Ports.StopBits.One, "\r\r");
  190. _scPowerAlarmTime = SC.GetValue<double>($"{Module}.{Name}.PowerAlarmTime");
  191. _scPowerAlarmRange = SC.GetValue<double>($"{Module}.{Name}.PowerAlarmRange");
  192. _scPowerWarningTime = SC.GetValue<double>($"{Module}.{Name}.PowerWarningTime");
  193. _scPowerWarningRange = SC.GetValue<double>($"{Module}.{Name}.PowerWarningRange");
  194. _scReflectPowerAlarmTime = SC.GetValue<double>($"{Module}.{Name}.ReflectPowerAlarmTime");
  195. _scReflectPowerAlarmRange = SC.GetValue<double>($"{Module}.{Name}.ReflectPowerAlarmRange");
  196. _scPowerRange = SC.GetValue<double>($"{Module}.{Name}.PowerRange");
  197. _scEnableCalibration = SC.GetConfigItem($"{Module}.{Name}.EnableCalibration");
  198. _scCalibrationTable = SC.GetConfigItem($"{Module}.{Name}.CalibrationTable");
  199. _scRFPhysicalMaxPower = SC.GetConfigItem($"{Module}.{Name}.RFPhysicalMaxPower");
  200. _scCurrentRFMaxPower = SC.GetConfigItem($"{Module}.{Name}.CurrentRFMaxPower");
  201. _diIntlk = IO.DI[$"{Module}.DI_RF_Generator_Interlock"];
  202. SerachCommandList = new List<string>()
  203. {
  204. AdTecRfMessage.QUERY
  205. };
  206. intervalTime = 300;
  207. sendDataChangedEvent += SkyPump_sendDataChangedEvent;
  208. baseStopwatch.Start();
  209. baseTimer.Enabled = true;
  210. monitorStopwatch.Start();
  211. }
  212. private void SkyPump_sendDataChangedEvent(string obj)
  213. {
  214. var newstr = obj + "\r";
  215. _serial?.Write(newstr);
  216. }
  217. ~AdTecGenerator()
  218. {
  219. _serial?.Close();
  220. }
  221. public override bool Initialize()
  222. {
  223. base.Initialize();
  224. DATA.Subscribe($"{Module}.{Name}.DeviceData", () => DeviceData);
  225. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetPowerOnOff}", (out string reason, int time, object[] param) =>
  226. {
  227. SetPowerOnOff(Convert.ToBoolean((string)param[0]), out reason);
  228. return true;
  229. });
  230. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetPower}", (out string reason, int time, object[] param) =>
  231. {
  232. reason = "";
  233. ushort val = Convert.ToUInt16(param[0]);
  234. SetPower(val);
  235. return true;
  236. });
  237. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetContinuousPower}", (out string reason, int time, object[] param) =>
  238. {
  239. reason = "";
  240. ushort val = Convert.ToUInt16(param[0]);
  241. SetPower(val);
  242. return true;
  243. });
  244. if (_serial.Open())
  245. {
  246. this.ConnectedStatus = true;
  247. _serial.OnDataChanged += SerialPortDataReceived;
  248. _serial.OnErrorHappened += SerialPortErrorOccurred;
  249. }
  250. else
  251. {
  252. this.ConnectedStatus = false;
  253. LOG.Write(eEvent.ERR_RF, Module, "AD TEC 射频发生器串口无法打开");
  254. return false;
  255. }
  256. _statRFOnTime = StatsDataManager.Instance.GetItemRFAndPump($"{Module}.{Name}OnTime");
  257. _timerQueryStatus.Start(QUERY_INTERVAL);
  258. _checkerPower = new ToleranceChecker(_scPowerAlarmTime);
  259. _checkerReflectPower = new ToleranceChecker(_scReflectPowerAlarmTime);
  260. SetCommunicationMode(1);
  261. return true;
  262. }
  263. public override void Monitor()
  264. {
  265. // 状态查询
  266. //if (_timerQueryStatus.IsTimeout())
  267. //{
  268. // this.SendCmd(AdTecRfMessage.QUERY);
  269. // _timerQueryStatus.Start(QUERY_INTERVAL);
  270. //}
  271. // power on triggered
  272. _rfOnTrigger.CLK = IsPowerOn;
  273. if (_rfOnTrigger.R)
  274. {
  275. _total = TotalDays;
  276. _fromLast = DaysFromLastPM;
  277. _timerTotal.Start(0);
  278. _timerFromLast.Start(0);
  279. _timerTotal.Restart(0);
  280. _timerFromLast.Restart(0);
  281. _powerOnStartTime = DateTime.Now;
  282. _checkerPower.Reset(_scPowerAlarmTime);
  283. _checkerReflectPower.Reset(_scReflectPowerAlarmTime);
  284. _alarmChecker.Reset(_scPowerAlarmTime);
  285. _warningChecker.Reset(_scPowerWarningTime);
  286. }
  287. if (_rfOnTrigger.M)
  288. {
  289. TotalDays =Convert.ToSingle( _timerTotal.GetElapseTime() / 1000 / 60 / 60);
  290. DaysFromLastPM = Convert.ToSingle(_timerFromLast.GetElapseTime() / 1000 / 60 / 60);
  291. }
  292. if (PMIntervalDays > 0)
  293. {
  294. _trigPMNeeded.CLK = IsPMNeeded;
  295. if (_trigPMNeeded.Q)
  296. {
  297. if (EnableAlarm)
  298. {
  299. LOG.Write(eEvent.ERR_RF, Module, "rf on time value larger than setting interval days");
  300. }
  301. }
  302. }
  303. if (_rfOnTrigger.T)
  304. {
  305. _timerTotal.Stop();
  306. _timerFromLast.Stop();
  307. StatsDataManager.Instance.Increase($"{Module}.{Name}OnTime", $"{Module} {Name} OnTime", DaysFromLastPM, TotalDays);
  308. }
  309. if (!_rfOnTrigger.CLK)
  310. {
  311. //ForwardPower = 0;
  312. //ReflectPower = 0;
  313. }
  314. // 通信 checking, 2 second 一次
  315. //if (_timerComm.IsTimeout() && !_bQueryComm)
  316. //{
  317. // this.SendCmd(AdTecRfMessage.CHK_COMM);
  318. // _bQueryComm = true;
  319. // _timerComm.Start(CHK_COMM_INTERVAL);
  320. //}
  321. // RF Turn On & Off Timeout Check
  322. _trigOnOff.CLK = _bRFPowerOn;
  323. if (_trigOnOff.R) //RF Turn On
  324. {
  325. _timerRFTurnOn.Start(SC.GetValue<int>($"{Module}.{Name}.RFTurnOnTimeout") * 1000);
  326. }
  327. if (_trigOnOff.M) //RF Stay On
  328. {
  329. if (_timerRFTurnOn.IsTimeout())
  330. {
  331. if (!IsPowerOn)
  332. {
  333. LOG.Write(eEvent.ERR_RF, Module, $"{Name} Turn On Failed");
  334. _timerRFTurnOn.Stop();
  335. }
  336. }
  337. }
  338. if (_trigOnOff.T)
  339. {
  340. _timerRFTurnOn.Stop();
  341. }
  342. if (monitorStopwatch.ElapsedMilliseconds > 1000)
  343. {
  344. if (IsPowerOn == true && _chamber != null && _chamber.RFInterlock(_device) == false)
  345. {
  346. SetPowerOnOff(false, out _);
  347. }
  348. monitorStopwatch.Restart();
  349. }
  350. base.Monitor();
  351. }
  352. public override void ResetRFStats()
  353. {
  354. _statRFOnTime = StatsDataManager.Instance.GetItemRFAndPump($"{Module}.{Name}OnTime");
  355. }
  356. public override void Terminate()
  357. {
  358. if (IsPowerOn)
  359. {
  360. SetPowerOnOff(false, out _);
  361. }
  362. _serial?.Close();
  363. }
  364. public override void Reset()
  365. {
  366. _rfOnTrigger.RST = true;
  367. _ErrTrigger.RST = true;
  368. _trigPMNeeded.RST = true;
  369. this.SendCmd(AdTecRfMessage.RESET);
  370. this.Status = GeneratorStatus.OFF;
  371. _bRFPowerOn = false;
  372. base.Reset();
  373. }
  374. public void SetRfMode(RfMode mode)
  375. {
  376. throw new NotImplementedException();
  377. }
  378. public override void SetCommunicationMode(int mode)
  379. {
  380. CommunicationType t1 = (CommunicationType)mode;
  381. switch (t1)
  382. {
  383. case CommunicationType.Analogue:
  384. this.SendCmd(AdTecRfMessage.ANALOG);
  385. break;
  386. case CommunicationType.RS232:
  387. this.SendCmd(AdTecRfMessage.RS232);
  388. break;
  389. default:
  390. throw new ArgumentOutOfRangeException("Communication mode error");
  391. }
  392. }
  393. public override void SetPower(float val)
  394. {
  395. if (!(this.ControlMode == EnumRfPowerControlMode.RS232Mode)) SetCommunicationMode(1);
  396. ushort a = !_scEnableCalibration.BoolValue ? (ushort)val : (ushort)CalibrationData(val, true);
  397. if (SendCmd($"{a:D4}{AdTecRfMessage.SET_POWER}"))
  398. {
  399. PowerSetPoint = val;
  400. }
  401. }
  402. public override bool SetPowerOnOff(bool on, out string str)
  403. {
  404. if (!(this.ControlMode == EnumRfPowerControlMode.RS232Mode)) SetCommunicationMode(1);
  405. str = "";
  406. _chamber = DEVICE.GetDevice<JetPMBase>(Module);
  407. //if (on && !_chamber.CheckGeneratorAndHVInterlock(_device))
  408. //{
  409. // return false;
  410. //}
  411. if (on)
  412. {
  413. SendCmd(AdTecRfMessage.RF_ON);
  414. _bRFPowerOn = true;
  415. _powerOnStartTime = DateTime.Now;
  416. QUERY_INTERVAL = 500;
  417. }
  418. else
  419. {
  420. SendCmd(AdTecRfMessage.RF_OFF);
  421. _bRFPowerOn = false;
  422. //ForwardPower = 0;
  423. //ReflectPower = 0;
  424. QUERY_INTERVAL = 500;
  425. _ErrTrigger.RST = true;
  426. PowerSetPoint = 0;
  427. }
  428. _timerQueryStatus.Start(QUERY_INTERVAL);
  429. return true;
  430. }
  431. //----------------------------------Private Method-------------------------------
  432. //
  433. private void SerialPortDataReceived(string str)
  434. {
  435. if (string.IsNullOrEmpty(str))
  436. {
  437. LOG.Write(eEvent.ERR_RF, Module, "AdTec RFG 无数据反馈");
  438. return;
  439. }
  440. string str2 = str.Trim('\r');
  441. if (str2 == AdTecRfMessage.ERR_RES)
  442. {
  443. LOG.Write(eEvent.WARN_RF, Module, $"AdTEC 收到 [{str2}]");
  444. return;
  445. }
  446. try
  447. {
  448. //LOG.Info($"{Module} Generator rec [{str2}]");
  449. Match match1 = Regex.Match(str2, INFO_PATTERN);
  450. if (!match1.Success)
  451. {
  452. //EV.PostWarningLog(Module, "AdTec 数据格式错误");
  453. if (!SC.GetValue<bool>("System.IsSimulatorMode"))
  454. {
  455. LOG.Write(eEvent.WARN_RF, Module, $"{Module}, AdTec 数据格式错误");
  456. }
  457. return;
  458. }
  459. string[] str1 =
  460. {
  461. match1.Groups[1].Value,
  462. match1.Groups[2].Value,
  463. match1.Groups[3].Value,
  464. match1.Groups[4].Value,
  465. match1.Groups[5].Value
  466. };
  467. this.ParseQueryData(str1);
  468. }
  469. catch (Exception ex)
  470. {
  471. LOG.WriteExeption(ex);
  472. }
  473. }
  474. private void ParseQueryData(string[] strInfo)
  475. {
  476. // Control mode
  477. string s2 = strInfo[0].Substring(0, 1);
  478. this.ControlMode = (EnumRfPowerControlMode)Convert.ToUInt16(s2);
  479. // output mode
  480. string s0 = strInfo[0].Substring(1, 1);
  481. this.WorkMode = (EnumRfPowerWorkMode)Convert.ToUInt16(s0);
  482. // ON/OFF
  483. char s1 = strInfo[0][2];
  484. if (s1 == '1')
  485. {
  486. Status = GeneratorStatus.ON;
  487. }
  488. else if (s1 == '0')
  489. {
  490. Status = GeneratorStatus.OFF;
  491. }
  492. // error code
  493. string alarm = strInfo[0].Substring(5, 2);
  494. byte errCode = Convert.ToByte(alarm);
  495. _ErrTrigger.CLK = errCode > 0;
  496. if (_ErrTrigger.Q)
  497. {
  498. string code = errCode == 1 ? "Ref Over" :
  499. errCode == 2 ? "Ref Limit" :
  500. errCode == 3 ? "Cur Over" :
  501. errCode == 4 ? "Cur Limit" :
  502. errCode == 5 ? "Temp Over" :
  503. errCode == 6 ? "Temp Sensor Short" :
  504. errCode == 7 ? "Temp Sensor Open" :
  505. errCode == 8 ? "Sensor Error" :
  506. errCode == 9 ? "Fwd Power Over" :
  507. errCode == 10 ? "RF ON Timer" :
  508. errCode == 11 ? "RS232C error" :
  509. errCode == 12 ? "Amp Unbalance" :
  510. errCode == 14 ? "Fan error" :
  511. errCode == 15 ? "Coolant Error" :
  512. errCode == 16 ? "Voltage Error" :
  513. errCode == 17 ? "Fwd Power Down" :
  514. errCode == 22 ? "PD Over" :
  515. errCode == 23 ? "PD Limit" :
  516. errCode == 26 ? "Dew Condensation" :
  517. errCode == 29 ? "SW Failure" :
  518. errCode == 99 ? "Safety Lock" : string.Empty;
  519. if (!string.IsNullOrEmpty(code))
  520. {
  521. if (errCode == 99)
  522. LOG.Write(eEvent.EV_DEVICE_INFO, Module, "Source Generator " + code);
  523. else
  524. {
  525. LOG.Write(eEvent.ERR_RF, Module, "Source Generator " + code);
  526. Singleton<RouteManager>.Instance.GetPM(ModuleHelper.Converter(Module)).PostMsg(PMEntity.MSG.Error);
  527. }
  528. }
  529. }
  530. // forward power
  531. this.ForwardPower = Convert.ToUInt64(strInfo[2]);
  532. // reflect power
  533. this.ReflectPower = Convert.ToUInt64(strInfo[3]);
  534. }
  535. private void SerialPortErrorOccurred(string obj)
  536. {
  537. Status = GeneratorStatus.ERROR;
  538. LOG.Write(eEvent.ERR_RF, Module, $"AdTec RFG 串口出错, [{obj}]");
  539. }
  540. private bool SendCmd(string str)
  541. {
  542. if (str != AdTecRfMessage.QUERY)
  543. {
  544. LOG.Write(eEvent.EV_DEVICE_INFO, Module, $"Generator send [{str}]");
  545. }
  546. SetPointCommandQueue.Add(str);
  547. return true;
  548. //return _serial.Write(str + "\r");
  549. }
  550. public override bool ReConnect()
  551. {
  552. return _serial.ReConnect();
  553. }
  554. }
  555. #endregion RFG
  556. #region match
  557. static class AdTecMatchMessage
  558. {
  559. public const string PRESET = "G";
  560. public const string AUTO = "L";
  561. public const string MANUAL = "M";
  562. public const string PRESET_MEM = "P";
  563. public const string START_QUERY = "S3";
  564. public const string STOP_QUERY = "SP";
  565. public const string WRITE_POS = "$APGR";
  566. public const string READ_POS = "$APRR";
  567. public const string Read_MUL = "R46";
  568. public const string Read_DIV = "R47";
  569. }
  570. class AdTecMatch : RfMatchBase
  571. {
  572. private readonly AsyncSerialPort _serial;
  573. private const ushort S3_HEAD_LENGTH = 2;
  574. private readonly DeviceTimer _timerQueryStatus = new DeviceTimer();
  575. private int QUERY_INTERVAL = 500;
  576. private float VDC_MUL = 1;
  577. private float VDC_DIV = 10240;
  578. //private int _scMatchPresetMode;
  579. //private int _scMatchMode;
  580. //private readonly SCConfigItem _scMatchPositionC1;
  581. //private readonly SCConfigItem _scMatchPositionC2;
  582. //private readonly bool _scEnableC1C2Position;
  583. // --------------------------Properties------------------------
  584. //
  585. [Subscription("MatchWorkMode")]
  586. public EnumRfMatchTuneMode WorkMode { get; set; }
  587. public float C1 { get; set; }
  588. public float C2 { get; set; }
  589. //[Subscription("VPP")]
  590. public ushort VPP { get; set; }
  591. public float VDC { get; set; }
  592. public new AITMatchData DeviceData
  593. {
  594. get
  595. {
  596. return new AITMatchData
  597. {
  598. Module = Module,
  599. DeviceName = Name,
  600. WorkMode = WorkMode.ToString(),
  601. C1 = TunePosition1,
  602. C2 = TunePosition2,
  603. VPP = "",
  604. DCBias = DCBias.ToString()
  605. };
  606. }
  607. }
  608. //public override AITRfMatchData DeviceData
  609. //{
  610. // get
  611. // {
  612. // return new AITRfMatchData
  613. // {
  614. // };
  615. // }
  616. //}
  617. // --------------------------Constructor-----------------------
  618. //
  619. public AdTecMatch(ModuleName mod, VenusDevice device) : base(mod.ToString(), device.ToString())
  620. {
  621. var portNum = SC.GetStringValue($"{mod}.{device}.Port");
  622. _serial = new AsyncSerialPort(portNum, 9600, 8);
  623. //_scMatchPresetMode = SC.GetValue<int>($"{Module}.Rf.PresetMode");
  624. //_scMatchMode = SC.GetValue<int>($"{Module}.Rf.MatchMode");
  625. //_scMatchPositionC1 = SC.GetConfigItem($"{Module}.Rf.MatchPositionC1");
  626. //_scMatchPositionC2 = SC.GetConfigItem($"{Module}.Rf.MatchPositionC2");
  627. //_scEnableC1C2Position = SC.GetValue<bool>($"{Module}.Rf.EnableC1C2Position");
  628. SerachCommandList = new List<string>()
  629. {
  630. AdTecMatchMessage.READ_POS,
  631. AdTecMatchMessage.START_QUERY
  632. };
  633. intervalTime = 100;
  634. sendDataChangedEvent += AdTecMatch_sendDataChangedEvent;
  635. baseStopwatch.Start();
  636. baseTimer.Enabled = true;
  637. }
  638. private void AdTecMatch_sendDataChangedEvent(string obj)
  639. {
  640. this.SendCmd(obj);
  641. }
  642. ~AdTecMatch()
  643. {
  644. _serial?.Close();
  645. }
  646. public override bool Initialize()
  647. {
  648. base.Initialize();
  649. if (_serial.Open())
  650. {
  651. _serial.OnDataChanged += SerialPortDataReceived;
  652. _serial.OnErrorHappened += SerialPortErrorOccurred;
  653. }
  654. else
  655. {
  656. LOG.Write(eEvent.ERR_RF, Module, "Match 串口无法打开");
  657. return false;
  658. }
  659. DATA.Subscribe($"{Module}.{Name}.C1", () => TunePosition1);
  660. DATA.Subscribe($"{Module}.{Name}.C2", () => TunePosition2);
  661. DATA.Subscribe($"{Module}.{Name}.VDC", () => VDC);
  662. DATA.Subscribe($"{Module}.{Name}.WorkMode", () => WorkMode.ToString());
  663. OP.Subscribe($"{Module}.{Name}.SetC1", (func, args) =>
  664. {
  665. return true;
  666. });
  667. OP.Subscribe($"{Module}.{Name}.SetC2", (func, args) =>
  668. {
  669. return true;
  670. });
  671. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchPositionC1}", (out string reason, int time, object[] param) =>
  672. {
  673. SetMatchPositionC1((float)Convert.ToDouble(param[0]), out reason);
  674. return true;
  675. });
  676. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchPositionC2}", (out string reason, int time, object[] param) =>
  677. {
  678. SetMatchPositionC2((float)Convert.ToDouble(param[0]), out reason);
  679. return true;
  680. });
  681. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchPosition}", (out string reason, int time, object[] param) =>
  682. {
  683. SetMatchPosition((float)Convert.ToDouble(param[0]), (float)Convert.ToDouble(param[1]), out reason);
  684. return true;
  685. });
  686. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchProcessMode}", (out string reason, int time, object[] param) =>
  687. {
  688. SetMatchMode((string)param[0] == "Auto" ? EnumRfMatchTuneMode.Auto : EnumRfMatchTuneMode.Manual, out reason);
  689. return true;
  690. });
  691. _timerQueryStatus.Start(QUERY_INTERVAL);
  692. this.SendCmd(AdTecMatchMessage.Read_MUL);
  693. this.SendCmd(AdTecMatchMessage.Read_DIV);
  694. this.SendCmd(AdTecMatchMessage.START_QUERY);
  695. //LOG.Write(eEvent.ERR_RF, Module, "Initialize done.");
  696. return true;
  697. }
  698. public override void Monitor()
  699. {
  700. try
  701. {
  702. if (SetPointCommandQueue.Count == 0 && _timerQueryStatus.IsIdle() || _timerQueryStatus.IsTimeout())
  703. {
  704. this.SendCmd(AdTecMatchMessage.Read_MUL);
  705. this.SendCmd(AdTecMatchMessage.Read_DIV);
  706. _timerQueryStatus.Start(QUERY_INTERVAL);
  707. }
  708. }
  709. catch (Exception ex)
  710. {
  711. LOG.WriteExeption(ex);
  712. }
  713. }
  714. public override void Terminate()
  715. {
  716. this.SendCmd(AdTecMatchMessage.STOP_QUERY);
  717. }
  718. public override void Reset()
  719. {
  720. //SendCmd(AdTecMatchMessage.STOP_QUERY);
  721. }
  722. /// <summary>
  723. ///
  724. /// </summary>
  725. /// <param name="c1,c2">百分比数字</param>
  726. /// <param name="c2"></param>
  727. ///
  728. private void executeMatchPostion(float c1, float c2)
  729. {
  730. SetWorkMode(EnumRfMatchTuneMode.Manual);
  731. //await Task.Delay(200);
  732. SetPosition(c1, c2);
  733. //await Task.Delay(200);
  734. SetPresetMemory(0);
  735. //await Task.Delay(200);
  736. // SetWorkMode(EnumRfMatchTuneMode.Auto);
  737. }
  738. public override void SetMatchPosition(float c1, float c2, out string reason)
  739. {
  740. //LOG.Write(eEvent.WARN_RF, Module, $"AdTec Match error [{c1}, {c2}]");
  741. base.SetMatchPosition(c1, c2, out reason);
  742. executeMatchPostion(c1, c2);
  743. reason = "";
  744. }
  745. public void SetPresetMode(RfMatchPresetMode mode)
  746. {
  747. }
  748. // -----------------------Private Method-------------------------
  749. //
  750. private void SerialPortDataReceived(string strOrg)
  751. {
  752. if (string.IsNullOrWhiteSpace(strOrg))
  753. {
  754. LOG.Write(eEvent.ERR_MATCH, Module, "收到 Match 数据为空");
  755. return;
  756. }
  757. string[] sContent = strOrg.Split('\r');
  758. foreach (var sItem in sContent)
  759. {
  760. string sItem1 = sItem.TrimStart('\n');
  761. if (sItem1.Contains(AdTecMatchMessage.START_QUERY))
  762. {
  763. // BYTE 3,4; bit 7
  764. string s0 = sItem1.Substring(2 + S3_HEAD_LENGTH, 2);
  765. ushort status0 = Convert.ToUInt16(s0, 16);
  766. byte[] a1 = BitConverter.GetBytes(status0);
  767. BitArray ba1 = new BitArray(a1);
  768. this.WorkMode = ba1[7] ? EnumRfMatchTuneMode.Manual : EnumRfMatchTuneMode.Auto;
  769. TuneMode1 = WorkMode;
  770. TuneMode2 = WorkMode;
  771. string sVpp = sItem1.Substring(42 + S3_HEAD_LENGTH, 3);
  772. this.VPP = Convert.ToUInt16(sVpp, 16);
  773. string sVDC = sItem1.Substring(39 + S3_HEAD_LENGTH, 3);
  774. //LOG.Write(eEvent.INFO_MATCH, Module, $"{Name} | Raw VDC:{sVDC}");
  775. float VDCMD = VDC_MUL / VDC_DIV;
  776. this.VDC = Convert.ToUInt16(sVDC, 16) > 800 ? (Convert.ToUInt16(sVDC, 16) - 4096) * VDCMD : Convert.ToUInt16(sVDC, 16) * VDCMD;
  777. //LOG.Write(eEvent.INFO_MATCH, Module, $"{Name}|Raw:{sItem1}|vdc_sub:{sVDC}|Vdc:{VDC}");
  778. }
  779. else if (sItem1.Contains(AdTecMatchMessage.READ_POS))
  780. {
  781. string s1 = sItem1.Substring(5);
  782. string sLoad = s1.Substring(0, 3);
  783. string sPhase = s1.Substring(3, 3);
  784. this.TunePosition1 = Convert.ToUInt64(sLoad, 16) * 0.1f;
  785. this.TunePosition2 = Convert.ToUInt64(sPhase, 16) * 0.1f;
  786. }
  787. else if (sItem1.Contains(AdTecMatchMessage.Read_MUL))
  788. {
  789. this.VDC_MUL = Convert.ToUInt16(sItem1.Substring(3), 16) * 0.1f;
  790. //LOG.Write(eEvent.INFO_MATCH, Module, $"Raw:{sItem1}|{sItem1.Substring(3)}:{VDC_MUL}");
  791. }
  792. else if (sItem1.Contains(AdTecMatchMessage.Read_DIV))
  793. {
  794. this.VDC_DIV = Convert.ToUInt16(sItem1.Substring(3), 16) * 0.1f;
  795. //LOG.Write(eEvent.INFO_MATCH, Module, $"Raw:{sItem1}|{sItem1.Substring(3)}:{VDC_DIV}");
  796. }
  797. }
  798. }
  799. private void SerialPortErrorOccurred(string str)
  800. {
  801. LOG.Write(eEvent.ERR_MATCH, Module, $"AdTec Match error [{str}]");
  802. }
  803. private void SendCmd(string str)
  804. {
  805. _serial?.Write(str + "\r");
  806. //EV.PostInfoLog(Module.ToString(), $"Match send [{str}]");
  807. }
  808. private void SetPosition(float c1val, float c2val)
  809. {
  810. ushort val1 = (ushort)(c1val * 10);
  811. ushort val2 = (ushort)(c2val * 10);
  812. string cmd = AdTecMatchMessage.WRITE_POS + val1.ToString("X3") + val2.ToString("X3");
  813. SetPointCommandQueue.Add(cmd);
  814. //this.SendCmd(cmd);
  815. }
  816. public override bool SetMatchMode(EnumRfMatchTuneMode enumRfMatchTuneMode, out string reason)
  817. {
  818. reason = string.Empty;
  819. SetWorkMode(enumRfMatchTuneMode);
  820. return true;
  821. }
  822. private void SetWorkMode(EnumRfMatchTuneMode mode)
  823. {
  824. string data = mode == EnumRfMatchTuneMode.Auto ? AdTecMatchMessage.AUTO :
  825. mode == EnumRfMatchTuneMode.Manual ? AdTecMatchMessage.MANUAL : "";
  826. //this.SendCmd(mode == EnumRfMatchTuneMode.Auto ? AdTecMatchMessage.AUTO :
  827. // mode == EnumRfMatchTuneMode.Manual ? AdTecMatchMessage.MANUAL : "");
  828. SetPointCommandQueue.Add(data);
  829. }
  830. private void SetPresetMemory(byte gear)
  831. {
  832. //this.SendCmd(AdTecMatchMessage.PRESET_MEM + gear.ToString());
  833. SetPointCommandQueue.Add(AdTecMatchMessage.PRESET_MEM + gear.ToString());
  834. }
  835. }
  836. #endregion match
  837. }