.netCore环境下使用ModbusTCP读取PLC数据, 大小端的两种转换方法

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

效果
.netCore环境下使用ModbusTCP读取PLC数据, 大小端的两种转换方法_第1张图片

DataConvertTool 数据转换类 来自于付老师的开源项目:

https://gitee.com/fujiajin/thinger.cn.DataConvertTool

你可能感兴趣的:(c#,java)