using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.IO.Ports;
using System.Threading;
using System.Collections.Concurrent;
using HBLConsole.Service;
namespace HBLConsole.Communication
{
public class MCUSerialHelper
{
private volatile static MCUSerialHelper _Instance;
public static MCUSerialHelper GetInstance => _Instance ?? (_Instance = new MCUSerialHelper());
private MCUSerialHelper() { }
private SerialPort comPort = new SerialPort();
public bool IsOpen => comPort.IsOpen;
public bool Open(string portName, int baudRate)
{
while (!SerialPort.GetPortNames().Contains(portName))
{
Thread.Sleep(1000);
}
while (!comPort.IsOpen)
{
comPort.PortName = portName;
comPort.BaudRate = baudRate;
comPort.DataBits = 8;
comPort.Parity = Parity.None;
comPort.StopBits = StopBits.One;
comPort.ReadTimeout = 1000;
comPort.WriteTimeout = 1000;
//comPort.RtsEnable = true; //设置为 true后会读取不到数据
//comPort.DtrEnable = true;//获取或设置一个值,该值在串行通信过程中启用数据终端就绪 (DTR) 信号。
//comPort.RtsEnable = true;//获取或设置一个值,该值指示在串行通信中是否启用请求发送 (RTS) 信号
try
{
comPort.Open();
}
catch (Exception ex)
{
MessageLog.GetInstance.ShowEx(ex.ToString());
Thread.Sleep(5000);
}
}
MessageLog.GetInstance.Show($"{portName} 串口打开成功");
return comPort.IsOpen;
}
private static readonly object OutPutLock=new object();
///
/// 单片机输出端口控制
///
/// 通道号 1 - 8
/// 控制值
public void OutputControl(byte index, bool value)
{
lock (OutPutLock)
{
byte NumValue = (byte)(value ? 0x01 : 0x00);
byte[] buffers = new byte[6] { 0xCC, 0x01, 0x01, index, NumValue, 0xDD };
if (IsOpen) comPort.Write(buffers, 0, buffers.Length);
}
}
///
/// 舵机控制
///
/// 通道号 1 - 8
/// 舵机位置 0 - 180
public void ServoControl(byte index, byte value)
{
byte[] buffers = new byte[6] { 0xCC, 0x01, 0x02, index, value, 0xDD };
if (IsOpen) comPort.Write(buffers, 0, buffers.Length);
}
///
/// 获取单片机输入端口状态
///
///
/// 0:无意义 1:有信号 2:无信号 3:信号不正确
public int GetInputStatus(byte index)
{
if (index <= 0 || index > 8) return 0;
byte[] buffers = new byte[6] { 0xCC, 0x01, 0x03, index, 0x00, 0xDD };
if (IsOpen)
{
comPort.Write(buffers, 0, buffers.Length);
DateTime dt = DateTime.Now;
List receive = new List();
while (true)
{
byte[] re = new byte[comPort.BytesToRead];
comPort.Read(re, 0, re.Length);
if (re.Contains(0xcc) && re.Contains(0xDD)) receive.AddRange(re);
comPort.DiscardInBuffer();
if (receive.Contains(0xcc) && receive.Contains(0xdd)) break;
if (DateTime.Now.Subtract(dt).TotalSeconds >= 2) break;
Thread.Sleep(1);
}
if (receive != null)
{
int Reindex = Array.FindIndex(receive.ToArray(), p => p == 0xcc);
if (Reindex < receive.Count && Reindex >= 0)
{
var res = receive.GetRange(Array.FindIndex(receive.ToArray(), p => p == 0xcc), 6);
if (res.ElementAt(2) == 0x03)
{
if (res != null && res.Count() == 6 && res.ElementAt(4) == 0x01)
{
return 1;
}
else if (res != null && res.Count() == 6 && res.ElementAt(4) == 0x00)
{
return 2;
}
}
else
{
return 3;
}
}
else
{
return 0;
}
}
}
return 0;
}
}
}