TruPlasmaRF.cs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877
  1. using Aitex.Core.Common.DeviceData;
  2. using Aitex.Core.RT.DataCenter;
  3. using Aitex.Core.RT.Device;
  4. using Aitex.Core.RT.Log;
  5. using Aitex.Core.RT.OperationCenter;
  6. using Aitex.Core.RT.SCCore;
  7. using Aitex.Core.RT.Tolerance;
  8. using Aitex.Core.UI.Control;
  9. using Aitex.Core.Util;
  10. using CommunityToolkit.HighPerformance.Buffers;
  11. using MECF.Framework.Common.Communications;
  12. using MECF.Framework.Common.DataCenter;
  13. using MECF.Framework.Common.Device.Bases;
  14. using MECF.Framework.Common.Equipment;
  15. using System;
  16. using System.Collections;
  17. using System.Collections.Generic;
  18. using System.Diagnostics;
  19. using System.Linq;
  20. using System.ServiceModel.Channels;
  21. using Venus_Core;
  22. namespace Venus_RT.Devices
  23. {
  24. public class TruPlasmaRF : RfPowerBase
  25. {
  26. private readonly AsyncSerialPort _serial;
  27. private List<byte> buffer = new List<byte>(4096);
  28. private double _total;
  29. private double _fromLast;
  30. private bool _bRFPowerOn = false;
  31. private readonly DeviceTimer _timerQueryStatus = new DeviceTimer();
  32. private readonly DeviceTimer _timerTotal = new DeviceTimer();
  33. private readonly DeviceTimer _timerFromLast = new DeviceTimer();
  34. private readonly DeviceTimer _timerRFTurnOn = new DeviceTimer();
  35. private readonly RD_TRIG _rfOnTrigger = new RD_TRIG();
  36. private readonly R_TRIG _ErrTrigger = new R_TRIG();
  37. private readonly R_TRIG _trigPMNeeded = new R_TRIG();
  38. private readonly RD_TRIG _trigOnOff = new RD_TRIG();
  39. //private ToleranceChecker _alarmChecker;
  40. //private ToleranceChecker _warningChecker;
  41. //private ToleranceChecker _checkerReflectPower;
  42. private readonly double _scPowerAlarmTime;
  43. private readonly double _scPowerAlarmRange;
  44. private readonly double _scPowerWarningTime;
  45. private readonly double _scPowerWarningRange;
  46. private readonly double _scReflectPowerAlarmTime;
  47. private readonly double _scReflectPowerAlarmRange;
  48. private StatsDataItemRFAndPump _statRFOnTime = new StatsDataItemRFAndPump();
  49. public string LastPMTime
  50. {
  51. get
  52. {
  53. return _statRFOnTime != null ? _statRFOnTime.LastPMTime.ToString() : "";
  54. }
  55. }
  56. public float DaysFromLastPM
  57. {
  58. get
  59. {
  60. return _statRFOnTime == null ? 0 : _statRFOnTime.fromLastPM;
  61. }
  62. set
  63. {
  64. if (_statRFOnTime != null)
  65. _statRFOnTime.fromLastPM = value;
  66. }
  67. }
  68. public float TotalDays
  69. {
  70. get
  71. {
  72. return _statRFOnTime != null ? _statRFOnTime.Total : 0;
  73. }
  74. set
  75. {
  76. if (_statRFOnTime != null)
  77. _statRFOnTime.Total = value;
  78. }
  79. }
  80. public double PMIntervalDays
  81. {
  82. get
  83. {
  84. return _statRFOnTime != null ? _statRFOnTime.PMInterval : 0;
  85. }
  86. }
  87. public bool IsPMNeeded
  88. {
  89. get
  90. {
  91. return DaysFromLastPM > PMIntervalDays;
  92. }
  93. }
  94. public bool EnableAlarm
  95. {
  96. get
  97. {
  98. return _statRFOnTime == null || _statRFOnTime.AlarmEnable;
  99. }
  100. }
  101. private readonly double _scPowerRange;
  102. public override float ScalePower => (float)_scPowerRange;
  103. public TruPlasmaRF(ModuleName mod, VenusDevice device) : base(mod.ToString(), device.ToString())
  104. {
  105. this.Status = GeneratorStatus.Unknown;
  106. var portNum = SC.GetStringValue(device == VenusDevice.Rf ? $"{mod}.Rf.Port" : $"{mod}.BiasRf.Port");
  107. _serial = new AsyncSerialPort(portNum, 9600, 8, System.IO.Ports.Parity.None, System.IO.Ports.StopBits.One, "/r", false);
  108. ResetRFStats();
  109. _scPowerAlarmTime = SC.GetValue<double>($"{Module}.{Name}.PowerAlarmTime");
  110. _scPowerAlarmRange = SC.GetValue<double>($"{Module}.{Name}.PowerAlarmRange");
  111. _scPowerWarningTime = SC.GetValue<double>($"{Module}.{Name}.PowerWarningTime");
  112. _scPowerWarningRange = SC.GetValue<double>($"{Module}.{Name}.PowerWarningRange");
  113. _scReflectPowerAlarmTime = SC.GetValue<double>($"{Module}.{Name}.ReflectPowerAlarmTime");
  114. _scReflectPowerAlarmRange = SC.GetValue<double>($"{Module}.{Name}.ReflectPowerAlarmRange");
  115. _scPowerRange = SC.GetValue<double>($"{Module}.{Name}.PowerRange");
  116. _scEnableCalibration = SC.GetConfigItem($"{Module}.{Name}.EnableCalibration");
  117. _scCalibrationTable = SC.GetConfigItem($"{Module}.{Name}.CalibrationTable");
  118. _scRFPhysicalMaxPower = SC.GetConfigItem($"{Module}.{Name}.RFPhysicalMaxPower");
  119. _scCurrentRFMaxPower = SC.GetConfigItem($"{Module}.{Name}.CurrentRFMaxPower");
  120. }
  121. public override bool Initialize()
  122. {
  123. base.Initialize();
  124. DATA.Subscribe($"{Module}.{Name}.DeviceData", () => DeviceData);
  125. if (_serial.Open())
  126. {
  127. _serial.OnBinaryDataChanged += SerialPortDataReceived;
  128. _serial.OnErrorHappened += SerialPortErrorOccurred;
  129. ResetCommand();
  130. getcontrol();
  131. SetPulseMode(false);
  132. }
  133. else
  134. {
  135. LOG.Write(eEvent.ERR_RF, Module, "Tru 射频发生器串口无法打开");
  136. return false;
  137. }
  138. return true;
  139. }
  140. public new AITRfData DeviceData =>
  141. new AITRfData
  142. {
  143. Module = Module,
  144. DeviceName = Name,
  145. ScalePower = ScalePower,
  146. ForwardPower = ForwardPower,
  147. ReflectPower = ReflectPower,
  148. IsRfOn = IsPowerOn,
  149. PowerSetPoint = PowerSetPoint,
  150. };
  151. private void SerialPortDataReceived(byte[] rawMessage)
  152. {
  153. try
  154. {
  155. buffer.AddRange(rawMessage);
  156. while (buffer.Count >= 18) //至少包含ACK帧头(1字节)、长度、校验位(17或12字节)
  157. {
  158. //2.1 查找数据头
  159. if (buffer[0] == 0x06) //传输数据有帧头,用于判断
  160. {
  161. //得到完整的数据,复制到ReceiveBytes中进行校验
  162. byte[] ReceiveBytes = new byte[13];
  163. byte[] ReadReceiveBytes = new byte[18];
  164. buffer.CopyTo(0, ReceiveBytes, 0, 13);
  165. buffer.CopyTo(0, ReadReceiveBytes, 0, 18);
  166. if ((ReceiveBytes[12] == 0x55) && (ReceiveBytes[1] == 0xAA)) //校验,最后一个字节是校验位
  167. {
  168. parsecmd(ReceiveBytes);
  169. buffer.RemoveRange(0, 13);
  170. }
  171. else if ((ReadReceiveBytes[17] == 0x55) && (ReceiveBytes[1] == 0xAA))
  172. {
  173. parsecmd(ReadReceiveBytes);
  174. buffer.RemoveRange(0, 18);
  175. }
  176. else
  177. {
  178. buffer.Clear();
  179. LOG.Write(eEvent.ERR_RF, Module, $"rf通讯错误");
  180. }
  181. }
  182. else //帧头不正确时,记得清除
  183. {
  184. //buffer.RemoveAt(0);
  185. }
  186. }
  187. }
  188. catch (Exception ex)
  189. {
  190. buffer.Clear();
  191. LOG.WriteExeption(ex);
  192. }
  193. }
  194. public GeneratorStatus Status { get; set; }
  195. private float _forwardPower;
  196. public override float ForwardPower
  197. {
  198. get
  199. {
  200. return _forwardPower;
  201. }
  202. set
  203. {
  204. _forwardPower = CalibrationData(value, false);
  205. }
  206. }
  207. private bool GetBitValue(byte value, int bit)
  208. {
  209. return (value & (byte)Math.Pow(2, bit)) > 0 ? true : false;
  210. }
  211. public override bool ReConnect()
  212. {
  213. return _serial.ReConnect();
  214. }
  215. public override bool IsPowerOn
  216. {
  217. get => Status == GeneratorStatus.ON;
  218. set { }
  219. }
  220. public void parsecmd(byte[] message)
  221. {
  222. try
  223. {
  224. IsPowerOn = GetBitValue(message[4], 4);
  225. if (GetBitValue(message[4], 4))
  226. {
  227. //LOG.Write(eEvent.INFO_RF,Module,"RF Status:ON");
  228. Status = GeneratorStatus.ON;
  229. }
  230. else
  231. {
  232. //LOG.Write(eEvent.INFO_RF, Module, "RF Status:OFF");
  233. Status = GeneratorStatus.OFF;
  234. }
  235. switch (message[5])
  236. {
  237. case 0x01://ParamRead
  238. if (message.Length == 18 && message[6] == 0x14)
  239. {
  240. int DataValue = BitConverter.ToInt32(new byte[] { message[11], message[12], message[13], message[14] }, 0);
  241. ReflectPower = DataValue;
  242. }
  243. else if (message.Length == 18 && message[6] == 0x12)
  244. {
  245. int DataValue1 = BitConverter.ToInt32(new byte[] { message[11], message[12], message[13], message[14] }, 0);
  246. ForwardPower = DataValue1;
  247. }
  248. break;
  249. case 0x02://ParamWrite
  250. break;
  251. case 0xFE://TelegramError
  252. LOG.Write(eEvent.ERR_RF, Module, "Telegram structure is not correct");
  253. break;
  254. default:
  255. // 默认代码块
  256. break;
  257. }
  258. switch (message[9])
  259. {
  260. case 0x26:
  261. //LOG.Write(eEvent.INFO_RF, Module, "RF Status:OFF");
  262. Status = GeneratorStatus.OFF;
  263. IsPowerOn = false;
  264. break;
  265. case 0x24:
  266. LOG.Write(eEvent.ERR_RF, Module, "Telegram structure is not correct");
  267. break;
  268. default:
  269. // 默认代码块
  270. break;
  271. }
  272. }
  273. catch (Exception ex)
  274. {
  275. LOG.WriteExeption(ex);
  276. }
  277. }
  278. private void SerialPortErrorOccurred(string obj)
  279. {
  280. LOG.Write(eEvent.ERR_RF, Module, $"Tru 射频串口出错, [{obj}]");
  281. }
  282. public override void SetPower(float val)
  283. {
  284. List<byte> baseBytes = new List<byte>() { 0xAA, 0x02, 0x0B, 0x00, 0x02, 0x06, 0x00, 0x01, 0x00, 0x04 };
  285. val = !_scEnableCalibration.BoolValue ? (ushort)val : (ushort)CalibrationData(val, true);
  286. byte[] valueBytes = BitConverter.GetBytes((int)val);
  287. baseBytes.AddRange(valueBytes);
  288. baseBytes = CRC16(baseBytes.ToArray());
  289. baseBytes.Add(0x55);
  290. _serial.Write(baseBytes.ToArray());
  291. PowerSetPoint = val;
  292. }
  293. public override void Monitor()
  294. {
  295. readpi();
  296. readpr();
  297. _rfOnTrigger.CLK = IsPowerOn;
  298. if (_rfOnTrigger.R)
  299. {
  300. _total = TotalDays;
  301. _fromLast = DaysFromLastPM;
  302. _timerTotal.Start(0);
  303. _timerFromLast.Start(0);
  304. _timerTotal.Restart(0);
  305. _timerFromLast.Restart(0);
  306. _alarmChecker.Reset(_scPowerAlarmTime);
  307. _warningChecker.Reset(_scPowerWarningTime);
  308. //_checkerReflectPower.Reset(_scReflectPowerAlarmTime);
  309. }
  310. if (_rfOnTrigger.M)
  311. {
  312. TotalDays =Convert.ToSingle( _timerTotal.GetElapseTime() / 1000 / 60 / 60);
  313. DaysFromLastPM =Convert.ToSingle( _timerFromLast.GetElapseTime() / 1000 / 60 / 60);
  314. }
  315. if (PMIntervalDays > 0)
  316. {
  317. _trigPMNeeded.CLK = IsPMNeeded;
  318. if (_trigPMNeeded.Q)
  319. {
  320. if (EnableAlarm)
  321. {
  322. LOG.Write(eEvent.ERR_RF, $"{Module}", "rf on time value larger than setting interval days");
  323. }
  324. }
  325. }
  326. if (_rfOnTrigger.T)
  327. {
  328. _timerTotal.Stop();
  329. _timerFromLast.Stop();
  330. StatsDataManager.Instance.Increase($"{Module}.{Name}OnTime", $"{Module}{Name}RfOnTime", DaysFromLastPM, TotalDays);
  331. }
  332. if (!_rfOnTrigger.CLK)
  333. {
  334. //ForwardPower = 0;
  335. //ReflectPower = 0;
  336. }
  337. // RF Turn On & Off Timeout Check
  338. _trigOnOff.CLK = _bRFPowerOn;
  339. if (_trigOnOff.R) //RF Turn On
  340. {
  341. _timerRFTurnOn.Start(SC.GetValue<int>($"{Module}.{Name}.RFTurnOnTimeout") * 1000);
  342. }
  343. if (_trigOnOff.M) //RF Stay On
  344. {
  345. if (_timerRFTurnOn.IsTimeout())
  346. {
  347. if (!IsPowerOn)
  348. {
  349. LOG.Write(eEvent.ERR_RF, $"{Module}", $"{Name} Turn On Failed");
  350. _timerRFTurnOn.Stop();
  351. }
  352. }
  353. }
  354. if (_trigOnOff.T)
  355. {
  356. _timerRFTurnOn.Stop();
  357. }
  358. base.Monitor();
  359. }
  360. public override void ResetRFStats()
  361. {
  362. _statRFOnTime = StatsDataManager.Instance.GetItemRFAndPump($"{Module}.{Name}OnTime");
  363. }
  364. public void getcontrol()
  365. {
  366. byte[] getincontrol = new byte[] { 0xAA, 0x02, 0x06, 0x00, 0x05, 0x01, 0x00, 0x00, 0xFF, 0x34, 0x8A, 0x55 };
  367. _serial.Write(getincontrol.ToArray());
  368. }
  369. public void releasecontrol()
  370. {
  371. byte[] getincontrol = new byte[] { 0xAA, 0x02, 0x06, 0x00, 0x05, 0x02, 0x00, 0x00, 0xFF, 0xE8, 0x11, 0x55 };
  372. _serial.Write(getincontrol.ToArray());
  373. }
  374. public void readpr()//reflect
  375. {
  376. byte[] getincontrol = new byte[] { 0xAA, 0x02, 0x06, 0x00, 0x01, 0x14, 0x00, 0x01, 0xFF, 0xE1, 0x97, 0x55 };
  377. _serial.Write(getincontrol.ToArray());
  378. }
  379. public void readpi()//forward
  380. {
  381. byte[] getincontrola = new byte[] { 0xAA, 0x02, 0x06, 0x00, 0x01, 0x12, 0x00, 0x01, 0xFF, 0x78, 0xB0, 0x55 };
  382. _serial.Write(getincontrola.ToArray());
  383. }
  384. public void ResetCommand()
  385. {
  386. LOG.Write(eEvent.ERR_RF, Module, $"Send rest");
  387. byte[] getincontrol = new byte[] { 0xAA, 0x02, 0x0B, 0x00, 0x02, 0x4D, 0x00, 0x01, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x30, 0x72, 0x55 };
  388. _serial.Write(getincontrol.ToArray());
  389. }
  390. public override void Reset()
  391. {
  392. byte[] getincontrol = new byte[] { 0xAA, 0x02, 0x0B, 0x00, 0x02, 0x4D, 0x00, 0x01, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x30, 0x72, 0x55 };
  393. _serial.Write(getincontrol.ToArray());
  394. }
  395. public override bool SetPowerOnOff(bool on, out string str)
  396. {
  397. str = "";
  398. var _chamber = DEVICE.GetDevice<JetPMBase>(Module);
  399. if (on && !_chamber.CheckGeneratorAndHVInterlock(VenusDevice.Rf))
  400. {
  401. return false;
  402. }
  403. getcontrol();
  404. List<byte> baseBytes = new List<byte>() { 0xAA, 0x02, 0x0B, 0x00, 0x02, 0x6F, 0x00, 0x01, 0x00, 0x07 };
  405. if (on == true)
  406. {
  407. _bRFPowerOn = true;
  408. baseBytes.AddRange(new List<byte> { 0x01, 0x00, 0x00, 0x00 });
  409. }
  410. else
  411. {
  412. _bRFPowerOn = false;
  413. baseBytes.AddRange(new List<byte> { 0x00, 0x00, 0x00, 0x00 });
  414. }
  415. baseBytes = CRC16(baseBytes.ToArray());
  416. baseBytes.Add(0x55);
  417. _serial.Write(baseBytes.ToArray());
  418. if (on == false)
  419. {
  420. releasecontrol();
  421. }
  422. return true;
  423. }
  424. public override void SetPulseMode(bool on)
  425. {
  426. List<byte> baseBytes = new List<byte>() { 0xAA, 0x02, 0x0B, 0x00, 0x02, 0x6A, 0x01, 0x01, 0x00, 0x04 };
  427. if (on == true)
  428. {
  429. baseBytes.AddRange(new List<byte> { 0x01, 0x00, 0x00, 0x00 });
  430. }
  431. else
  432. {
  433. baseBytes.AddRange(new List<byte> { 0x00, 0x00, 0x00, 0x00 });
  434. }
  435. baseBytes = CRC16(baseBytes.ToArray());
  436. baseBytes.Add(0x55);
  437. _serial.Write(baseBytes.ToArray());
  438. }
  439. public override void SetPulseRateFreq(int nFreq)
  440. {
  441. if (nFreq > 0)
  442. {
  443. List<byte> baseBytes = new List<byte>() { 0xAA, 0x02, 0x0B, 0x00, 0x02, 0x6C, 0x01, 0x01, 0x00, 0x04 };
  444. byte[] valueBytes = BitConverter.GetBytes(nFreq);
  445. baseBytes.AddRange(valueBytes);
  446. baseBytes = CRC16(baseBytes.ToArray());
  447. baseBytes.Add(0x55);
  448. _serial.Write(baseBytes.ToArray());
  449. }
  450. else
  451. {
  452. LOG.Write(eEvent.ERR_RF, Module, $"{Name},SetPulseRateFreq() parameter error: {nFreq}");
  453. }
  454. }
  455. public override void SetPulseDutyCycle(int percentage)
  456. {
  457. if (percentage >= 10 && percentage <= 90)
  458. {
  459. List<byte> baseBytes = new List<byte>() { 0xAA, 0x02, 0x0B, 0x00, 0x02, 0x6D, 0x01, 0x01, 0x00, 0x04 };
  460. byte[] valueBytes = BitConverter.GetBytes(percentage);
  461. baseBytes.AddRange(valueBytes);
  462. baseBytes = CRC16(baseBytes.ToArray());
  463. baseBytes.Add(0x55);
  464. _serial.Write(baseBytes.ToArray());
  465. }
  466. else
  467. {
  468. LOG.Write(eEvent.ERR_RF, Module, $"{Name},SetPulseDutyCycle() parameter error: {percentage}");
  469. }
  470. }
  471. #region 霍廷格RF协议crc-16/CCITT-FALSE校验
  472. private bool CRC16(byte[] buffer, ref byte[] ResCRC16) // crc-16/CCITT-FALSE,判断校验
  473. {
  474. bool status = false;
  475. ushort crc = 0xFFFF;
  476. int size = buffer.Length; //计算待计算的数据长度
  477. int i = 0;
  478. if (size > 0)
  479. {
  480. while (size-- > 0)
  481. {
  482. crc = (ushort)((crc >> 8) | (crc << 8));
  483. crc ^= buffer[i++];
  484. crc ^= (ushort)(((byte)crc) >> 4);
  485. crc ^= (ushort)(crc << 12);
  486. crc ^= (ushort)((crc & 0xff) << 5);
  487. }
  488. }
  489. //判断输入的ResCRC16与计算出来的是否一致
  490. if (ResCRC16[0] == (byte)((crc >> 8) & 0xff) && ResCRC16[1] == (byte)(crc & 0xff))
  491. {
  492. status = true;
  493. }
  494. return status;
  495. }
  496. private List<byte> CRC16(byte[] buffer) // crc-16/CCITT-FALSE,补全两个字节
  497. {
  498. ushort crc = 0xFFFF;
  499. int size = buffer.Length; //计算待计算的数据长度
  500. int i = 0;
  501. if (size > 0)
  502. {
  503. while (size-- > 0)
  504. {
  505. crc = (ushort)((crc >> 8) | (crc << 8));
  506. crc ^= buffer[i++];
  507. crc ^= (ushort)(((byte)crc) >> 4);
  508. crc ^= (ushort)(crc << 12);
  509. crc ^= (ushort)((crc & 0xff) << 5);
  510. }
  511. }
  512. var byteList = buffer.ToList();
  513. byteList.Add((byte)(crc & 0xff));
  514. byteList.Add((byte)((crc >> 8) & 0xff));
  515. return byteList;
  516. }
  517. #endregion
  518. }
  519. class TruPlasmaMatch : RfMatchBase
  520. {
  521. private readonly AsyncSerialPort _serial;
  522. private const ushort S3_HEAD_LENGTH = 2;
  523. private readonly DeviceTimer _timerQueryStatus = new DeviceTimer();
  524. //private int QUERY_INTERVAL = 1000;
  525. private List<byte> buffer = new List<byte>(4096);
  526. [Subscription("MatchWorkMode")]
  527. public EnumRfMatchTuneMode WorkMode { get; set; }
  528. public float C1 { get; set; }
  529. public float C2 { get; set; }
  530. public float _C1setpoint { get; set; }
  531. public float _C2setpoint { get; set; }
  532. //[Subscription("VPP")]
  533. public ushort VPP { get; set; }
  534. public float VDC { get; set; }
  535. public new AITMatchData DeviceData
  536. {
  537. get
  538. {
  539. return new AITMatchData
  540. {
  541. Module = Module,
  542. DeviceName = Name,
  543. WorkMode = WorkMode.ToString(),
  544. C1 = TunePosition1,
  545. C2 = TunePosition2,
  546. VPP = "",
  547. DCBias = DCBias.ToString(),
  548. C1SetPoint= _C1setpoint,
  549. C2SetPoint = _C2setpoint,
  550. };
  551. }
  552. }
  553. public TruPlasmaMatch(ModuleName mod, VenusDevice device) : base(mod.ToString(), device.ToString())
  554. {
  555. var portNum = SC.GetStringValue($"{mod}.{device}.Port");
  556. _serial = new AsyncSerialPort(portNum, 9600, 8, System.IO.Ports.Parity.None, System.IO.Ports.StopBits.One, "/r", false);
  557. intervalTime = 100;
  558. }
  559. ~TruPlasmaMatch()
  560. {
  561. _serial?.Close();
  562. }
  563. public override bool Initialize()
  564. {
  565. base.Initialize();
  566. preset(50,50);
  567. DATA.Subscribe($"{Module}.{Name}.DeviceData", () => DeviceData);
  568. if (_serial.Open())
  569. {
  570. _serial.OnBinaryDataChanged += SerialBinaryPortDataReceived;
  571. _serial.OnErrorHappened += SerialPortErrorOccurred;
  572. }
  573. else
  574. {
  575. LOG.Write(eEvent.ERR_RF, Module, "Match 串口无法打开");
  576. return false;
  577. }
  578. DATA.Subscribe($"{Module}.{Name}.C1", () => TunePosition1);
  579. DATA.Subscribe($"{Module}.{Name}.C2", () => TunePosition2);
  580. DATA.Subscribe($"{Module}.{Name}.VDC", () => VDC);
  581. DATA.Subscribe($"{Module}.{Name}.WorkMode", () => WorkMode.ToString());
  582. OP.Subscribe($"{Module}.{Name}.SetC1", (func, args) =>
  583. {
  584. return true;
  585. });
  586. OP.Subscribe($"{Module}.{Name}.SetC2", (func, args) =>
  587. {
  588. return true;
  589. });
  590. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchPositionC1}", (out string reason, int time, object[] param) =>
  591. {
  592. SetMatchPositionC1((float)Convert.ToDouble(param[0]), out reason);
  593. return true;
  594. });
  595. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchPositionC2}", (out string reason, int time, object[] param) =>
  596. {
  597. SetMatchPositionC2((float)Convert.ToDouble(param[0]), out reason);
  598. return true;
  599. });
  600. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchPosition}", (out string reason, int time, object[] param) =>
  601. {
  602. SetMatchPosition((float)Convert.ToDouble(param[0]), (float)Convert.ToDouble(param[1]), out reason);
  603. return true;
  604. });
  605. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchProcessMode}", (out string reason, int time, object[] param) =>
  606. {
  607. SetMatchMode((string)param[0] == "Auto" ? EnumRfMatchTuneMode.Auto : EnumRfMatchTuneMode.Manual, out reason);
  608. return true;
  609. });
  610. return true;
  611. }
  612. public void readc1()
  613. {
  614. byte[] readc1 = new byte[] { 0x0C, 0xF3, 0x00, 0x02, 0x00, 0x01, 0x61, 0x42, 0x79, 0x18, 0x01, 0x37 };
  615. _serial.Write(readc1.ToArray());
  616. }
  617. public void readc2()
  618. {
  619. byte[] readc1 = new byte[] { 0x0C, 0xF3, 0x00, 0x02, 0x00, 0x01, 0x61, 0x42, 0x79, 0x19, 0x01, 0x38 };
  620. _serial.Write(readc1.ToArray());
  621. }
  622. public void readVDC()
  623. {
  624. byte[] readvdc = new byte[] { 0x0C, 0xF3, 0x00, 0x02, 0x00, 0x00, 0x61, 0x42, 0x79, 0x1E, 0x01, 0x3C };
  625. _serial.Write(readvdc.ToArray());
  626. }
  627. public override void Monitor()
  628. {
  629. //ReadPosition(50,50);//0x10 (present mode)CMD 可实现任意模式下只读不设值,0x08(auto then manual)在auto模式下可实现相同功能
  630. readc1();
  631. readc2();
  632. readVDC();
  633. readVDC();
  634. }
  635. public override void Terminate()
  636. {
  637. }
  638. public override void Reset()
  639. {
  640. preset(50, 50);
  641. }
  642. /// <summary>
  643. ///
  644. /// </summary>
  645. /// <param name="c1,c2">百分比数字</param>
  646. /// <param name="c2"></param>
  647. ///
  648. private void executeMatchPostion(float c1, float c2)
  649. {
  650. SetPositionManualAuto(c1, c2);
  651. }
  652. public override void SetMatchPosition(float c1, float c2, out string reason)
  653. {
  654. //preset(c1, c2);
  655. executeMatchPostion(c1, c2);
  656. reason = "";
  657. }
  658. public void SetPresetMode(RfMatchPresetMode mode)
  659. {
  660. }
  661. // -----------------------Private Method-------------------------
  662. //
  663. private void SerialBinaryPortDataReceived(byte[] message)
  664. {
  665. if (message.Count() < 18)
  666. {
  667. string hexString = BitConverter.ToString(message.ToArray()).Replace("-", " ");
  668. //LOG.Write(eEvent.ERR_MATCH, Module, hexString);
  669. //LOG.Write(eEvent.ERR_RF, Module, "收到 Match 数据格式不正确");
  670. }
  671. else
  672. {
  673. try
  674. {
  675. buffer.AddRange(message);
  676. while (buffer.Count >= 18) //至少包含帧头(1字节)、长度(1字节)、其余27字节
  677. {
  678. //2.1 查找数据头
  679. if (buffer[0] == 0x1D && buffer[1] == 0xE2) //传输数据有帧头,用于判断
  680. {
  681. //得到完整的数据,复制到ReceiveBytes中进行校验
  682. byte[] ReceiveBytes = new byte[29];
  683. buffer.CopyTo(0, ReceiveBytes, 0, 29);
  684. TunePosition1 = BitConverter.ToSingle(new byte[] { ReceiveBytes[10], ReceiveBytes[11], ReceiveBytes[12], ReceiveBytes[13] }, 0) * 100;
  685. TunePosition2 = BitConverter.ToSingle(new byte[] { ReceiveBytes[14], ReceiveBytes[15], ReceiveBytes[16], ReceiveBytes[17] }, 0) * 100;
  686. buffer.RemoveRange(0, 29);
  687. switch (ReceiveBytes[19])
  688. {
  689. case 0x01:
  690. this.WorkMode = EnumRfMatchTuneMode.Manual;
  691. break;
  692. case 0x02:
  693. this.WorkMode = EnumRfMatchTuneMode.Auto;
  694. break;
  695. case 0x20:
  696. this.WorkMode = EnumRfMatchTuneMode.Undefined;
  697. break;
  698. default:
  699. break;
  700. }
  701. }
  702. else if (buffer[0] == 0x12 && buffer[1] == 0xED)
  703. {
  704. byte[] ReceiveBytes18 = new byte[18];
  705. buffer.CopyTo(0, ReceiveBytes18, 0, 18);
  706. if (ReceiveBytes18[10] == 0x79 && ReceiveBytes18[11] == 0x18)
  707. {
  708. TunePosition1 = BitConverter.ToSingle(new byte[] { ReceiveBytes18[12], ReceiveBytes18[13], ReceiveBytes18[14], ReceiveBytes18[15] }, 0) * 100;
  709. } else if (ReceiveBytes18[10] == 0x79 && ReceiveBytes18[11] == 0x19)
  710. {
  711. TunePosition2 = BitConverter.ToSingle(new byte[] { ReceiveBytes18[12], ReceiveBytes18[13], ReceiveBytes18[14], ReceiveBytes18[15] }, 0) * 100;
  712. }
  713. else if (ReceiveBytes18[10] == 0x79 && ReceiveBytes18[11] == 0x1E)
  714. {
  715. VDC = BitConverter.ToSingle(new byte[] { ReceiveBytes18[12], ReceiveBytes18[13], ReceiveBytes18[14], ReceiveBytes18[15] }, 0);
  716. }
  717. buffer.RemoveRange(0, 18);
  718. }
  719. else //帧头不正确时,记得清除
  720. {
  721. buffer.Clear();
  722. //LOG.Write(eEvent.ERR_MATCH, Module, $"Match通讯错误");
  723. }
  724. }
  725. }
  726. catch (Exception ex)
  727. {
  728. buffer.Clear();
  729. LOG.WriteExeption(ex);
  730. }
  731. }
  732. }
  733. private void SerialPortErrorOccurred(string str)
  734. {
  735. LOG.Write(eEvent.ERR_RF, Module, $"TruPlasma Match error [{str}]");
  736. }
  737. private void SetPositionManualAuto(float c1val, float c2val)
  738. {
  739. _C1setpoint = c1val;
  740. _C2setpoint = c2val;
  741. List<byte> Len = new List<byte>() { 0x16, 0xE9 };
  742. List<byte> DstSrc = new List<byte>() { 0x00, 0x02, 0x00, 0x01 };
  743. List<byte> Cmd = new List<byte> { 0x60, 0x40 };
  744. byte[] val1Bytes = BitConverter.GetBytes(c1val / 100);
  745. byte[] val2Bytes = BitConverter.GetBytes(c2val / 100);
  746. List<byte> Act = new List<byte>() { 0x00 };
  747. List<byte> Ctr123 = new List<byte> { 0x08, 0x00, 0x00 };
  748. List<byte> baseBytes = new List<byte>() { };
  749. baseBytes.AddRange(Len);
  750. baseBytes.AddRange(DstSrc);
  751. baseBytes.AddRange(Cmd);
  752. baseBytes.AddRange(val1Bytes);
  753. baseBytes.AddRange(val2Bytes);
  754. baseBytes.AddRange(Act);
  755. baseBytes.AddRange(Ctr123);
  756. int a = 0;
  757. for (int i = 2; i < baseBytes.Count; i++)
  758. {
  759. a += (Int16)baseBytes[i];
  760. }
  761. byte[] ackture = new byte[2];
  762. byte[] ackbyte = BitConverter.GetBytes(a);
  763. ackture[0] = ackbyte[1];
  764. ackture[1] = ackbyte[0];
  765. baseBytes.AddRange(ackture);
  766. _serial.Write(baseBytes.ToArray());
  767. }
  768. private void preset(float c1val, float c2val)
  769. {
  770. _C1setpoint = c1val;
  771. _C2setpoint = c2val;
  772. List<byte> Len = new List<byte>() { 0x16, 0xE9 };
  773. List<byte> DstSrc = new List<byte>() { 0x00, 0x02, 0x00, 0x01 };
  774. List<byte> Cmd = new List<byte> { 0x60, 0x40 };
  775. byte[] val1Bytes = BitConverter.GetBytes(c1val / 100);
  776. byte[] val2Bytes = BitConverter.GetBytes(c2val / 100);
  777. List<byte> Act = new List<byte>() { 0x00 };
  778. List<byte> Ctr123 = new List<byte> { 0x04, 0x10, 0x80 };
  779. List<byte> baseBytes = new List<byte>() { };
  780. baseBytes.AddRange(Len);
  781. baseBytes.AddRange(DstSrc);
  782. baseBytes.AddRange(Cmd);
  783. baseBytes.AddRange(val1Bytes);
  784. baseBytes.AddRange(val2Bytes);
  785. baseBytes.AddRange(Act);
  786. baseBytes.AddRange(Ctr123);
  787. int a = 0;
  788. for (int i = 2; i < baseBytes.Count; i++)
  789. {
  790. a += (Int16)baseBytes[i];
  791. }
  792. byte[] ackture = new byte[2];
  793. byte[] ackbyte = BitConverter.GetBytes(a);
  794. ackture[0] = ackbyte[1];
  795. ackture[1] = ackbyte[0];
  796. baseBytes.AddRange(ackture);
  797. _serial.Write(baseBytes.ToArray());
  798. }
  799. public override bool SetMatchMode(EnumRfMatchTuneMode enumRfMatchTuneMode, out string reason)
  800. {
  801. reason = string.Empty;
  802. return true;
  803. }
  804. public override bool ReConnect()
  805. {
  806. return _serial.ReConnect();
  807. }
  808. private void SetWorkMode(EnumRfMatchTuneMode mode)
  809. {
  810. }
  811. private void SetPresetMemory(byte gear)
  812. {
  813. }
  814. }
  815. }