feat: 完成七段数码管后端

This commit is contained in:
2025-08-14 15:21:15 +08:00
parent 0e07a5996a
commit 7bfc362b1f
13 changed files with 189 additions and 58 deletions

View File

@@ -0,0 +1,79 @@
using System.Net;
using DotNext;
using Common;
namespace Peripherals.SevenDigitalTubesClient;
static class SevenDigitalTubesAddr
{
public const UInt32 BASE = 0x0000_0000;
}
public class SevenDigitalTubesCtrl
{
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
readonly int timeout = 500;
readonly int taskID;
readonly int port;
readonly string address;
private IPEndPoint ep;
/// <summary>
/// 初始化七段数码管控制器
/// </summary>
/// <param name="address">七段数码管控制器IP地址</param>
/// <param name="port">七段数码管控制器端口</param>
/// <param name="taskID">任务ID</param>
/// <param name="timeout">超时时间(毫秒)</param>
public SevenDigitalTubesCtrl(string address, int port, int taskID, int timeout = 500)
{
if (timeout < 0)
throw new ArgumentException("Timeout couldn't be negative", nameof(timeout));
this.address = address;
this.port = port;
this.ep = new IPEndPoint(IPAddress.Parse(address), port);
this.taskID = taskID;
this.timeout = timeout;
}
public async ValueTask<Result<byte>> ReadTube(int num)
{
if (num < 0 || num > 31)
throw new ArgumentOutOfRangeException(nameof(num), "Tube number must be between 0 and 31");
var ret = await UDPClientPool.ReadAddr(
this.ep, this.taskID, SevenDigitalTubesAddr.BASE + (UInt32)num, this.timeout);
if (!ret.IsSuccessful)
{
logger.Error($"Read tubes failed: {ret.Error}");
return new(ret.Error);
}
if (ret.Value.Options.Data == null || ret.Value.Options.Data.Length < 4)
return new(new Exception("Data length is too short"));
var data = Number.BytesToUInt32(ret.Value.Options.Data, 0, 4, true).Value;
if ((data >> 8) != num)
{
logger.Error($"Read wrong tube number: {num} != {data >> 8}");
return new(new Exception($"Read wrong tube number: {num} != {data >> 8}"));
}
return (byte)(data & 0xFF);
}
public async ValueTask<Result<byte[]>> ScanTubes()
{
var tubes = new byte[32];
for (int i = 0; i < 32; i++)
{
var ret = await ReadTube(i);
if (!ret.IsSuccessful)
return new(ret.Error);
tubes[i] = ret.Value;
}
return tubes;
}
}