using DeviceCommand.Base; using System; using System.IO.Ports; using System.Threading; using System.Threading.Tasks; namespace DeviceCommand.Devices { /// /// UMC1000 温湿度控制器(RS485) /// public class UMC1000Rtu : ModbusRtu { private readonly byte _slaveId; /// /// 温度测量值 REAL /// private const ushort TemperatureAddress = 150; /// /// 湿度测量值 REAL /// private const ushort HumidityAddress = 152; public UMC1000Rtu( byte slaveId, string portName, int baudRate = 9600, int dataBits = 8, StopBits stopBits = StopBits.One, Parity parity = Parity.None, int readTimeout = 3000, int writeTimeout = 3000) { _slaveId = slaveId; ConfigureDevice( portName, baudRate, dataBits, stopBits, parity, readTimeout, writeTimeout); } /// /// 读取温度 /// public async Task ReadTemperatureAsync( CancellationToken ct = default) { return await ReadFloatAsync( TemperatureAddress, ct); } /// /// 读取湿度 /// public async Task ReadHumidityAsync( CancellationToken ct = default) { return await ReadFloatAsync( HumidityAddress, ct); } /// /// 一次读取温湿度 /// public async Task<(float Temperature, float Humidity)> ReadAllAsync( CancellationToken ct = default) { ushort[] regs = await ReadHoldingRegistersAsync( _slaveId, TemperatureAddress, 4, ct); return ( ToFloat(regs[0], regs[1]), ToFloat(regs[2], regs[3]) ); } private async Task ReadFloatAsync( ushort address, CancellationToken ct) { ushort[] regs = await ReadHoldingRegistersAsync( _slaveId, address, 2, ct); return ToFloat(regs[0], regs[1]); } /// /// 两个寄存器转Float /// private static float ToFloat( ushort highWord, ushort lowWord) { byte[] bytes = { (byte)(highWord >> 8), (byte)highWord, (byte)(lowWord >> 8), (byte)lowWord }; if (BitConverter.IsLittleEndian) Array.Reverse(bytes); return BitConverter.ToSingle(bytes, 0); } } }