Files
ModbusTool/ModbusMaster/MasterForm.cs
T
2020-07-27 09:20:24 -04:00

285 lines
9.6 KiB
C#

using System;
using System.IO.Ports;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Windows.Forms;
using Modbus.Common;
using ModbusLib;
using ModbusLib.Protocols;
namespace ModbusMaster
{
public partial class MasterForm : BaseForm
{
private int _transactionId;
private ModbusClient _driver;
private ICommClient _portClient;
private SerialPort _uart;
private byte _lastReadCommand = 0;
#region Form
public MasterForm()
{
InitializeComponent();
this.Text += String.Format(" ({0})", Assembly.GetExecutingAssembly().GetName().Version.ToString());
}
private void MasterFormClosing(object sender, FormClosingEventArgs e)
{
DoDisconnect();
}
#endregion
#region Connect/disconnect
private void DoDisconnect()
{
if (_socket != null)
{
_socket.Close();
_socket.Dispose();
_socket = null;
}
if (_uart != null)
{
_uart.Close();
_uart.Dispose();
_uart = null;
}
_portClient = null;
_driver = null;
}
private void BtnConnectClick(object sender, EventArgs e)
{
try
{
switch (CommunicationMode)
{
case CommunicationMode.RTU:
_uart = new SerialPort(PortName, Baud, Parity, DataBits, StopBits);
_uart.Open();
_portClient = _uart.GetClient();
_driver = new ModbusClient(new ModbusRtuCodec()) { Address = SlaveId };
_driver.OutgoingData += DriverOutgoingData;
_driver.IncommingData += DriverIncommingData;
AppendLog(String.Format("Connected using RTU to {0}", PortName));
break;
case CommunicationMode.UDP:
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
_socket.Connect(new IPEndPoint(IPAddress, TCPPort));
_portClient = _socket.GetClient();
_driver = new ModbusClient(new ModbusTcpCodec()) { Address = SlaveId };
_driver.OutgoingData += DriverOutgoingData;
_driver.IncommingData += DriverIncommingData;
AppendLog(String.Format("Connected using UDP to {0}", _socket.RemoteEndPoint));
break;
case CommunicationMode.TCP:
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
_socket.SendTimeout = 2000;
_socket.ReceiveTimeout = 2000;
_socket.Connect(new IPEndPoint(IPAddress, TCPPort));
_portClient = _socket.GetClient();
_driver = new ModbusClient(new ModbusTcpCodec()) { Address = SlaveId };
_driver.OutgoingData += DriverOutgoingData;
_driver.IncommingData += DriverIncommingData;
AppendLog(String.Format("Connected using TCP to {0}", _socket.RemoteEndPoint));
break;
}
}
catch (Exception ex)
{
AppendLog(ex.Message);
return;
}
btnConnect.Enabled = false;
buttonDisconnect.Enabled = true;
groupBoxFunctions.Enabled = true;
groupBoxTCP.Enabled = false;
groupBoxRTU.Enabled = false;
groupBoxMode.Enabled = false;
grpExchange.Enabled = false;
}
private void ButtonDisconnectClick(object sender, EventArgs e)
{
DoDisconnect();
btnConnect.Enabled = true;
buttonDisconnect.Enabled = false;
groupBoxFunctions.Enabled = false;
groupBoxMode.Enabled = true;
grpExchange.Enabled = true;
SetMode();
AppendLog("Disconnected");
}
#endregion
#region Functions buttons
private void BtnReadCoilsClick(object sender, EventArgs e)
{
ExecuteReadCommand(ModbusCommand.FuncReadCoils);
}
private void BtnReadDisInpClick(object sender, EventArgs e)
{
ExecuteReadCommand(ModbusCommand.FuncReadInputDiscretes);
}
private void BtnReadHoldRegClick(object sender, EventArgs e)
{
ExecuteReadCommand(ModbusCommand.FuncReadMultipleRegisters);
}
private void BtnReadInpRegClick(object sender, EventArgs e)
{
ExecuteReadCommand(ModbusCommand.FuncReadInputRegisters);
}
private void ExecuteReadCommand(byte function)
{
_lastReadCommand = function;
try
{
var command = new ModbusCommand(function) {Offset = StartAddress, Count = DataLength, TransId = _transactionId++};
var result = _driver.ExecuteGeneric(_portClient, command);
if (result.Status == CommResponse.Ack)
{
command.Data.CopyTo(_registerData, StartAddress);
UpdateDataTable();
AppendLog(String.Format("Read succeeded: Function code:{0}.", function));
}
else
{
AppendLog(String.Format("Failed to execute Read: Error code:{0}", result.Status));
}
}
catch (Exception ex)
{
AppendLog(ex.Message);
}
}
private void ExecuteWriteCommand(byte function)
{
try
{
var command = new ModbusCommand(function)
{
Offset = StartAddress,
Count = DataLength,
TransId = _transactionId++,
Data = new ushort[DataLength]
};
for (int i = 0; i < DataLength; i++)
{
var index = StartAddress + i;
if (index > _registerData.Length)
{
break;
}
command.Data[i] = _registerData[index];
}
var result = _driver.ExecuteGeneric(_portClient, command);
AppendLog(result.Status == CommResponse.Ack
? String.Format("Write succeeded: Function code:{0}", function)
: String.Format("Failed to execute Write: Error code:{0}", result.Status));
}
catch (Exception ex)
{
AppendLog(ex.Message);
}
}
private void BtnWriteSingleCoilClick(object sender, EventArgs e)
{
try
{
var command = new ModbusCommand(ModbusCommand.FuncWriteCoil)
{
Offset = StartAddress,
Count = 1,
TransId = _transactionId++,
Data = new ushort[1]
};
command.Data[0] = (ushort)(_registerData[StartAddress] & 0x0100);
var result = _driver.ExecuteGeneric(_portClient, command);
AppendLog(result.Status == CommResponse.Ack
? String.Format("Write succeeded: Function code:{0}", ModbusCommand.FuncWriteCoil)
: String.Format("Failed to execute Write: Error code:{0}", result.Status));
}
catch (Exception ex)
{
AppendLog(ex.Message);
}
}
private void BtnWriteSingleRegClick(object sender, EventArgs e)
{
ExecuteWriteCommand(ModbusCommand.FuncWriteSingleRegister);
}
private void BtnWriteMultipleCoilsClick(object sender, EventArgs e)
{
ExecuteWriteCommand(ModbusCommand.FuncForceMultipleCoils);
}
private void BtnWriteMultipleRegClick(object sender, EventArgs e)
{
ExecuteWriteCommand(ModbusCommand.FuncWriteMultipleRegisters);
}
private void ButtonReadExceptionStatusClick(object sender, EventArgs e)
{
}
#endregion
private void txtPollDelay_Leave(object sender, EventArgs e)
{
var textBox = (TextBox)sender;
if (int.TryParse(textBox.Text, out var parsedMillisecs))
{
pollTimer.Interval = parsedMillisecs;
}
else
{
textBox.Text = "0";
cbPoll.Checked = false;
pollTimer.Enabled = false;
}
}
private void cbPoll_CheckStateChanged(object sender, EventArgs e)
{
pollTimer.Enabled = cbPoll.Checked;
if (!pollTimer.Enabled)
_lastReadCommand = 0;
}
private void pollTimer_Tick(object sender, EventArgs e)
{
if (_lastReadCommand != 0)
ExecuteReadCommand(_lastReadCommand);
}
private void MasterForm_Load(object sender, EventArgs e)
{
}
}
}