feat: 完成七段数码管后端
This commit is contained in:
79
server/src/Peripherals/SevenDigitalTubesClient.cs
Normal file
79
server/src/Peripherals/SevenDigitalTubesClient.cs
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user