目录
1. 创建WPF项目ModbusTcpDemo
Visual Studio 2019
.NET Framework 4.8.1
2. NuGet安装依赖包
Nmodbus4
3. 编辑ModelView.xmal代码
<Window x:Class="ModbusTcpDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ModbusTcpDemo"
mc:Ignorable="d"
Title="ModBus示例" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="320"/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel HorizontalAlignment="Center">
<TextBox x:Name="TextReceiveData" Text="读取内容" IsReadOnly="True" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" Width="700" Height="300" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Margin="0 10 0 10"/>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center">
<Label Content="IP地址:" VerticalContentAlignment="Center" FontWeight="Bold"/>
<TextBox x:Name="TextIpAddress" Text="127.0.0.1" Height="30" Width="100" FontSize="20" HorizontalContentAlignment="Center"/>
<Label Content="端口:" VerticalAlignment="Center" FontWeight="Bold"/>
<TextBox x:Name="TextPort" Text="502" Height="30" Width="50" FontSize="20" HorizontalContentAlignment="Center"/>
<Label Content="从站地址:" VerticalAlignment="Center" FontWeight="Bold"/>
<TextBox x:Name="TextSlaveAddress" Text="1" Height="30" Width="50" FontSize="20" HorizontalContentAlignment="Center"/>
<Label Content="起始地址:" VerticalAlignment="Center" FontWeight="Bold"/>
<TextBox x:Name="TextStartAddress" Text="0" Height="30" Width="50" FontSize="20" HorizontalContentAlignment="Center"/>
<Label Content="读取个数:" VerticalAlignment="Center" FontWeight="Bold"/>
<TextBox x:Name="TextTotalSize" Text="1" Height="30" Width="50" FontSize="20" HorizontalContentAlignment="Center"/>
<Button x:Name="BtnConnectAndStart" Content="连接并启动" FontWeight="Bold" Height="30" Width="80" Margin="10 0 0 0" Click="ConnectAndStartRetriveData"/>
</StackPanel>
</Grid>
</Window>
4. 编辑ModelView.xmal.cs代码
using System;
using System.Net.Sockets;
using System.Threading.Tasks;
using System.Windows;
namespace ModbusTcpDemo
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
TcpClient tcpClient = null;
public MainWindow()
{
InitializeComponent();
}
private void ConnectAndStartRetriveData(object sender, RoutedEventArgs e)
{
var port = TextPort.Text;
var ipAddress = TextIpAddress.Text;
var readTotalSize = TextTotalSize.Text;
var slaveAddress = TextSlaveAddress.Text;
var startReadAddress = TextStartAddress.Text;
//1. 读取IP地址并验证是否是合法的
if (!isValidIpAddress(ipAddress))
{
MessageBox.Show("不是合法的IP地址");
return;
}
//2. 读取端口号并验证是否是合法的
if (!isValidPort(port))
{
MessageBox.Show("不是合法的端口");
}
//3. 禁用“连接并启动”按钮
BtnConnectAndStart.IsEnabled = false;
//4. 建立TCP连接
if (tcpClient == null)
{
tcpClient = new TcpClient();
}
tcpClient.Connect(ipAddress, int.Parse(port));
//5. 建立Modbus连接
Modbus.Device.ModbusIpMaster master = Modbus.Device.ModbusIpMaster.CreateIp(tcpClient);
//6. 启动线程去循环获取数据
Task.Run(()=> {
while (true)
{
ushort[] ushortArray = master.ReadHoldingRegisters((byte)int.Parse(slaveAddress), (byte)int.Parse(startReadAddress), (byte)int.Parse(readTotalSize));
//注意这里WPF线程更新UI需要用以下的方法 不然程序运行会出问题
Application.Current.Dispatcher.Invoke((Action)delegate ()
{
TextReceiveData.Text = ushortArray[0].ToString();
});
}
});
}
private bool isValidIpAddress(string ipAddress)
{
//TODO
return true;
}
private bool isValidPort(string port)
{
//TODO
return true;
}
}
}
5. 启动Modbus Slave工具
6. 启动程序进行连接测试