jesus christ the serial port in sharp is so clunky
This commit is contained in:
30
Datasheet.Designer.cs
generated
30
Datasheet.Designer.cs
generated
@@ -28,37 +28,43 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
{
|
{
|
||||||
|
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
|
||||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Datasheet));
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Datasheet));
|
||||||
this.listView1 = new System.Windows.Forms.ListView();
|
this.DGV_Device = new System.Windows.Forms.DataGridView();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.DGV_Device)).BeginInit();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
// listView1
|
// DGV_Device
|
||||||
//
|
//
|
||||||
this.listView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
|
||||||
|
this.DGV_Device.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle1;
|
||||||
|
this.DGV_Device.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||||
| System.Windows.Forms.AnchorStyles.Left)
|
| System.Windows.Forms.AnchorStyles.Left)
|
||||||
| System.Windows.Forms.AnchorStyles.Right)));
|
| System.Windows.Forms.AnchorStyles.Right)));
|
||||||
this.listView1.HideSelection = false;
|
this.DGV_Device.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||||
this.listView1.Location = new System.Drawing.Point(12, 137);
|
this.DGV_Device.Location = new System.Drawing.Point(13, 60);
|
||||||
this.listView1.Name = "listView1";
|
this.DGV_Device.MultiSelect = false;
|
||||||
this.listView1.Size = new System.Drawing.Size(716, 301);
|
this.DGV_Device.Name = "DGV_Device";
|
||||||
this.listView1.TabIndex = 0;
|
this.DGV_Device.RowHeadersVisible = false;
|
||||||
this.listView1.UseCompatibleStateImageBehavior = false;
|
this.DGV_Device.Size = new System.Drawing.Size(567, 378);
|
||||||
|
this.DGV_Device.TabIndex = 0;
|
||||||
//
|
//
|
||||||
// Datasheet
|
// Datasheet
|
||||||
//
|
//
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
this.ClientSize = new System.Drawing.Size(740, 450);
|
this.ClientSize = new System.Drawing.Size(592, 450);
|
||||||
this.Controls.Add(this.listView1);
|
this.Controls.Add(this.DGV_Device);
|
||||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||||
this.Name = "Datasheet";
|
this.Name = "Datasheet";
|
||||||
this.Text = "Datasheet";
|
this.Text = "Datasheet";
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.DGV_Device)).EndInit();
|
||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private System.Windows.Forms.ListView listView1;
|
private System.Windows.Forms.DataGridView DGV_Device;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
89
Datasheet.cs
89
Datasheet.cs
@@ -3,7 +3,9 @@ using System.Collections.Generic;
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.IO.Ports;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.Remoting.Messaging;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
@@ -12,31 +14,86 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
{
|
{
|
||||||
public partial class Datasheet : Form
|
public partial class Datasheet : Form
|
||||||
{
|
{
|
||||||
|
int timeout = 3000;
|
||||||
int pollDelay = 250; // delay between each entry poll, ms
|
int pollDelay = 250; // delay between each entry poll, ms
|
||||||
|
byte slaveID;
|
||||||
Device device = App.device;
|
Device device = App.device;
|
||||||
public Datasheet()
|
List<Entry> entries;
|
||||||
|
SerialPort port = App.port;
|
||||||
|
public Datasheet(byte slaveID)
|
||||||
{
|
{
|
||||||
|
this.slaveID = slaveID;
|
||||||
|
entries = device.entries;
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
listView1.AllowColumnReorder = true;
|
|
||||||
listView1.CheckBoxes = true;
|
|
||||||
listView1.FullRowSelect = true;
|
|
||||||
listView1.GridLines = true;
|
|
||||||
|
|
||||||
listView1.Columns.Add("#", -2, HorizontalAlignment.Left);
|
DGV_Device.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
|
||||||
listView1.Columns.Add("Name", -2, HorizontalAlignment.Left);
|
DGV_Device.MultiSelect = false;
|
||||||
listView1.Columns.Add("Value", -2, HorizontalAlignment.Left);
|
DGV_Device.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders;
|
||||||
listView1.Columns.Add("Address", -2, HorizontalAlignment.Left);
|
DGV_Device.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
|
||||||
|
|
||||||
|
DGV_Device.Columns.Add("#", "#");
|
||||||
|
DGV_Device.Columns[0].FillWeight = 20;
|
||||||
|
DGV_Device.Columns.Add("Name", "Имя");
|
||||||
|
DGV_Device.Columns[1].FillWeight = 40;
|
||||||
|
DGV_Device.Columns.Add("Value", "Значение");
|
||||||
|
DGV_Device.Columns[2].FillWeight = 60;
|
||||||
|
DGV_Device.Columns.Add("Address", "Адрес");
|
||||||
|
DGV_Device.Columns[3].FillWeight = 30;
|
||||||
|
DGV_Device.Columns.Add(new DataGridViewCheckBoxColumn());
|
||||||
|
DGV_Device.Columns[4].Name = "Опрос";
|
||||||
|
DGV_Device.Columns[4].FillWeight = 20;
|
||||||
|
|
||||||
for (int i = 0; i < device.entries.Count; i++)
|
for (int i = 0; i < entries.Count; i++)
|
||||||
{
|
{
|
||||||
ListViewItem item = new ListViewItem(i.ToString());
|
DGV_Device.Rows.Add(i.ToString(), entries[i].name, "", entries[i].address);
|
||||||
item.SubItems.Add(device.entries[i].name);
|
}
|
||||||
item.SubItems.Add(" ");
|
Task.Delay(1000).ContinueWith(_ => AutoPollAsync());
|
||||||
item.SubItems.Add(device.entries[i].address.ToString());
|
}
|
||||||
|
|
||||||
listView1.Items.Add(item);
|
public async Task<bool> AutoPollAsync()
|
||||||
|
{
|
||||||
|
port.Open();
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < entries.Count; i++)
|
||||||
|
{
|
||||||
|
if ((bool)DGV_Device.Rows[i].Cells[4].Value)
|
||||||
|
{
|
||||||
|
DGV_Device.Rows[i].Cells[2].Value = await PollForEntry(entries[i]);
|
||||||
|
await Task.Delay(pollDelay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string> PollForEntry(Entry entry)
|
||||||
|
{
|
||||||
|
byte[] result = new byte[] { 0xFF };
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await Modbus.ReadRegAsync(port, slaveID, (FunctionCode)entry.registerType, entry.address, entry.length);
|
||||||
|
var task = Task.Delay(10).ContinueWith(_ =>
|
||||||
|
{
|
||||||
|
result = new byte[port.BytesToRead];
|
||||||
|
port.Read(result, 0, port.BytesToRead);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (await Task.WhenAny(Task.Delay(timeout + 10), task) == task)
|
||||||
|
{
|
||||||
|
if (result.Length > 5)
|
||||||
|
{
|
||||||
|
return Modbus.ByteArrayToString(result);
|
||||||
|
}
|
||||||
|
else return "N/A";
|
||||||
|
}
|
||||||
|
else return "N/A";
|
||||||
|
}
|
||||||
|
catch (Exception err)
|
||||||
|
{
|
||||||
|
MessageBox.Show(err.Message);
|
||||||
|
return "N/A";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
6
Json.cs
6
Json.cs
@@ -25,12 +25,12 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
{
|
{
|
||||||
public string name;
|
public string name;
|
||||||
public RegisterType registerType;
|
public RegisterType registerType;
|
||||||
public int address;
|
public ushort address;
|
||||||
public int length;
|
public ushort length;
|
||||||
public string dataType;
|
public string dataType;
|
||||||
public bool readOnce;
|
public bool readOnce;
|
||||||
|
|
||||||
public Entry(string name, RegisterType registerType, int address, int length, string dataType, bool readOnce)
|
public Entry(string name, RegisterType registerType, ushort address, ushort length, string dataType, bool readOnce)
|
||||||
{
|
{
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.registerType = registerType;
|
this.registerType = registerType;
|
||||||
|
|||||||
59
Main.cs
59
Main.cs
@@ -29,7 +29,7 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
};
|
};
|
||||||
public static int[] DataBits = new int[] { 7, 8 };
|
public static int[] DataBits = new int[] { 7, 8 };
|
||||||
Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
|
Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
|
||||||
int offset = 0;
|
|
||||||
byte[] message = new byte[255];
|
byte[] message = new byte[255];
|
||||||
public bool isAwaitingResponse = false;
|
public bool isAwaitingResponse = false;
|
||||||
public bool isProcessingResponse = false;
|
public bool isProcessingResponse = false;
|
||||||
@@ -38,7 +38,7 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
public int expectedLength = 0;
|
public int expectedLength = 0;
|
||||||
|
|
||||||
public static Device device;
|
public static Device device;
|
||||||
|
#region Initialization
|
||||||
public App()
|
public App()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
@@ -123,7 +123,9 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
Button_Connect.Text = "Найти адрес";
|
Button_Connect.Text = "Найти адрес";
|
||||||
else Button_Connect.Text = "Подключиться";
|
else Button_Connect.Text = "Подключиться";
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
// Send a custom message
|
||||||
async Task SendMessageAsync(FunctionCode functionCode, ushort address, ushort length)
|
async Task SendMessageAsync(FunctionCode functionCode, ushort address, ushort length)
|
||||||
{
|
{
|
||||||
if (CBox_Ports.Text == "")
|
if (CBox_Ports.Text == "")
|
||||||
@@ -131,7 +133,7 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
if (UpDown_ModbusID.Value == 0)
|
if (UpDown_ModbusID.Value == 0)
|
||||||
MessageBox.Show("Глобальное вещание пока не поддерживается");
|
MessageBox.Show("Глобальное вещание пока не поддерживается");
|
||||||
|
|
||||||
// Port Setup
|
/* - Port Setup - */
|
||||||
if (port.IsOpen)
|
if (port.IsOpen)
|
||||||
port.Close();
|
port.Close();
|
||||||
|
|
||||||
@@ -146,21 +148,19 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
port.WriteTimeout = 3000;
|
port.WriteTimeout = 3000;
|
||||||
|
|
||||||
|
|
||||||
offset = 0;
|
|
||||||
message = new byte[255];
|
message = new byte[255];
|
||||||
port.Open();
|
port.Open();
|
||||||
|
|
||||||
|
|
||||||
/* - Reading from Registers - */
|
/* - Reading from Registers - */
|
||||||
if (CBox_Function.SelectedIndex < 4)
|
if (CBox_Function.SelectedIndex < 4)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
byte[] request = new byte[8];
|
|
||||||
Modbus.BuildMessage((byte)UpDown_ModbusID.Value, (byte)(1 + functionCode), address, length, ref request);
|
|
||||||
string messageParsed = Modbus.ParseByteArray(request);
|
|
||||||
|
|
||||||
var send = await Modbus.ReadRegAsync(port, functionCode, (byte)UpDown_ModbusID.Value, address, length);
|
AddLog("Message goes here;");
|
||||||
AddLog("Отправка сообщения: " + messageParsed);
|
|
||||||
|
var send = await Modbus.ReadRegAsync(port, (byte)UpDown_ModbusID.Value, functionCode, address, length);
|
||||||
isAwaitingResponse = true;
|
isAwaitingResponse = true;
|
||||||
Task timer = Task.Delay(port.ReadTimeout);
|
Task timer = Task.Delay(port.ReadTimeout);
|
||||||
await timer.ContinueWith(_ =>
|
await timer.ContinueWith(_ =>
|
||||||
@@ -188,7 +188,7 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
{
|
{
|
||||||
byte[] request = new byte[8];
|
byte[] request = new byte[8];
|
||||||
Modbus.BuildMessage((byte)UpDown_ModbusID.Value, (byte)(1 + functionCode), address, length, ref request);
|
Modbus.BuildMessage((byte)UpDown_ModbusID.Value, (byte)(1 + functionCode), address, length, ref request);
|
||||||
string messageParsed = Modbus.ParseByteArray(request);
|
string messageParsed = Modbus.ByteArrayToString(request);
|
||||||
|
|
||||||
var send = await Modbus.WriteSingle(port, functionCode, (byte)UpDown_ModbusID.Value, address, (ushort)UpDown_Value.Value);
|
var send = await Modbus.WriteSingle(port, functionCode, (byte)UpDown_ModbusID.Value, address, (ushort)UpDown_Value.Value);
|
||||||
}
|
}
|
||||||
@@ -212,9 +212,34 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
MessageBox.Show("Выберите конфигурацию для подключения и опроса устройства.");
|
MessageBox.Show("Выберите конфигурацию для подключения и опроса устройства.");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* - Port Setup - */
|
||||||
|
if (port.IsOpen)
|
||||||
|
port.Close();
|
||||||
|
|
||||||
|
port.Handshake = Handshake.None;
|
||||||
|
port.PortName = CBox_Ports.Text;
|
||||||
|
port.BaudRate = BaudRate[CBox_BaudRate.SelectedIndex];
|
||||||
|
port.Parity = Parity.None;
|
||||||
|
port.DataBits = DataBits[CBox_DataBits.SelectedIndex];
|
||||||
|
port.StopBits = (StopBits)CBox_StopBits.SelectedIndex;
|
||||||
|
|
||||||
|
port.ReadTimeout = 3000;
|
||||||
|
port.WriteTimeout = 3000;
|
||||||
|
|
||||||
|
|
||||||
|
message = new byte[255];
|
||||||
|
port.Open();
|
||||||
|
|
||||||
AddLog("Попытка подключиться к устройству " + device.name);
|
AddLog("Попытка подключиться к устройству " + device.name);
|
||||||
Datasheet datasheet = new Datasheet();
|
try
|
||||||
datasheet.Show();
|
{
|
||||||
|
Datasheet datasheet = new Datasheet((byte)UpDown_ModbusID.Value);
|
||||||
|
datasheet.Show();
|
||||||
|
}
|
||||||
|
catch (Exception err)
|
||||||
|
{
|
||||||
|
MessageBox.Show(err.Message);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
if (Radio_SerialPort.Checked)
|
if (Radio_SerialPort.Checked)
|
||||||
await SendMessageAsync(FunctionCode.InputRegister, 200, 6);
|
await SendMessageAsync(FunctionCode.InputRegister, 200, 6);
|
||||||
@@ -241,7 +266,7 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
await socket.ConnectAsync(ipText, portParsed);
|
await socket.ConnectAsync(ipText, portParsed);
|
||||||
byte[] data = new byte[8];
|
byte[] data = new byte[8];
|
||||||
Modbus.BuildMessage(0x1E, 0x03, 128, 1, ref data);
|
Modbus.BuildMessage(0x1E, 0x03, 128, 1, ref data);
|
||||||
AddLog("Sending to " + ipText + ":" + portText + ":" + Modbus.ParseByteArray(data));
|
AddLog("Sending to " + ipText + ":" + portText + ":" + Modbus.ByteArrayToString(data));
|
||||||
|
|
||||||
// set up an event listener to receive the response
|
// set up an event listener to receive the response
|
||||||
await SocketDataTransfer(data);
|
await SocketDataTransfer(data);
|
||||||
@@ -277,8 +302,8 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
{
|
{
|
||||||
data[i] = message[i + 3];
|
data[i] = message[i + 3];
|
||||||
}
|
}
|
||||||
Console.WriteLine("Data: " + Modbus.ParseByteArray(data));
|
Console.WriteLine("Data: " + Modbus.ByteArrayToString(data));
|
||||||
string dataCleaned = Modbus.ParseByteArray(message);
|
string dataCleaned = Modbus.ByteArrayToString(message);
|
||||||
|
|
||||||
TextBox_Log.Invoke((MethodInvoker)delegate { AddLog("Получен ответ: " + dataCleaned); });
|
TextBox_Log.Invoke((MethodInvoker)delegate { AddLog("Получен ответ: " + dataCleaned); });
|
||||||
TextBox_Log.Invoke((MethodInvoker)delegate { AddLog("ASCII: " + "wip"); });
|
TextBox_Log.Invoke((MethodInvoker)delegate { AddLog("ASCII: " + "wip"); });
|
||||||
@@ -403,4 +428,4 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum FunctionCode { Coil, DiscreteInput, HoldingRegister, InputRegister, WriteCoil, WriteRegister, WriteMultCoils, WriteMultRegisters };
|
public enum FunctionCode { ReadCoil, ReadDiscrete, ReadHolding, ReadInput, WriteCoil, WriteRegister, WriteMultCoils, WriteMultRegisters };
|
||||||
|
|||||||
83
Modbus.cs
83
Modbus.cs
@@ -12,58 +12,30 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
{
|
{
|
||||||
public static class Modbus
|
public static class Modbus
|
||||||
{
|
{
|
||||||
|
|
||||||
#region CRC Computation
|
|
||||||
static void GetCRC(byte[] message, ref byte[] CRC)
|
|
||||||
{
|
|
||||||
//Function expects a modbus message of any length as well as a 2 byte CRC array in which to
|
|
||||||
//return the CRC values:
|
|
||||||
|
|
||||||
ushort CRCFull = 0xFFFF;
|
|
||||||
byte CRCHigh = 0xFF, CRCLow = 0xFF;
|
|
||||||
char CRCLSB;
|
|
||||||
|
|
||||||
for (int i = 0; i < (message.Length) - 2; i++)
|
|
||||||
{
|
|
||||||
CRCFull = (ushort)(CRCFull ^ message[i]);
|
|
||||||
|
|
||||||
for (int j = 0; j < 8; j++)
|
|
||||||
{
|
|
||||||
CRCLSB = (char)(CRCFull & 0x0001);
|
|
||||||
CRCFull = (ushort)((CRCFull >> 1) & 0x7FFF);
|
|
||||||
|
|
||||||
if (CRCLSB == 1)
|
|
||||||
CRCFull = (ushort)(CRCFull ^ 0xA001);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CRC[1] = CRCHigh = (byte)((CRCFull >> 8) & 0xFF);
|
|
||||||
CRC[0] = CRCLow = (byte)(CRCFull & 0xFF);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Build Message
|
#region Build Message
|
||||||
public static void BuildMessage(byte address, byte type, ushort start, ushort length, ref byte[] message)
|
public static byte[] BuildMessage(byte modbusID, byte functionCode, ushort address, ushort length, ref byte[] message)
|
||||||
{
|
{
|
||||||
//Array to receive CRC bytes:
|
//Array to receive CRC bytes:
|
||||||
byte[] CRC = new byte[2];
|
byte[] CRC = new byte[2];
|
||||||
|
|
||||||
message[0] = address;
|
message[0] = modbusID;
|
||||||
message[1] = type;
|
message[1] = functionCode;
|
||||||
message[2] = (byte)(start >> 8);
|
message[2] = (byte)(address >> 8);
|
||||||
message[3] = (byte)start;
|
message[3] = (byte)address;
|
||||||
message[4] = (byte)(length >> 8);
|
message[4] = (byte)(length >> 8);
|
||||||
message[5] = (byte)length;
|
message[5] = (byte)length;
|
||||||
|
|
||||||
GetCRC(message, ref CRC);
|
GetCRC(message, ref CRC);
|
||||||
message[message.Length - 2] = CRC[0];
|
message[message.Length - 2] = CRC[0];
|
||||||
message[message.Length - 1] = CRC[1];
|
message[message.Length - 1] = CRC[1];
|
||||||
string msg = BitConverter.ToString(message);
|
string msg = ByteArrayToString(message);
|
||||||
Console.WriteLine("Message: " + msg);
|
Console.WriteLine("Message: " + msg);
|
||||||
|
return message;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Read Functions
|
#region Read Functions
|
||||||
public static async Task<bool> ReadRegAsync(SerialPort port, FunctionCode functionCode, byte address, ushort start, ushort length)
|
public static async Task<bool> ReadRegAsync(SerialPort port, byte slaveID, FunctionCode functionCode, ushort address, ushort length)
|
||||||
{
|
{
|
||||||
//Ensure port is open:
|
//Ensure port is open:
|
||||||
if (port.IsOpen)
|
if (port.IsOpen)
|
||||||
@@ -76,7 +48,7 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
byte[] message = new byte[8];
|
byte[] message = new byte[8];
|
||||||
|
|
||||||
//Build outgoing modbus message:
|
//Build outgoing modbus message:
|
||||||
BuildMessage(address, (byte)(1 + (int)functionCode), start, length, ref message);
|
BuildMessage(slaveID, (byte)(1 + (int)functionCode), address, length, ref message);
|
||||||
|
|
||||||
//Send modbus message to Serial Port:
|
//Send modbus message to Serial Port:
|
||||||
try
|
try
|
||||||
@@ -142,12 +114,7 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public static string ByteArrayToString(byte[] bytes)
|
||||||
/// 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;
|
int length = bytes.Length - 1;
|
||||||
// snip off the empty bytes at the end
|
// snip off the empty bytes at the end
|
||||||
@@ -175,5 +142,33 @@ namespace Gidrolock_Modbus_Scanner
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region CRC Computation
|
||||||
|
static void GetCRC(byte[] message, ref byte[] CRC)
|
||||||
|
{
|
||||||
|
//Function expects a modbus message of any length as well as a 2 byte CRC array in which to
|
||||||
|
//return the CRC values:
|
||||||
|
|
||||||
|
ushort CRCFull = 0xFFFF;
|
||||||
|
byte CRCHigh = 0xFF, CRCLow = 0xFF;
|
||||||
|
char CRCLSB;
|
||||||
|
|
||||||
|
for (int i = 0; i < (message.Length) - 2; i++)
|
||||||
|
{
|
||||||
|
CRCFull = (ushort)(CRCFull ^ message[i]);
|
||||||
|
|
||||||
|
for (int j = 0; j < 8; j++)
|
||||||
|
{
|
||||||
|
CRCLSB = (char)(CRCFull & 0x0001);
|
||||||
|
CRCFull = (ushort)((CRCFull >> 1) & 0x7FFF);
|
||||||
|
|
||||||
|
if (CRCLSB == 1)
|
||||||
|
CRCFull = (ushort)(CRCFull ^ 0xA001);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CRC[1] = CRCHigh = (byte)((CRCFull >> 8) & 0xFF);
|
||||||
|
CRC[0] = CRCLow = (byte)(CRCFull & 0xFF);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user