using Microsoft.Extensions.Logging; using SlnMesnac.Config; using SlnMesnac.Model.dto; using System; using System.IO.Ports; using System.Text; using System.Threading; namespace SlnMesnac.Common { /// /// 光源控制类 /// 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 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()); } } /// /// 接收数据 /// /// /// 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); } /// /// 发送数据方法 ///OPEN:打开灯光,CLOSE:关闭灯光 ///可选参数:lightType: 0-默认两个灯亮; 1-ch1亮; 2-ch2亮 /// /// public void SendData(string data, BarCodeModel barCodeModel =null) { //try //{ // if (serialPort.IsOpen) // { // if (data == "OPEN") // { // if (barCodeModel != null) // { // OpenByConfig(barCodeModel); // } // else // { // // 第1通道亮度 // serialPort.Write(CalculateChecksum("$31","220")); // Thread.Sleep(30); // // 第2通道亮度 // serialPort.Write(CalculateChecksum("$32","220")); // } // } // 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); //} } /// /// 根据配置文件打开灯光 /// private void OpenByConfig(BarCodeModel barCodeModel) { if (config.FullLightControl == "1") { //全局控制 // 第1通道亮度 serialPort.Write(CalculateChecksum("$31", config.Ch1)); Thread.Sleep(30); // 第2通道亮度 serialPort.Write(CalculateChecksum("$32", config.Ch2)); } else { // 单独采用数据库配置 if(barCodeModel.logoConfig.LightType== 1) { // 第1通道亮度 serialPort.Write(CalculateChecksum("$31", barCodeModel.logoConfig.Ch1Hight.ToString())); }else if(barCodeModel.logoConfig.LightType == 2) { // 第2通道亮度 serialPort.Write(CalculateChecksum("$32", barCodeModel.logoConfig.Ch2Hight.ToString())); } else { // 第1通道亮度 serialPort.Write(CalculateChecksum("$31", barCodeModel.logoConfig.Ch1Hight.ToString())); // 第2通道亮度 serialPort.Write(CalculateChecksum("$32", barCodeModel.logoConfig.Ch2Hight.ToString())); } } } /// /// 校验位计算,返回指令,input==$31\32 /// /// /// public string CalculateChecksum(string input,string high) { input = input + StringToHex(high); // 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; } /// /// 将字符串转换为十六进制字符串 /// /// /// 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; } } } }