25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

118 lines
4.3 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.IO;
  7. using System.IO.Ports;
  8. using System.Threading;
  9. using System.Collections.Concurrent;
  10. using HBLConsole.Service;
  11. namespace HBLConsole.Communication
  12. {
  13. public class MCUSerialHelper
  14. {
  15. private volatile static MCUSerialHelper _Instance;
  16. public static MCUSerialHelper GetInstance => _Instance ?? (_Instance = new MCUSerialHelper());
  17. private MCUSerialHelper() { }
  18. private SerialPort comPort = new SerialPort();
  19. public bool IsOpen => comPort.IsOpen;
  20. public bool Open(string portName, int baudRate)
  21. {
  22. while (!SerialPort.GetPortNames().Contains(portName))
  23. {
  24. Thread.Sleep(1000);
  25. }
  26. while (!comPort.IsOpen)
  27. {
  28. comPort.PortName = portName;
  29. comPort.BaudRate = baudRate;
  30. comPort.DataBits = 8;
  31. comPort.Parity = Parity.None;
  32. comPort.StopBits = StopBits.One;
  33. comPort.ReadTimeout = 1000;
  34. comPort.WriteTimeout = 1000;
  35. //comPort.RtsEnable = true; //设置为 true后会读取不到数据
  36. //comPort.DtrEnable = true;//获取或设置一个值,该值在串行通信过程中启用数据终端就绪 (DTR) 信号。
  37. //comPort.RtsEnable = true;//获取或设置一个值,该值指示在串行通信中是否启用请求发送 (RTS) 信号
  38. try
  39. {
  40. comPort.Open();
  41. }
  42. catch (Exception ex)
  43. {
  44. MessageLog.GetInstance.ShowEx(ex.ToString());
  45. Thread.Sleep(5000);
  46. }
  47. }
  48. MessageLog.GetInstance.Show($"{portName} 串口打开成功");
  49. return comPort.IsOpen;
  50. }
  51. /// <summary>
  52. /// 单片机输出端口控制
  53. /// </summary>
  54. /// <param name="index">通道号 1 - 8 </param>
  55. /// <param name="value">控制值</param>
  56. public void OutputControl(byte index, bool value)
  57. {
  58. byte NumValue = (byte)(value ? 0x01 : 0x00);
  59. byte[] buffers = new byte[6] { 0xCC, 0x01, 0x01, index, NumValue, 0xDD };
  60. if (IsOpen) comPort.Write(buffers, 0, buffers.Length);
  61. }
  62. /// <summary>
  63. /// 舵机控制
  64. /// </summary>
  65. /// <param name="index">通道号 1 - 8</param>
  66. /// <param name="value">舵机位置 0 - 180</param>
  67. public void ServoControl(byte index, byte value)
  68. {
  69. byte[] buffers = new byte[6] { 0xCC, 0x01, 0x02, index, value, 0xDD };
  70. if (IsOpen) comPort.Write(buffers, 0, buffers.Length);
  71. }
  72. /// <summary>
  73. /// 获取单片机输入端口状态
  74. /// </summary>
  75. /// <param name="index"></param>
  76. /// <returns></returns>
  77. public bool GetInputStatus(byte index)
  78. {
  79. if (index <= 0 || index > 8) return false;
  80. byte[] buffers = new byte[6] { 0xCC, 0x01, 0x03, index, 0x00, 0xDD };
  81. if (IsOpen)
  82. {
  83. comPort.Write(buffers, 0, buffers.Length);
  84. DateTime dt = DateTime.Now;
  85. List<byte> receive = new List<byte>();
  86. while (true)
  87. {
  88. byte[] re = new byte[comPort.BytesToRead];
  89. comPort.Read(re, 0, re.Length);
  90. if (re.Contains<byte>(0xcc) && re.Contains<byte>(0xDD)) receive.AddRange(re);
  91. comPort.DiscardInBuffer();
  92. if (receive.Contains(0xcc) && receive.Contains(0xdd)) break;
  93. if (DateTime.Now.Subtract(dt).TotalSeconds >= 2) break;
  94. Thread.Sleep(1);
  95. }
  96. if (receive != null)
  97. {
  98. int Reindex = Array.FindIndex(receive.ToArray(), p => p == 0xcc);
  99. if (Reindex < receive.Count && Reindex >= 0)
  100. {
  101. var res = receive.GetRange(Array.FindIndex(receive.ToArray(), p => p == 0xcc), 6);
  102. return res != null && res.Count() == 6 && res.ElementAt(4) == 0x01;
  103. }
  104. }
  105. }
  106. return false;
  107. }
  108. }
  109. }