You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

205 lines
6.1 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using Microsoft.Extensions.Logging;
using SlnMesnac.Config;
using System;
using System.IO.Ports;
using System.Text;
using System.Threading;
namespace SlnMesnac.Common
{
/// <summary>
/// 光源控制类
/// </summary>
public sealed class LightHelper
{
public delegate void RefreshMessage(string message, bool isWarning = false);
public static event RefreshMessage? RefreshMessageEvent;
#region 单例实现
private static readonly LightHelper lazy = new LightHelper();
public static LightHelper Instance
{
get
{
return lazy;
}
}
#endregion
private ILogger<LightHelper> logger;
#region 变量定义
private static SerialPort serialPort = new SerialPort();
#endregion
private DebugConfig config = DebugConfig.Instance;
//初始化串口并启动接收数据
public void InstanceSerialPort()
{
try
{
serialPort.PortName = config.LightPort;// portName;
serialPort.BaudRate = int.Parse(config.LightBaudRate);
//奇偶校验
serialPort.Parity = Parity.None;
//停止位
serialPort.StopBits = StopBits.One;
//数据位
serialPort.DataBits = 0x8;
//忽略null字节
serialPort.DiscardNull = true;
//接收事件
serialPort.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(serialPort1_DataReceived);
//开启串口
serialPort.Open();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message.ToString());
}
}
/// <summary>
/// 接收数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string result = "";
int bytesToRead = serialPort.BytesToRead;
byte[] buf = new byte[bytesToRead];
serialPort.Read(buf, 0x0, bytesToRead);
for (int i = 0x0; i < buf.Length; i++)
{
int num = (int)buf[i];
result =result+num.ToString("X2");
}
Console.WriteLine(result);
}
/// <summary>
/// 发送数据方法
///OPEN打开灯光,CLOSE关闭灯光
/// </summary>
/// <param name="data"></param>
public void SendData(string data)
{
try
{
if (serialPort.IsOpen)
{
if (data == "OPEN")
{
// 第1通道亮度200
serialPort.Write(CalculateChecksum("$31"));
Thread.Sleep(30);
// 第2通道亮度200
serialPort.Write(CalculateChecksum("$32"));
}
else if (data == "CLOSE")
{
// 第1通道亮度0
serialPort.Write("$3100016");
Thread.Sleep(30);
// 第2通道亮度0
serialPort.Write("$3200015");
}
}
else
{
logger.LogError("灯光串口未打开,请先初始化串口并打开连接。");
}
}
catch (Exception ex)
{
logger.LogError($"灯光发送数据时发生错误:{ex.Message}");
RefreshMessageEvent?.Invoke("相机灯光控制失败,检查灯光参数",true);
}
}
/// <summary>
/// 校验位计算,返回指令,input==$31\32
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public string CalculateChecksum(string input)
{
if (input == "$31")
{
input = input + StringToHex(config.Ch1);
}
else
{
input = input + StringToHex(config.Ch2);
}
// Step 1: Convert each character to ASCII binary representation
StringBuilder binaryBuilder = new StringBuilder();
foreach (char c in input)
{
// Convert character to ASCII binary
string asciiBinary = Convert.ToString(c, 2).PadLeft(8, '0');
binaryBuilder.Append(asciiBinary);
}
string binaryString = binaryBuilder.ToString();
// Step 2: Apply XOR operation consecutively
int result = 0;
for (int i = 0; i < binaryString.Length; i += 8)
{
// Take 8 bits (1 byte) at a time
string segment = binaryString.Substring(i, 8);
int segmentInt = Convert.ToInt32(segment, 2);
result ^= segmentInt;
}
// Step 3: Convert the final result to hexadecimal
string checksumHex = result.ToString("X");
// Ensure checksumHex is 2 characters long (pad with 0 if necessary)
checksumHex = checksumHex.PadLeft(2, '0');
return input+checksumHex;
}
/// <summary>
/// 将字符串转换为十六进制字符串
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public string StringToHex(string input)
{
try
{
int num = int.Parse(input);
return num.ToString("X3");
}
catch (Exception ex)
{
RefreshMessageEvent?.Invoke("检查亮度参数是否合理:0-255", true);
return null;
}
}
}
}