better connection controls

This commit is contained in:
nikzori
2024-11-11 10:43:58 +03:00
parent d2c4dc3ec3
commit b5dbd8fc9c
4 changed files with 451 additions and 73 deletions

223
Form1.cs
View File

@@ -12,17 +12,27 @@ using System.Drawing.Drawing2D;
using System.Threading;
using System.Runtime;
using System.Web;
using System.Windows.Forms.Automation;
using System.Diagnostics;
namespace Gidrolock_Modbus_Scanner
{
public partial class App : Form
{
public static int[] BaudRate = new int[]
{
110, 300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 76800, 115200, 230300, 460800, 921600
};
public static int[] DataBits = new int[] { 7, 8 };
int offset = 0;
byte[] data = new byte[255];
byte[] message = new byte[255];
public bool isAwaitingResponse = false;
public bool isProcessingResponse = false;
public short[] res = new short[12];
public SerialPort port = new SerialPort();
public int expectedLength = 0;
public App()
{
@@ -35,10 +45,45 @@ namespace Gidrolock_Modbus_Scanner
CBox_Function.Items.Add("02 - Read Discrete Input");
CBox_Function.Items.Add("03 - Read Holding Register");
CBox_Function.Items.Add("04 - Read Input Register");
CBox_Function.Items.Add("05 - Write Single Coil");
CBox_Function.Items.Add("06 - Write Single Holding Register");
CBox_Function.Items.Add("0F - Write Multiple Coils");
CBox_Function.Items.Add("10 - Write Multiple Registers");
CBox_Function.SelectedItem = CBox_Function.Items[0];
CBox_BaudRate.Items.Add("110");
CBox_BaudRate.Items.Add("300");
CBox_BaudRate.Items.Add("1200");
CBox_BaudRate.Items.Add("2400");
CBox_BaudRate.Items.Add("4800");
CBox_BaudRate.Items.Add("9600");
CBox_BaudRate.Items.Add("14400");
CBox_BaudRate.Items.Add("19200");
CBox_BaudRate.Items.Add("28800");
CBox_BaudRate.Items.Add("38400");
CBox_BaudRate.Items.Add("57600");
CBox_BaudRate.Items.Add("76800");
CBox_BaudRate.Items.Add("115200");
CBox_BaudRate.Items.Add("230300");
CBox_BaudRate.Items.Add("460800");
CBox_BaudRate.Items.Add("921600");
CBox_BaudRate.SelectedIndex = 5;
CBox_DataBits.Items.Add("7");
CBox_DataBits.Items.Add("8");
CBox_DataBits.SelectedIndex = 1;
CBox_StopBits.Items.Add("Нет");
CBox_StopBits.Items.Add("1");
CBox_StopBits.Items.Add("1.5");
CBox_StopBits.Items.Add("2");
CBox_StopBits.SelectedIndex = 1;
UpDown_RegAddress.Minimum = 0;
UpDown_RegAddress.Maximum = 65536;
UpDown_RegAddress.Maximum = 65535;
UpDown_Value.Minimum = 0;
UpDown_Value.Maximum = 65535; // 2^16
}
void App_FormClosed(object sender, FormClosedEventArgs e)
{
@@ -69,54 +114,85 @@ namespace Gidrolock_Modbus_Scanner
if (UpDown_ModbusID.Value == 0)
MessageBox.Show("Глобальное вещание пока не поддерживается");
try
{
if (port.IsOpen)
port.Close();
port.Handshake = Handshake.None;
port.PortName = CBox_Ports.Text;
port.BaudRate = 9600;
port.Parity = Parity.None;
port.DataBits = 8;
port.StopBits = StopBits.One;
port.ReadTimeout = 1000;
port.WriteTimeout = 1000;
offset = 0;
data = new byte[255];
port.Open();
byte[] message = new byte[8];
Modbus.BuildMessage((byte)UpDown_ModbusID.Value, (byte)(1 + functionCode), address, length, ref message);
string messageParsed = Modbus.ParseByteArray(message);
var send = await Modbus.ReadRegAsync(port, functionCode, (byte)UpDown_ModbusID.Value, address, length);
AddLog("Отправка сообщения: " + messageParsed);
isAwaitingResponse = true;
Task timer = Task.Delay(2000);
await timer.ContinueWith(_ =>
{
if (isAwaitingResponse)
{
MessageBox.Show("Истекло время ожидания ответа.", "Ошибка");
port.Close();
}
});
}
catch (Exception err)
{
// Port Setup
if (port.IsOpen)
port.Close();
MessageBox.Show(err.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
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 = 1000;
port.WriteTimeout = 1000;
offset = 0;
message = new byte[255];
port.Open();
/* - Reading from Registers - */
if (CBox_Function.SelectedIndex < 4)
{
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("Отправка сообщения: " + messageParsed);
isAwaitingResponse = true;
Task timer = Task.Delay(2000);
await timer.ContinueWith(_ =>
{
if (isAwaitingResponse)
{
MessageBox.Show("Истекло время ожидания ответа.", "Ошибка");
port.Close();
}
});
}
catch (Exception err)
{
port.Close();
MessageBox.Show(err.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/* - Writing to Registers - */
else
{
try
{
if (CBox_Function.SelectedIndex < 6) // Single Registers
{
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.WriteSingle(port, functionCode, (byte)UpDown_ModbusID.Value, address, (ushort)UpDown_Value.Value);
}
else // Multiple Registers
{
byte[] request = new byte[(int)UpDown_RegLength.Value * 2 + 6];
}
}
catch (Exception err)
{
port.Close();
MessageBox.Show(err.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private async void ButtonConnect_Click(object sender, EventArgs e)
{
await SendMessageAsync(FunctionCode.HoldingRegister, 128, 1);
AddLog("Попытка подключиться к устройству Gidrolock.");
await SendMessageAsync(FunctionCode.DiscreteInput, 200, 5);
}
void CBox_Ports_Click(object sender, EventArgs e)
@@ -129,23 +205,40 @@ namespace Gidrolock_Modbus_Scanner
{
Console.WriteLine("Data receieved on Serial Port");
isAwaitingResponse = false;
try
{
int len = port.BytesToRead;
Console.WriteLine("Data length: " + len);
port.Read(data, offset, len);
offset += len;
string dataCleaned = Modbus.ParseByteArray(data);
TextBox_Log.Invoke((MethodInvoker)delegate { AddLog("Получен ответ: " + dataCleaned); });
//MessageBox.Show("Получен ответ от устройства: " + dataCleaned, "Успех", MessageBoxButtons.OK);
}
catch (Exception err)
if (!isProcessingResponse)
{
MessageBox.Show(err.Message);
isProcessingResponse = true;
try
{
port.Read(message, 0, 3);
int length = (int)message[2];
for (int i = 0; i < length + 2; i++)
{
port.Read(message, i + 3, 1);
}
byte[] data = new byte[length];
for (int i = 0; i < length; i++)
{
data[i] = message[i + 3];
}
Console.WriteLine("Data: " + Modbus.ParseByteArray(data));
string dataCleaned = Modbus.ParseByteArray(message);
TextBox_Log.Invoke((MethodInvoker)delegate { AddLog("Получен ответ: " + dataCleaned); });
TextBox_Log.Invoke((MethodInvoker)delegate { AddLog("ASCII: " + "wip"); });
//MessageBox.Show("Получен ответ от устройства: " + dataCleaned, "Успех", MessageBoxButtons.OK);
port.DiscardInBuffer();
isProcessingResponse = false;
}
catch (Exception err)
{
MessageBox.Show(err.Message);
}
}
//port.Close();
}
void AddLog(string message)
@@ -161,7 +254,21 @@ namespace Gidrolock_Modbus_Scanner
await SendMessageAsync(functionCode, address, length);
}
private void OnSelectedFunctionChanged(object sender, EventArgs e)
{
if (CBox_Function.SelectedIndex < 4)
UpDown_Value.Enabled = false;
else
{
if (CBox_Function.SelectedIndex == 4 || CBox_Function.SelectedIndex == 6)
UpDown_Value.Maximum = 1;
else UpDown_Value.Maximum = 65535;
UpDown_Value.Enabled = true;
}
}
}
}
public enum FunctionCode { Coil, DiscreteInput, HoldingRegister, InputRegister}
public enum FunctionCode { Coil, DiscreteInput, HoldingRegister, InputRegister, WriteCoil, WriteRegister, WriteMultCoils, WriteMultRegisters };