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;
}
}
}
}