Skip to content

Commit

Permalink
v1.8实现NewLife.IoT的控制器层IModbus接口
Browse files Browse the repository at this point in the history
  • Loading branch information
nnhy committed Dec 10, 2023
1 parent c8a1578 commit 30e92a2
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 19 deletions.
2 changes: 1 addition & 1 deletion NewLife.Modbus/Drivers/ModbusDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public override IDictionary<String, Object> Read(INode node, IPoint[] points)
{
seg.Data = Modbus.Read(seg.ReadCode, n.Host, (UInt16)seg.Address, (UInt16)seg.Count)?.ReadBytes();

var x = seg.Data.Join(" ", e => e.ToHex());
//var x = seg.Data.Join(" ", e => e.ToHex());
}
catch (Exception ex)
{
Expand Down
8 changes: 4 additions & 4 deletions NewLife.Modbus/NewLife.Modbus.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<Description>Modbus基础协议,包括ModbusTcp</Description>
<Company>新生命开发团队</Company>
<Copyright>©2002-2023 新生命开发团队</Copyright>
<VersionPrefix>1.7</VersionPrefix>
<VersionPrefix>1.8</VersionPrefix>
<VersionSuffix>$([System.DateTime]::Now.ToString(`yyyy.MMdd`))</VersionSuffix>
<Version>$(VersionPrefix).$(VersionSuffix)</Version>
<FileVersion>$(Version)</FileVersion>
Expand Down Expand Up @@ -37,15 +37,15 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1">
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="NewLife.Core" Version="10.6.2023.1001" />
<PackageReference Include="NewLife.Core" Version="10.6.2023.1201" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="NewLife.IoT" Version="1.9.2023.1001" />
<PackageReference Include="NewLife.IoT" Version="2.0.2023.1210-beta1616" />
</ItemGroup>

<ItemGroup>
Expand Down
3 changes: 2 additions & 1 deletion NewLife.Modbus/Protocols/Modbus.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Runtime.CompilerServices;
using NewLife.Data;
using NewLife.IoT.Controllers;
using NewLife.Log;
using NewLife.Serialization;

Expand All @@ -8,7 +9,7 @@
namespace NewLife.IoT.Protocols;

/// <summary>Modbus协议核心</summary>
public abstract class Modbus : DisposeBase
public abstract class Modbus : DisposeBase, IModbus
{
#region 属性
/// <summary>名称</summary>
Expand Down
129 changes: 129 additions & 0 deletions NewLife.ModbusRTU/Controllers/DefaultSerialPort.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#if !NETFRAMEWORK
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO.Ports;
using NewLife.Data;

namespace NewLife.IoT.Controllers;

/// <summary>默认串口实现</summary>
public class DefaultSerialPort : DisposeBase, ISerialPort
{
/// <summary>串口名</summary>
public String PortName { get; set; } = null!;

/// <summary>波特率</summary>
public Int32 Baudrate { get; set; }

/// <summary>网络超时。发起请求后等待响应的超时时间,默认3000ms</summary>
public Int32 Timeout { get; set; } = 3000;

/// <summary>字节超时。数据包间隔,默认10ms</summary>
public Int32 ByteTimeout { get; set; } = 10;

/// <summary>缓冲区大小。默认256</summary>
public Int32 BufferSize { get; set; } = 256;

private SerialPort? _port;

Check warning on line 27 in NewLife.ModbusRTU/Controllers/DefaultSerialPort.cs

View workflow job for this annotation

GitHub Actions / build-publish

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

/// <summary>销毁</summary>
/// <param name="disposing"></param>
protected override void Dispose(Boolean disposing)
{
base.Dispose(disposing);

_port.TryDispose();
}

/// <summary>打开</summary>
[MemberNotNull(nameof(_port))]
public virtual void Open()
{
if (_port != null) return;

if (PortName.IsNullOrEmpty()) throw new ArgumentNullException(nameof(PortName));
if (Baudrate == 0) Baudrate = 9600;

_port = new SerialPort(PortName, Baudrate)
{
ReadTimeout = Timeout,
WriteTimeout = Timeout
};
_port.Open();
}

/// <summary>发送数据</summary>
/// <param name="buffer">待发送数据</param>
/// <param name="offset">偏移</param>
/// <param name="count">个数</param>
public virtual void Write(Byte[] buffer, Int32 offset, Int32 count)
{
Open();

_port.Write(buffer, offset, count);
}

/// <summary>接收数据</summary>
/// <param name="buffer">接收缓冲区</param>
/// <param name="offset">偏移</param>
/// <param name="count">个数</param>
/// <returns>已接收数据的字节数</returns>
public virtual Int32 Read(Byte[] buffer, Int32 offset, Int32 count)
{
Open();

return _port.Read(buffer, offset, count);
}

/// <summary>调用,发送数据后等待响应</summary>
/// <param name="request">待发送数据</param>
/// <param name="minLength">等待响应数据的最小长度,默认1</param>
/// <returns></returns>
public virtual Packet Invoke(Packet? request, Int32 minLength)

Check warning on line 82 in NewLife.ModbusRTU/Controllers/DefaultSerialPort.cs

View workflow job for this annotation

GitHub Actions / build-publish

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

Check warning on line 82 in NewLife.ModbusRTU/Controllers/DefaultSerialPort.cs

View workflow job for this annotation

GitHub Actions / build-publish

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
{
Open();

if (request != null)
{
// 清空缓冲区
_port.DiscardInBuffer();

if (request.Next == null)
_port.Write(request.Data, request.Offset, request.Count);
else
_port.Write(request.ToArray(), 0, request.Total);

if (ByteTimeout > 10) Thread.Sleep(ByteTimeout);
}

// 串口速度较慢,等待收完数据
WaitMore(_port, minLength);

var buf = new Byte[BufferSize];
var rs = _port.Read(buf, 0, buf.Length);

return new Packet(buf, 0, rs);
}

private void WaitMore(SerialPort sp, Int32 minLength)
{
var count = sp.BytesToRead;
if (count >= minLength) return;

var ms = ByteTimeout > 0 ? ByteTimeout : 10;
var sw = Stopwatch.StartNew();
while (sp.IsOpen && sw.ElapsedMilliseconds < Timeout)
{
//Thread.SpinWait(1);
Thread.Sleep(ms);
if (count != sp.BytesToRead)
{
count = sp.BytesToRead;
if (count >= minLength) break;

//sw.Restart();
}
}
}
}
#endif
16 changes: 11 additions & 5 deletions NewLife.ModbusRTU/NewLife.ModbusRTU.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<Description>串口ModbusRTU协议</Description>
<Company>新生命开发团队</Company>
<Copyright>©2002-2023 新生命开发团队</Copyright>
<VersionPrefix>1.7</VersionPrefix>
<VersionPrefix>1.8</VersionPrefix>
<VersionSuffix>$([System.DateTime]::Now.ToString(`yyyy.MMdd`))</VersionSuffix>
<Version>$(VersionPrefix).$(VersionSuffix)</Version>
<FileVersion>$(Version)</FileVersion>
Expand Down Expand Up @@ -37,18 +37,24 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1">
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="NewLife.Core" Version="10.6.2023.1001" />
<PackageReference Include="NewLife.Core" Version="10.6.2023.1201" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'=='net461'">
<ItemGroup Condition="'$(TargetFramework)'=='net461' or '$(TargetFramework)'=='netstandard2.0' or '$(TargetFramework)'=='netstandard2.1'">
<PackageReference Include="System.IO.Ports" Version="6.0.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'!='net461' and '$(TargetFramework)'!='net45'">
<ItemGroup Condition="'$(TargetFramework)'=='net6.0'">
<PackageReference Include="System.IO.Ports" Version="6.0.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'=='net7.0'">
<PackageReference Include="System.IO.Ports" Version="7.0.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'=='net8.0'">
<PackageReference Include="System.IO.Ports" Version="8.0.0" />
</ItemGroup>

<ItemGroup>
<Content Include="..\Doc\leaf.png" Link="leaf.png" PackagePath="\" />
Expand Down
2 changes: 1 addition & 1 deletion Test/Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="NewLife.Core" Version="10.6.2023.1001" />
<PackageReference Include="NewLife.Core" Version="10.6.2023.1201" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion WinModbus/WinModbus.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="NewLife.Core" Version="10.6.2023.1001" />
<PackageReference Include="NewLife.Core" Version="10.6.2023.1201" />
</ItemGroup>

<ItemGroup>
Expand Down
12 changes: 6 additions & 6 deletions XUnitTest/XUnitTest.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.3" />
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="NewLife.Core" Version="10.6.2023.1001" />
<PackageReference Include="xunit" Version="2.5.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0">
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="NewLife.Core" Version="10.6.2023.1201" />
<PackageReference Include="xunit" Version="2.6.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down

0 comments on commit 30e92a2

Please sign in to comment.