using NModbus;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BPASmartClient.Modbus
{
public class ModbusRTU
{
#region 参数配置
private static IModbusMaster master;
private static IModbusSerialMaster serialMaster;
private static ModbusFactory factory;
private static SerialPort port;
//写线圈或写寄存器数组
private bool[] coilsBuffer;
private ushort[] registerBuffer;
//功能码
private string functionCode;
//串口参数
private string portName;
private int baudRate;
private Parity parity;
private int dataBits;
private StopBits stopBits;
#endregion
#region 串口配置
///
/// 串口参数获取
///
/// 返回串口配置参数>
public void InitSerialPortParameter(string protName, int bauRate, string currentParity, int dataBits, string currentStopBits)
{
switch (currentParity)
{
case "奇":
parity = Parity.Odd;
break;
case "偶":
parity = Parity.Even;
break;
case "无":
parity = Parity.None;
break;
default:
break;
}
switch (currentStopBits)
{
case "1":
stopBits = StopBits.One;
break;
case "2":
stopBits = StopBits.Two;
break;
default:
break;
}
port = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
//master = factory.CreateMaster()
}
#endregion
#region 串口收/发
public async void ExecuteFunctionRecive(string functionCode, byte slaveAddress, ushort startAddress, ushort numberOfPoints)
{
try
{
if (port.IsOpen == false)
{
port.Open();
}
if (functionCode != null)
{
switch (functionCode)
{
case "01 Read Coils"://读取单个线圈
try
{
coilsBuffer = master.ReadCoils(slaveAddress, startAddress, numberOfPoints);
}
catch (Exception)
{
//MessageBox.Show(e.Message);
break;
}
break;
case "02 Read DisCrete Inputs"://读取输入线圈/离散量线圈
try
{
coilsBuffer = master.ReadInputs(slaveAddress, startAddress, numberOfPoints);
}
catch (Exception)
{
break;
}
break;
case "03 Read Holding Registers"://读取保持寄存
try
{
registerBuffer = master.ReadHoldingRegisters(slaveAddress, startAddress, numberOfPoints);
}
catch (Exception)
{
break;
}
break;
case "04 Read Input Registers"://读取输入寄存器
try
{
registerBuffer = master.ReadInputRegisters(slaveAddress, startAddress, numberOfPoints);
}
catch (Exception)
{
break;
}
break;
default:
break;
}
}
port.Close();
}
catch (Exception ex)
{
port.Close();
}
}
public async void ExecuteFunctionSend(string data, byte slaveAddress, ushort startAddress)
{
try
{
if (port.IsOpen == false)
{
port.Open();
}
if (functionCode != null)
{
switch (functionCode)
{
case "05 Write Single Coil"://写单个线圈
SetWriteParametes(data,true);
await master.WriteSingleCoilAsync(slaveAddress, startAddress, coilsBuffer[0]);
break;
case "06 Write Single Registers"://写单个输入线圈/离散量线圈
SetWriteParametes(data,true);
await master.WriteSingleRegisterAsync(slaveAddress, startAddress, registerBuffer[0]);
break;
case "0F Write Multiple Coils"://写一组线圈
SetWriteParametes(data);
await master.WriteMultipleCoilsAsync(slaveAddress, startAddress, coilsBuffer);
break;
case "10 Write Multiple Registers"://写一组保持寄存器
SetWriteParametes(data);
await master.WriteMultipleRegistersAsync(slaveAddress, startAddress, registerBuffer);
break;
default:
break;
}
}
port.Close();
}
catch (Exception ex)
{
port.Close();
}
}
#endregion
///
/// 设置写参数
///
private void SetWriteParametes(string data,bool isParametes =false)
{
//判断是否写线圈
if (isParametes)
{
string[] strarr = data.Split(' ');
coilsBuffer = new bool[strarr.Length];
//转化为bool数组
for (int i = 0; i < strarr.Length; i++)
{
// strarr[i] == "0" ? coilsBuffer[i] = false : coilsBuffer[i] = true;
if (strarr[i] == "0")
{
coilsBuffer[i] = false;
}
else
{
coilsBuffer[i] = true;
}
}
}
else
{
//转化ushort数组
string[] strarr = data.Split(' ');
registerBuffer = new ushort[strarr.Length];
for (int i = 0; i < strarr.Length; i++)
{
registerBuffer[i] = ushort.Parse(strarr[i]);
}
}
}
}
}