added manual read requests

This commit is contained in:
nikzori
2024-11-05 16:57:05 +03:00
parent 30bd39350b
commit d2c4dc3ec3
4 changed files with 258 additions and 85 deletions

View File

@@ -42,7 +42,7 @@ namespace Gidrolock_Modbus_Scanner
#endregion
#region Build Message
static void BuildMessage(byte address, byte type, ushort start, ushort registers, ref byte[] message)
public static void BuildMessage(byte address, byte type, ushort start, ushort length, ref byte[] message)
{
//Array to receive CRC bytes:
byte[] CRC = new byte[2];
@@ -51,8 +51,8 @@ namespace Gidrolock_Modbus_Scanner
message[1] = type;
message[2] = (byte)(start >> 8);
message[3] = (byte)start;
message[4] = (byte)(registers >> 8);
message[5] = (byte)registers;
message[4] = (byte)(length >> 8);
message[5] = (byte)length;
GetCRC(message, ref CRC);
message[message.Length - 2] = CRC[0];
@@ -62,51 +62,22 @@ namespace Gidrolock_Modbus_Scanner
}
#endregion
#region Check Response
static bool CheckResponse(byte[] response)
{
//Perform a basic CRC check:
byte[] CRC = new byte[2];
GetCRC(response, ref CRC);
if (CRC[0] == response[response.Length - 2] && CRC[1] == response[response.Length - 1])
return true;
else
return false;
}
#endregion
#region Get Response
static void GetResponse(SerialPort port, ref byte[] response)
{
Console.WriteLine("Got response from port");
if (port.BytesToRead == 0)
return;
//There is a bug in .Net 2.0 DataReceived Event that prevents people from using this
//event as an interrupt to handle data (it doesn't fire all of the time). Therefore
//we have to use the ReadByte command for a fixed length as it's been shown to be reliable.
for (int i = 0; i < response.Length; i++)
{
response[i] = (byte)(port.ReadByte());
}
}
#endregion
#region Function 3 - Read Holding Registers
public static async Task<bool> ReadRegAsync(SerialPort port, byte regType, byte address, ushort start, ushort registers)
public static async Task<bool> ReadRegAsync(SerialPort port, FunctionCode functionCode, byte address, ushort start, ushort length)
{
short[] values = new short[8];
//Ensure port is open:
if (port.IsOpen)
{
//Clear in/out buffers:
port.DiscardOutBuffer();
port.DiscardInBuffer();
//Function 3 request is always 8 bytes:
//Read functions are always 8 bytes long
byte[] message = new byte[8];
//Function 3 response buffer:
byte[] response = new byte[5 + 2 * registers];
//Build outgoing modbus message:
BuildMessage(address, (byte)3, start, registers, ref message);
BuildMessage(address, (byte)(1 + (int)functionCode), start, length, ref message);
//Send modbus message to Serial Port:
try
{
@@ -129,6 +100,39 @@ namespace Gidrolock_Modbus_Scanner
}
#endregion
/// <summary>
/// Parses a byte array into a string.
/// </summary>
/// <param name="command"></param>
/// <returns>string</returns>
public static string ParseByteArray(byte[] bytes)
{
int length = bytes.Length - 1;
// snip off the empty bytes at the end
for (int i = length; i >= 0; i--)
{
if (bytes[i] != 0)
{
length = i + 1;
break;
}
}
byte[] res = new byte[length];
for (int i = 0; i < length; i++)
res[i] = bytes[i];
string dataString = BitConverter.ToString(res);
string result = "";
for (int i = 0; i < dataString.Length; i++)
{
if (dataString[i] == '-')
result += " ";
else result += dataString[i];
}
return result;
}
}
}