NModbus4有.NetCore版本 此为.netCore3.1
依赖项
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>WinExeOutputType>
<TargetFramework>netcoreapp3.1TargetFramework>
<UseWindowsForms>trueUseWindowsForms>
PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.22" />
<PackageReference Include="NModbus4.NetCore" Version="1.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="6.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.22" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="3.1.22" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.22" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.22">
<PrivateAssets>allPrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitiveIncludeAssets>
PackageReference>
ItemGroup>
<ItemGroup>
<None Update="Ipcfg.json">
<CopyToOutputDirectory>PreserveNewestCopyToOutputDirectory>
None>
ItemGroup>
<ItemGroup>
<Folder Include="DataConvertLib\" />
ItemGroup>
Project>
ModbusTCP Helper
using Modbus.Device;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using thinger.DataConvertLib;
namespace NModbusCoreDemon
{
public class NModBusHelper
{
private TcpClient tcpClient = null;
private ModbusIpMaster master;
public bool Connect(string ip, string port)
{
try
{
tcpClient = new TcpClient();
tcpClient.Connect(IPAddress.Parse(ip), int.Parse(port));
master = ModbusIpMaster.CreateIp(tcpClient);
}
catch (Exception)
{
return false;
}
return tcpClient.Connected;
}
public bool Disconnect()
{
if (tcpClient != null)
{
tcpClient.Close();
return true;
}
else
{
return false;
}
}
public byte[] ReadKeepRegByteArr(string iAddress, string iLength)//偏移量,寄存器数量
{
try
{
ushort[] des = master.ReadHoldingRegisters(ushort.Parse(iAddress), ushort.Parse(iLength));
byte[] res = ByteArrayLib.GetByteArrayFromUShortArray(des);
return res;
}
catch (Exception)
{
return null;
}
}
public ushort[] ReadKeepRegUshort(string iAddress, string iLength)//偏移量,寄存器数量
{
try
{
ushort[] des = master.ReadHoldingRegisters(ushort.Parse(iAddress), ushort.Parse(iLength));
//byte[] res = ByteArrayLib.GetByteArrayFromUShortArray(des);
return des;
}
catch (Exception)
{
return null;
}
}
public List<float> AnalyseData_4x(ushort[] des, string iAddress)
{
int StartByte;
StartByte = int.Parse(iAddress) * 2;
List<float> floatArray = new List<float>();
byte[] byteArray = ByteArrayLib.GetByteArrayFromUShortArray(des);
for (int i = StartByte; i < byteArray.Length; i += 4)
{
floatArray.Add(FloatLib.GetFloatFromByteArray(byteArray, i));
}
return floatArray;
}
}
}
主界面UI
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using thinger.DataConvertLib;
using System.Linq;
using System.IO;
namespace NModbusCoreDemon
{
public partial class FrmMain : Form
{
public FrmMain()
{
InitializeComponent();
this.Load += FrmMain_Load;
}
private void FrmMain_Load(object sender, EventArgs e)
{
cfgBuilder.AddJsonFile("Ipcfg.json", optional: true, reloadOnChange: true);
IConfigurationRoot configRoot = cfgBuilder.Build();
this.ip = configRoot.GetSection("Ip").Value;
this.port = configRoot.GetSection("Port").Value;
//str = Directory.GetCurrentDirectory();
}
private ConfigurationBuilder cfgBuilder = new ConfigurationBuilder();
public string ip;
public string port;
private CancellationTokenSource cts = new CancellationTokenSource();
private bool IsConnected = false;
ushort[] res;
string iAddress = "0";
string iLenth = "10"; //寄存器个数
private List<float> floatList = new List<float>();
private NModBusHelper objTcp = new NModBusHelper();
//设置ListBox
private void Addinfo(string info)
{
this.isInfo.Items.Insert(
0, DateTime.Now.ToString("HH:mm:ss") + " " + info + Environment.NewLine);
}
private void btnConn_Click(object sender, EventArgs e)
{
IsConnected = objTcp.Connect(ip, port);
Addinfo(IsConnected ? "连接成功" : "连接失败");
}
private void btnDisConn_Click(object sender, EventArgs e)
{
objTcp.Disconnect();
Addinfo("断开连接");
}
private void btnRead_Click(object sender, EventArgs e)
{
Addinfo("开始读取整数");
Task.Run(async () =>
{
while (!cts.IsCancellationRequested)
{
await Task.Delay(500);
res = objTcp.ReadKeepRegUshort(iAddress, iLenth);
for (int i = 0; i < res.Length; i++)
{
this.isInfo.Invoke(new Action<ushort>(t =>
{
this.isInfo.Items.Add(t.ToString());
}), res[i]);
}
}
}, cts.Token);
}
private void btnReadFloat_Click(object sender, EventArgs e)
{
Addinfo("开始读取浮点数");
Task.Run(async () =>
{
while (!cts.IsCancellationRequested)
{
await Task.Delay(500);
res = objTcp.ReadKeepRegUshort(iAddress, iLenth);
floatList.AddRange(objTcp.AnalyseData_4x(res, iAddress));
for (int i = 0; i < floatList.Count; i++)
{
this.isInfo.Invoke(new Action<float>(t =>
{
this.isInfo.Items.Add(t.ToString());
}), floatList.ToArray()[i]);
}
}
}, cts.Token);
}
//大小端的方法:西门子等欧系PLC都是大端在前
List<ushort> barr2 = new List<ushort>();
//第一种方法
private void btn1_Click(object sender, EventArgs e)
{
byte[] barr = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
for (int i = 0; i < barr.Length; i+=2)
{
byte tmpByte = barr[i+1];
barr[i + 1] = barr[i];
barr[i] = tmpByte;
}
for (int i = 0; i < barr.Length; i++)
{
this.isInfo.Invoke(new Action<byte>(t =>
{
this.isInfo.Items.Add(t.ToString());
}), barr[i]);
}
}
//第二种方法
private void btn2_Click(object sender, EventArgs e)
{
byte[] barr = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
//barr2.AddRange(barr);
byte[] byteArr;
for (int i = 0; i < barr.Length; i += 2)
{
barr2.Add(Convert.ToUInt16(barr[i] + barr[i + 1] * 256));
}
byteArr = ByteArrayLib.GetByteArrayFromUShortArray(barr2.ToArray());
for (int i = 0; i < byteArr.Length; i++)
{
this.isInfo.Invoke(new Action<ushort>(t =>
{
this.isInfo.Items.Add(t.ToString());
}), byteArr[i]);
}
}
private void btnInsert_Click(object sender, EventArgs e)
{
using (MyDbContext dbContext = new MyDbContext())
{
ActualData actualData = new ActualData()
{
Description = "测试Description1",
Value = "23345",
InsertTime = DateTime.UtcNow
};
dbContext.ActualDatas.Add(actualData);
dbContext.SaveChanges();
}
}
}
}
json文件
{
"Ip": "127.0.0.1",
"Port": "502",
"ConnectionStrings": {
"SqliteConnectionString": "Data Source=E:\\Csharp\\NModbusCoreDemon\\NModbusCoreDemon\\bin\\Debug\\netcoreapp3.1\\Database\\DbSqlite.db",
"MySQLConnectionString": "server=192.168.85.102; database=OneToMany; uid=root; pwd=123456;"
}
}
实体类:
using System;
using System.Collections.Generic;
using System.Text;
namespace NModbusCoreDemon
{
public class ActualData
{
public long Id { get; set; }
public string Description { get; set; }
public string Value { get; set; }
public DateTime InsertTime { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace NModbusCoreDemon
{
public class Variable
{
public long Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Type { get; set; }
public string VarAddress { get; set; }
public string Scale { get; set; }
public string Offset { get; set; }
public string Start { get; set; }
public string AccessProperty { get; set; }
public string AlarmEnable { get; set; }
public string ArchiveEnable { get; set; }
public string SetLimitEnable { get; set; }
public string AlarmType { get; set; }
public string DiscreteAlarmType { get; set; }
public string DiscreteAlarmPriority { get; set; }
public string DiscreteAlarmNote { get; set; }
public string LoLoAlarmEnable { get; set; }
public string LoLoAlarmValue { get; set; }
public string LoLoAlarmPriority { get; set; }
public string LoLoAlarmNote { get; set; }
public string LowAlarmEnable { get; set; }
public string LowAlarmValue { get; set; }
public string LowAlarmPriority { get; set; }
public string LowAlarmNote { get; set; }
public string HighAlarmEnable { get; set; }
public string HighAlarmValue { get; set; }
public string HighAlarmPriority { get; set; }
public string HighAlarmNote { get; set; }
public string HiHiAlarmEnable { get; set; }
public string HiHiAlarmValue { get; set; }
public string HiHiAlarmPriority { get; set; }
public string HiHiAlarmNote { get; set; }
public string ArchivePeriod { get; set; }
public string SetLimitMax { get; set; }
public string SetLimitMin { get; set; }
public string VarType { get; set; }
}
}
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
using System.Text;
namespace NModbusCoreDemon
{
public class ActualDataConfig : IEntityTypeConfiguration<ActualData>
{
public void Configure(EntityTypeBuilder<ActualData> builder)
{
builder.ToTable("ActualData");
builder.HasKey(a => a.Id);
builder.Property(a => a.Description).HasMaxLength(100);
}
}
}
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
using System.Text;
namespace NModbusCoreDemon
{
public class VariableConfig : IEntityTypeConfiguration<Variable>
{
public void Configure(EntityTypeBuilder<Variable> builder)
{
builder.ToTable("Variable");
builder.HasKey(v => v.Id);
builder.Property(v => v.Description).HasMaxLength(100);
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Sqlite;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
namespace NModbusCoreDemon
{
public class MyDbContext:DbContext
{
public DbSet<ActualData> ActualDatas { get; set; }
public DbSet<Variable> Variables { get; set; }
private ConfigurationBuilder cfgBuilder = new ConfigurationBuilder();
//private IConfiguration configuration;
//private string connString;
public MyDbContext()
{
//configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("Ipcfg.json").Build();
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
cfgBuilder.AddJsonFile("Ipcfg.json", optional: true, reloadOnChange: true);
IConfigurationRoot configRoot = cfgBuilder.Build();
string connString = configRoot.GetSection("ConnectionStrings:SqliteConnectionString").Value;
optionsBuilder.UseSqlite(connString);
//configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("Ipcfg.json").Build();
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
//var iniActualData = File.ReadAllText(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"/Database/Variable.json");
//IList iniActualList = JsonConvert.DeserializeObject>(iniActualData);
//modelBuilder.Entity().HasData(iniActualList);
modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
}
}
}
DataConvertTool 数据转换类 来自于付老师的开源项目:
https://gitee.com/fujiajin/thinger.cn.DataConvertTool