added manual read requests
This commit is contained in:
80
Modbus.cs
80
Modbus.cs
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user