|
|
@@ -147,7 +147,7 @@ namespace ModbusDemo.Device |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
/// <summary> |
|
|
|
/// 写入多个线圈操作 |
|
|
@@ -160,7 +160,7 @@ namespace ModbusDemo.Device |
|
|
|
if (!_serialPort.IsOpen) |
|
|
|
{ |
|
|
|
MessageBox.Show("串口没有链接,请先链接"); |
|
|
|
return ; |
|
|
|
return; |
|
|
|
} |
|
|
|
List<byte> sendByteList = new List<byte>(); |
|
|
|
//设置从站地址 |
|
|
@@ -205,12 +205,10 @@ namespace ModbusDemo.Device |
|
|
|
byte[] response = null; |
|
|
|
while (attempt < maxRetries) |
|
|
|
{ |
|
|
|
|
|
|
|
try |
|
|
|
{ |
|
|
|
// 清空接收缓冲区(避免残留数据干扰) |
|
|
|
_serialPort.DiscardInBuffer(); |
|
|
|
|
|
|
|
_serialPort.Write(sendByte, 0, sendByte.Length); |
|
|
|
Thread.Sleep(300); |
|
|
|
response = new byte[_serialPort.BytesToRead]; |
|
|
@@ -219,7 +217,6 @@ namespace ModbusDemo.Device |
|
|
|
{ |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
catch (Exception) |
|
|
|
{ |
|
|
@@ -241,21 +238,18 @@ namespace ModbusDemo.Device |
|
|
|
//判断发送回来的数据是否正确 |
|
|
|
if (CheckData.CheckResponse(response)) |
|
|
|
{ |
|
|
|
if (!CRCUitl.ValidateCRC(response)) |
|
|
|
{ |
|
|
|
MessageBox.Show("0x14:CRC校验错误"); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
public ushort[] ReadRegisters(byte slaveAddress, ushort startAddress, ushort numberOfPoints) |
|
|
|
{ |
|
|
|
ushort[] resultValue = null; |
|
|
|
if (!_serialPort.IsOpen) |
|
|
|
{ |
|
|
|
MessageBox.Show("串口没有链接,请先链接"); |
|
|
|
return null; |
|
|
|
return resultValue; |
|
|
|
} |
|
|
|
List<byte> sendByteList = new List<byte>(); |
|
|
|
//设置从站地址 |
|
|
@@ -275,19 +269,46 @@ namespace ModbusDemo.Device |
|
|
|
sendByteList.Add(resultCRC[1]); |
|
|
|
|
|
|
|
byte[] sendByte = sendByteList.ToArray(); |
|
|
|
if (_serialPort.IsOpen) |
|
|
|
int maxRetries = 3; // 最大重试次数 |
|
|
|
int attempt = 0; |
|
|
|
while (attempt < maxRetries) |
|
|
|
{ |
|
|
|
// 清空接收缓冲区(避免残留数据干扰) |
|
|
|
_serialPort.DiscardInBuffer(); |
|
|
|
|
|
|
|
_serialPort.Write(sendByte, 0, sendByte.Length); |
|
|
|
Thread.Sleep(300); |
|
|
|
byte[] response = new byte[_serialPort.BytesToRead]; |
|
|
|
_serialPort.Read(response, 0, _serialPort.BytesToRead); |
|
|
|
return ParseRegistersresponse(sendByte, response, numberOfPoints); |
|
|
|
try |
|
|
|
{ |
|
|
|
// 清空接收缓冲区(避免残留数据干扰) |
|
|
|
_serialPort.DiscardInBuffer(); |
|
|
|
|
|
|
|
_serialPort.Write(sendByte, 0, sendByte.Length); |
|
|
|
Thread.Sleep(300); |
|
|
|
byte[] response = new byte[_serialPort.BytesToRead]; |
|
|
|
_serialPort.Read(response, 0, _serialPort.BytesToRead); |
|
|
|
if (response[0] == 0x00) |
|
|
|
{ |
|
|
|
continue; |
|
|
|
} |
|
|
|
resultValue = ParseRegistersresponse(sendByte, response, numberOfPoints); |
|
|
|
return resultValue; |
|
|
|
} |
|
|
|
catch (Exception) |
|
|
|
{ |
|
|
|
|
|
|
|
attempt++; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
//将操作失败的指令,插入数据库 |
|
|
|
string RequestStr = ByteArrayToString(sendByte); |
|
|
|
|
|
|
|
ModbusLog m = new ModbusLog(); |
|
|
|
m.OperationType = "读寄存器"; |
|
|
|
m.ResponseData = ""; |
|
|
|
m.RequestData = RequestStr; |
|
|
|
_modbusDbContext.Add(m); |
|
|
|
_modbusDbContext.SaveChanges(); |
|
|
|
return resultValue; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return null; |
|
|
|
} |
|
|
|
public ushort[] ParseRegistersresponse(byte[] sendByte, byte[] response, ushort numberOfPoints) |
|
|
|
{ |
|
|
@@ -302,27 +323,35 @@ namespace ModbusDemo.Device |
|
|
|
_modbusDbContext.SaveChanges(); |
|
|
|
|
|
|
|
//判断发送回来的数据是否正确 |
|
|
|
CheckData.CheckResponse(response); |
|
|
|
if (CheckData.CheckResponse(response)) |
|
|
|
{ |
|
|
|
ushort[] registers = new ushort[numberOfPoints]; |
|
|
|
for (int i = 0; i < numberOfPoints; i++) |
|
|
|
{ |
|
|
|
int pos = 3 + i * 2; |
|
|
|
// 大端序转换 (高位在前) |
|
|
|
registers[i] = (ushort)((response[pos] << 8) | response[pos + 1]); |
|
|
|
} |
|
|
|
|
|
|
|
if (!CRCUitl.ValidateCRC(response)) |
|
|
|
return registers; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
MessageBox.Show("0x14:CRC校验错误"); |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
ushort[] registers = new ushort[numberOfPoints]; |
|
|
|
for (int i = 0; i < numberOfPoints; i++) |
|
|
|
{ |
|
|
|
int pos = 3 + i * 2; |
|
|
|
// 大端序转换 (高位在前) |
|
|
|
registers[i] = (ushort)((response[pos] << 8) | response[pos + 1]); |
|
|
|
} |
|
|
|
|
|
|
|
return registers; |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
public void WriteRegisters(byte slaveAddress, ushort startAddress, ushort[] data) |
|
|
|
{ |
|
|
|
if (!_serialPort.IsOpen) |
|
|
|
{ |
|
|
|
MessageBox.Show("串口没有链接,请先链接"); |
|
|
|
return; |
|
|
|
} |
|
|
|
List<byte> sendByteList = new List<byte>(); |
|
|
|
//设置从站地址 |
|
|
|
sendByteList.Add(slaveAddress); |
|
|
@@ -353,39 +382,52 @@ namespace ModbusDemo.Device |
|
|
|
sendByteList.Add(resultCRC[0]); |
|
|
|
sendByteList.Add(resultCRC[1]); |
|
|
|
|
|
|
|
|
|
|
|
byte[] sendByte = sendByteList.ToArray(); |
|
|
|
if (_serialPort.IsOpen) |
|
|
|
|
|
|
|
|
|
|
|
int maxRetries = 3; // 最大重试次数 |
|
|
|
int attempt = 0; |
|
|
|
byte[] response = null; |
|
|
|
|
|
|
|
while (attempt< maxRetries) |
|
|
|
{ |
|
|
|
// 清空接收缓冲区(避免残留数据干扰) |
|
|
|
_serialPort.DiscardInBuffer(); |
|
|
|
|
|
|
|
_serialPort.Write(sendByte, 0, sendByte.Length); |
|
|
|
Thread.Sleep(300); |
|
|
|
byte[] response = new byte[_serialPort.BytesToRead]; |
|
|
|
_serialPort.Read(response, 0, _serialPort.BytesToRead); |
|
|
|
|
|
|
|
//将操作的指令,插入数据库 |
|
|
|
string RequestStr = ByteArrayToString(sendByte); |
|
|
|
string responseStr = ByteArrayToString(response); |
|
|
|
ModbusLog m = new ModbusLog(); |
|
|
|
m.OperationType = "写寄存器"; |
|
|
|
m.ResponseData = responseStr; |
|
|
|
m.RequestData = responseStr; |
|
|
|
_modbusDbContext.Add(m); |
|
|
|
_modbusDbContext.SaveChanges(); |
|
|
|
|
|
|
|
//判断发送回来的数据是否正确 |
|
|
|
CheckData.CheckResponse(response); |
|
|
|
|
|
|
|
if (!CRCUitl.ValidateCRC(response)) |
|
|
|
try |
|
|
|
{ |
|
|
|
MessageBox.Show("0x14:CRC校验错误"); |
|
|
|
// 清空接收缓冲区(避免残留数据干扰) |
|
|
|
_serialPort.DiscardInBuffer(); |
|
|
|
|
|
|
|
_serialPort.Write(sendByte, 0, sendByte.Length); |
|
|
|
Thread.Sleep(1000); |
|
|
|
response = new byte[_serialPort.BytesToRead]; |
|
|
|
_serialPort.Read(response, 0, _serialPort.BytesToRead); |
|
|
|
if (response[0] != 0x00) |
|
|
|
{ |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
catch (Exception) |
|
|
|
{ |
|
|
|
attempt++; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//将操作的指令,插入数据库 |
|
|
|
string RequestStr = ByteArrayToString(sendByte); |
|
|
|
string responseStr = ByteArrayToString(response); |
|
|
|
ModbusLog m = new ModbusLog(); |
|
|
|
m.OperationType = "写寄存器"; |
|
|
|
m.ResponseData = responseStr; |
|
|
|
m.RequestData = responseStr; |
|
|
|
_modbusDbContext.Add(m); |
|
|
|
_modbusDbContext.SaveChanges(); |
|
|
|
|
|
|
|
//判断发送回来的数据是否正确 |
|
|
|
CheckData.CheckResponse(response); |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static string ByteArrayToString(byte[] byteArray) |
|
|
|
{ |
|
|
|
if (byteArray == null || byteArray.Length == 0) |
|
|
|