using Modbus.Device; using MyCommunicators; using RJCP.IO.Ports; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO.Ports; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; namespace MyProcesses.Communicators { public class ModbusRTU : BaseCommunicator { SerialPort SerialPort = null; ModbusSerialMaster ModbusRTUMaster = null; ushort startAddress { get { ushort addr = 0; if (CommunicatorConnections.Contains("首地址")) { ushort.TryParse(CommunicatorConnections["首地址"].ToString(), out addr); } return addr; } } ushort numRegisters { get { ushort num = 100; if (CommunicatorConnections.Contains("寄存器个数")) { ushort.TryParse(CommunicatorConnections["寄存器个数"].ToString(), out num); } return num; } } public ModbusRTU(string name = "ModbusRTU主站") { CommunicatorConnections.Add("地址", "COM1"); CommunicatorConnections.Add("端口", "9600"); CommunicatorConnections.Add("首地址", "0"); CommunicatorConnections.Add("寄存器个数", "100"); CommunicatorBrand = CommunicatorBrand.ModbusRTUMaster; CommunicatorName = name; } /// /// 配置串口参数 /// /// /// /// /// /// public void SetConfigure(string portName, int baudRate = 9600, System.IO.Ports.Parity parity = System.IO.Ports.Parity.None, int dataBits = 8, System.IO.Ports.StopBits stopBits = System.IO.Ports.StopBits.One) { Disconnect(); SerialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits); } public override bool Connect() { try { Disconnect(); //波特率 int PORT = 0; if (!int.TryParse(this.CommunicatorConnections["端口"].ToString(), out PORT)) { Msg = string.Format("端口未设置"); return false; } if (!CommunicatorConnections.Contains("地址")) { Msg = string.Format("地址未设置"); return false; } //串口号 string IP = CommunicatorConnections["地址"].ToString(); if (!SerialPort.IsOpen) { SerialPort = new SerialPort(); SetConfigure(IP, PORT); SerialPort.Open(); bConnected = true; // 启动心跳线程 bHeart = true; //heartbeatThread = new Thread(SendHeartbeat); //heartbeatThread.IsBackground = true; //heartbeatThread.Start(); // 启动接收线程 Task.Run(HandleServerComm); return true; } else { Msg = $"原串口关闭失败无法重新打开"; return false; } } catch (Exception ex) { Msg = $"失败,服务器未启动: {ex.Message}"; return false; } } public override bool Disconnect() { try { bConnected = false; if (SerialPort == null) { SerialPort = new SerialPort(); return true; } if (SerialPort.IsOpen) SerialPort.Close(); // 关闭串口 SerialPort = new SerialPort(); return true; } catch (Exception ex) { bConnected = false; Msg = $"断开串口时出错: {ex.Message}"; return true; } } string lastReceiveMsg = ""; private async Task HandleServerComm() { while (bConnected) { try { await Task.Delay(25); // 等待 25ms 后再尝试检查数据 byte[] buffer = new byte[1024]; // 主站轮询从站数据 int bytesRead = 0;//= _networkStream.Read(buffer, 0, buffer.Length); if (bytesRead > 0) { string message = Encoding.UTF8.GetString(buffer, 0, bytesRead); if (message != null) { strReceiveMsg = message; // 从站数据发生变化时触发消息接收事件 if (lastReceiveMsg != strReceiveMsg) { lastReceiveMsg = strReceiveMsg; try { TriggerRunMessageReceived?.Invoke(CommunicatorName, strReceiveMsg); // 触发运行事件 } catch { } try { MessageReceived?.Invoke(strReceiveMsg); // 触发回调 } catch { } } } } } catch (Exception ex) { bHeart = false; Debug.WriteLine($"接收消息时发生错误: {ex.Message}"); } } } // 发送消息到服务器 public override bool SendMessage(string message) { if (!bConnected) { Msg = "尚未连接到服务器"; return false; } try { //空消息不发送 if (string.IsNullOrEmpty(message) || message.Trim() == "") return true; // slaveAddress是目标设备的地址,address是要写入的寄存器地址,value是要写入的数据 ModbusRTUMaster.WriteSingleRegisterAsync(1, 0, ushort.Parse(message)); //_writer.Flush(); // 强制将缓冲区中的数据写入网络流 return true; } catch (Exception ex) { bHeart = false; Msg = $"发送消息时发生错误: {ex.Message}"; return false; } } } }