三、代码
public partial class ModbusTCP : Form
{
#region 字段
private string ipAddress = "127.0.0.1";
private int port = 502;
private byte slaveId = 1;
ushort startAddress = 0;
ushort numRegisters = 10;
ushort writeAddress = 0;
ushort writeValue = 0;
private bool isConnected = false;
private TcpClient tcpClient = null;
private ModbusFactory factory = null;
private IModbusMaster master = null;
Timer taskTimer = null;
private Timer heartbeatTimer = null;
#endregion
#region 初始化加载
public ModbusTCP()
{
InitializeComponent();
CenterToParent();
CenterToScreen();
}
private void MainForm_Load(object sender, EventArgs e)
{
Initialize();
}
private void ModbusTCP_FormClosing(object sender, FormClosingEventArgs e)
{
isConnected = false;
taskTimer?.Stop();
tcpClient?.Close();
heartbeatTimer?.Stop();
}
#endregion
public void Initialize()
{
InitializeControlsState();
UpdataControlsState();
dataGridView.Columns[0].Width = 100;
dataGridView.Columns[1].Width = 100;
dataGridView.Columns[0].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
dataGridView.Columns[1].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
dataGridView.RowHeadersVisible = false;
dataGridView.Rows.Add(new object[] { 0, 0 });
dataGridView.Rows.Add(new object[] { 1, 0 });
dataGridView.Rows.Add(new object[] { 2, 0 });
dataGridView.Rows.Add(new object[] { 3, 0 });
dataGridView.Rows.Add(new object[] { 4, 0 });
dataGridView.Rows.Add(new object[] { 5, 0 });
dataGridView.Rows.Add(new object[] { 6, 0 });
dataGridView.Rows.Add(new object[] { 7, 0 });
dataGridView.Rows.Add(new object[] { 8, 0 });
dataGridView.Rows.Add(new object[] { 9, 0 });
taskTimer = new Timer();
taskTimer.Interval = 100;
taskTimer.Tick += Timer_Tick;
heartbeatTimer = new Timer();
heartbeatTimer.Interval = 1000;
heartbeatTimer.Tick += HeartbeatTimer_Tick;
}
private void HeartbeatTimer_Tick(object sender, EventArgs e)
{
try
{
ushort[] dummyArray = master.ReadHoldingRegisters(slaveId, 0, 1);
if (dummyArray == null || dummyArray.Length != 1 || dummyArray[0] != 0)
{
UpdataMessage("心跳失败,断开连接...");
isConnected = false;
taskTimer.Stop();
tcpClient.Close();
UpdataControlsState();
}
}
catch (Exception ex)
{
UpdataMessage("心跳失败...");
isConnected = false;
taskTimer.Stop();
tcpClient.Close();
UpdataControlsState();
}
}
public void InitializeControlsState()
{
tbx_SlaveID.Text = slaveId.ToString();
tbx_IPAddress.Text = ipAddress;
tbx_TargetPort.Text = port.ToString();
tbx_StartAddress.Text = startAddress.ToString();
tbx_ReadLength.Enabled = false;
tbx_ReadLength.Text = numRegisters.ToString();
tbx_WriteAddress.Text = writeAddress.ToString();
tbx_WriteValue.Text = writeValue.ToString();
}
private void UpdataControlsState()
{
if (isConnected)
{
btn_Connect.Text = "断开";
btn_WriteData.Enabled = true;
tbx_IPAddress.Enabled = false;
tbx_TargetPort.Enabled = false;
tbx_SlaveID.Enabled = false;
tbx_ReadLength.Enabled=false;
}
else
{
btn_Connect.Text = "连接";
btn_WriteData.Enabled = false;
tbx_IPAddress.Enabled = true;
tbx_TargetPort.Enabled = true;
tbx_SlaveID.Enabled = true;
tbx_ReadLength.Enabled = false;
}
}
private void Timer_Tick(object sender, EventArgs e)
{
try
{
if (isConnected)
{
ushort[] array = master.ReadHoldingRegisters(slaveId, startAddress, numRegisters);
for (int i = 0; i < array.Length; i++)
{
dataGridView.Rows[i].Cells[0].Value = (startAddress + i);
dataGridView.Rows[i].Cells[1].Value = array[i];
}
}
}
catch (Exception ex)
{
UpdataMessage("");
}
}
private void btn_Connect_Click(object sender, EventArgs e)
{
try
{
if (!isConnected)
{
tcpClient = new TcpClient(ipAddress, port);
factory = new ModbusFactory();
master = factory.CreateMaster(tcpClient);
taskTimer.Start();
heartbeatTimer?.Start();
isConnected = true;
UpdataControlsState();
UpdataMessage("连接成功...");
}
else
{
isConnected = false;
master = null;
taskTimer.Stop();
tcpClient.Close();
UpdataControlsState();
UpdataMessage("断开连接...");
heartbeatTimer?.Stop();
}
}
catch (Exception ex)
{
isConnected = false;
taskTimer?.Stop();
heartbeatTimer?.Stop();
tcpClient?.Close();
UpdataControlsState();
UpdataMessage("连接失败...");
UpdataMessage($"{ex.Message}");
}
}
private void btn_WriteData_Click(object sender, EventArgs e)
{
master.WriteSingleRegister(slaveId, writeAddress, writeValue);
UpdataMessage($"从站ID:{slaveId},写入数据:地址:{writeAddress} ,值:{writeValue}");
}
private void UpdataMessage(string message)
{
tbx_Output.BeginInvoke(new Action(() =>
{
tbx_Output.AppendText($"{DateTime.Now.ToString()}】{message}\r\n");
}));
}
#region 文本变更
private void tbx_StartAddress_TextChanged(object sender, EventArgs e)
{
if (ushort.TryParse(tbx_StartAddress.Text, out ushort address))
{
startAddress = address;
}
}
private void tbx_ReadLength_TextChanged(object sender, EventArgs e)
{
if (ushort.TryParse(tbx_ReadLength.Text, out ushort length))
{
numRegisters = length;
}
}
private void tbx_WriteAddress_TextChanged(object sender, EventArgs e)
{
if (ushort.TryParse(tbx_WriteAddress.Text, out ushort address))
{
writeAddress = address;
}
}
private void tbx_WriteValue_TextChanged(object sender, EventArgs e)
{
if (ushort.TryParse(tbx_WriteValue.Text, out ushort address))
{
writeValue = address;
}
}
private void tbx_SlaveID_TextChanged(object sender, EventArgs e)
{
if (byte.TryParse(tbx_SlaveID.Text, out byte address))
{
slaveId = address;
}
}
#endregion
}