.NET6下的Modbus通讯 和数据库记录

这个C#应用展示了如何结合Entity Framework Core进行数据库操作,并实现Modbus通信。应用包含了数据库模型配置,如NodeClass、ModbusNode、ModbusGroup和Variable,用于存储Modbus设备的配置信息。同时,定义了NModBusHelper类用于与Modbus设备进行数据交换,包括读取和解析寄存器数据。此外,应用还包括了一个定时任务,周期性地从Modbus设备读取数据并将其存储到SQLite数据库中。

所用的包:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net6.0-windows</TargetFramework>
    <Nullable>enable</Nullable>
    <UseWindowsForms>true</UseWindowsForms>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <None Include="..\.editorconfig" Link=".editorconfig" />
  </ItemGroup>

	<ItemGroup>
		<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.3" />
		<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="6.0.3" />
		<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.3" />
		<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.3" />
		<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.3">
			<PrivateAssets>all</PrivateAssets>
			<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
		</PackageReference>
		<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="NModbus4.NetCore" Version="2.0.1" />
		<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="6.0.1" />
	</ItemGroup>

	<ItemGroup>
	  <None Update="VariableNode.json">
	    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
	  </None>
	</ItemGroup>


</Project>

通信库:

using Modbus.Device;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using thinger.DataConvertLib;

namespace EF6Demon
{
   
   
    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;
        }
    }
}

主程序:

using Microsoft.Extensions.Configuration;
using thinger.DataConvertLib;

namespace EF6Demon
{
   
   
    public partial class FrmMain : Form
    {
   
   
        public FrmMain()
        {
   
   
            InitializeComponent();
            this.Load += FrmMain_Load;
        }

        private ModelsResponsitory dbContext = new ModelsResponsitory();
        private ConfigurationBuilder cfgBuilder = new ConfigurationBuilder();
        private IConfigurationRoot configRoot;
        private CancellationTokenSource cts = new CancellationTokenSource();
        ushort[] res;
        string iAddress = "0";
        string iLenth; //寄存器个数
        private List<float> floatList = new List<float>();
        private CancellationTokenSource cts1 = new CancellationTokenSource();

        InsertDataSQLite objInsert = new InsertDataSQLite(10000);//10秒1次
        private NModBusHelper objTcp;


        private void FrmMain_Load(object? sender, EventArgs e)
        {
   
   
            //读取IP;
            cfgBuilder.AddJsonFile("VariableNode.json", optional: true, reloadOnChange: true);
            this.configRoot = cfgBuilder.Build();
            CommonMethods.Ip = configRoot.GetSection("NodeClass:ModbusNode:ServerURL").Value;
            CommonMethods.Port = configRoot.GetSection("NodeClass:ModbusNode:Port").Value;
            CommonMethods.VarNum = configRoot.GetSection("NodeClass:ModbusNode:VarNum").Value;
            //读取点表信息
            //for (int i = 0; i < int.Parse(CommonMethods.VarNum); i++)
            //{
   
   
            //    Variable variable = configRoot.GetSection($"NodeClass:ModbusNode:ModbusGroup:Variable:{i}").Get<Variable>();
            //    CommonMethods.AllVarList.Add(variable);
            //}
            this.iLenth = configRoot.GetSection("NodeClass:ModbusNode:ModbusGroup:Length").Value;
            CommonMethods.ModbusTCPList = dbContext.GetAllVariable();

            foreach (var item in CommonMethods.ModbusTCPList)
            {
   
   
                foreach (var item1 in item.ModbusNodes)
                {
   
   
                    foreach (var item2 in item1.ModbusGroups)
                    {
   
   
                        CommonMethods.AllVarList.AddRange(item2.Variables);
                    }
                }
            }

            InsertDataSQLite objInsert = new InsertDataSQLite(10000);//10秒1次
            ModbusTCPInitialInfo();
            Communication();
        }

        private void Communication()
        {
   
   
            if (CommonMethods.ModbusTCPList.Count() > 0)
            {
   
   
                foreach (var t in CommonMethods.ModbusTCPList)
                {
   
   
                    foreach (var dev in t.ModbusNodes)
                    {
   
   
                        if (bool.Parse(dev.IsActive))
                        {
   
   
                            Task.Run(async () =>
                            {
   
   
                                while (!cts1.IsCancellationRequested)
                                {
   
   
                                    if (CommonMethods.IsConnected)
                                    {
   
   
                                        await Task.Delay(500);
                                        foreach (var gp in dev.ModbusGroups)
                                        {
   
   
                                            if (bool.Parse(gp.IsActive))
                                            {
   
   
                                                //读取数据
                                                byte[] res = null;
                                                if (int.Parse(gp.StoreArea) == 40000)
                                                {
   
   
                                                    res = objTcp.ReadKeepRegByteArr(gp.Start, gp.Length);
                                                }

                                                if (res != null && res.Length == int.Parse(gp.Length) * 2)
                                                {
   
   
                                                    CommonMethods.ErrorTimes = 0;
                                                    foreach (var variable in gp.Variables)
                                                    {
   
   
                                                        if (VerifyModbusAddress(false, variable.VarAddress, out int start, out int offset))
                                                        {
   
   
                                                            start -= int.Parse(gp.Start);
                                                            start *= 2;
                                                            // ABCD = 0,BADC = 1, CDAB = 2, DCBA = 3,
                                                            switch (variable.VarType
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潘诺西亚的火山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值