2026-01-07 13:42:17 +08:00
|
|
|
|
using Modbus.Device;
|
|
|
|
|
|
using Modbus;
|
|
|
|
|
|
using Sunny.UI;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Threading;
|
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
|
|
|
|
|
|
|
namespace 全自动水压检测仪
|
|
|
|
|
|
{
|
|
|
|
|
|
public class Function
|
|
|
|
|
|
{
|
|
|
|
|
|
ModbusMaster master;
|
|
|
|
|
|
IModbusMaster modbusMaster;
|
|
|
|
|
|
DataChange dc = new DataChange();
|
|
|
|
|
|
public enum ButtonType
|
|
|
|
|
|
{
|
|
|
|
|
|
复归型,
|
|
|
|
|
|
切换型,
|
|
|
|
|
|
置位型,
|
|
|
|
|
|
复位型
|
|
|
|
|
|
}
|
|
|
|
|
|
public enum DataType
|
|
|
|
|
|
{
|
|
|
|
|
|
整形,
|
|
|
|
|
|
浮点型
|
|
|
|
|
|
}
|
|
|
|
|
|
public Function(ModbusMaster master_in)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.master = master_in;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Function(IModbusMaster modbusMaster)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.modbusMaster = modbusMaster;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void BtnClickFunction(ButtonType buttonType, ushort address)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (buttonType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case ButtonType.复归型:
|
|
|
|
|
|
master.WriteSingleCoil(1, address, true);
|
|
|
|
|
|
Thread.Sleep(100);
|
|
|
|
|
|
master.WriteSingleCoil(1, address, false);
|
|
|
|
|
|
Thread.Sleep(100);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ButtonType.切换型:
|
|
|
|
|
|
if (master.ReadCoils(1, address, 1)[0])
|
|
|
|
|
|
{
|
|
|
|
|
|
master.WriteSingleCoil(1, address, false); Thread.Sleep(100);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{ master.WriteSingleCoil(1, address, true); Thread.Sleep(100); }
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ButtonType.置位型:
|
|
|
|
|
|
master.WriteSingleCoil(1, address, true);
|
|
|
|
|
|
Thread.Sleep(100);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ButtonType.复位型:
|
|
|
|
|
|
master.WriteSingleCoil(1, address, false);
|
|
|
|
|
|
Thread.Sleep(100);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
MessageBox.Show("操作失败!" + "\n" + "\n" + ex.Message, "错误");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void BtnClickFunctionForNew(ButtonType buttonType, ushort address)
|
|
|
|
|
|
{
|
2026-02-04 12:51:01 +08:00
|
|
|
|
int maxRetries = 3;
|
|
|
|
|
|
int retryCount = 0;
|
2026-02-09 19:13:20 +08:00
|
|
|
|
|
2026-02-04 12:51:01 +08:00
|
|
|
|
while (retryCount < maxRetries)
|
2026-01-07 13:42:17 +08:00
|
|
|
|
{
|
2026-02-04 12:51:01 +08:00
|
|
|
|
try
|
2026-01-07 13:42:17 +08:00
|
|
|
|
{
|
2026-02-04 12:51:01 +08:00
|
|
|
|
switch (buttonType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case ButtonType.复归型:
|
|
|
|
|
|
modbusMaster.WriteSingleCoil(1, address, true);
|
|
|
|
|
|
Thread.Sleep(100);
|
|
|
|
|
|
modbusMaster.WriteSingleCoil(1, address, false);
|
|
|
|
|
|
Thread.Sleep(100);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ButtonType.切换型:
|
|
|
|
|
|
bool currentState = false;
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
// 尝试读取当前状态
|
|
|
|
|
|
bool[] coils = modbusMaster.ReadCoils(1, address, 1);
|
|
|
|
|
|
if (coils != null && coils.Length > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
currentState = coils[0];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception readEx)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 如果读取失败,默认写入true(开启状态)
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine($"[Function] 读取地址{address}失败,使用默认值: {readEx.Message}");
|
|
|
|
|
|
}
|
2026-02-09 19:13:20 +08:00
|
|
|
|
|
2026-02-04 12:51:01 +08:00
|
|
|
|
// 写入相反的状态
|
|
|
|
|
|
modbusMaster.WriteSingleCoil(1, address, !currentState);
|
|
|
|
|
|
Thread.Sleep(100);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ButtonType.置位型:
|
|
|
|
|
|
modbusMaster.WriteSingleCoil(1, address, true);
|
|
|
|
|
|
Thread.Sleep(100);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ButtonType.复位型:
|
|
|
|
|
|
modbusMaster.WriteSingleCoil(1, address, false);
|
|
|
|
|
|
Thread.Sleep(100);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2026-02-09 19:13:20 +08:00
|
|
|
|
|
2026-02-04 12:51:01 +08:00
|
|
|
|
// 操作成功,退出重试循环
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (SlaveException slaveEx)
|
|
|
|
|
|
{
|
|
|
|
|
|
retryCount++;
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine($"[Function] Modbus从站异常 (尝试 {retryCount}/{maxRetries}): {slaveEx.Message}");
|
2026-02-09 19:13:20 +08:00
|
|
|
|
|
2026-02-04 12:51:01 +08:00
|
|
|
|
if (retryCount >= maxRetries)
|
|
|
|
|
|
{
|
|
|
|
|
|
MessageBox.Show($"操作失败!\n\nModbus从站错误: {slaveEx.SlaveExceptionCode}\n{slaveEx.Message}", "错误");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2026-02-09 19:13:20 +08:00
|
|
|
|
|
2026-02-04 12:51:01 +08:00
|
|
|
|
// 等待后重试
|
|
|
|
|
|
Thread.Sleep(200);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
retryCount++;
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine($"[Function] 操作失败 (尝试 {retryCount}/{maxRetries}): {ex.Message}");
|
2026-02-09 19:13:20 +08:00
|
|
|
|
|
2026-02-04 12:51:01 +08:00
|
|
|
|
if (retryCount >= maxRetries)
|
|
|
|
|
|
{
|
|
|
|
|
|
MessageBox.Show("操作失败!" + "\n" + "\n" + ex.Message, "错误");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2026-02-09 19:13:20 +08:00
|
|
|
|
|
2026-02-04 12:51:01 +08:00
|
|
|
|
// 等待后重试
|
|
|
|
|
|
Thread.Sleep(200);
|
2026-01-07 13:42:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
public void WriteToPLC(string inPutValue, ushort address, DataType dataType)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (dataType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case DataType.浮点型:
|
|
|
|
|
|
double value = inPutValue.ToDouble();
|
|
|
|
|
|
if (UIInputDialog.ShowInputDoubleDialog(ref value, UIStyle.Inherited, desc: "请输入值", showMask: false))
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
master.WriteMultipleRegisters(1, address, dc.SplitFloatToUShortArray((float)value));
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DataType.整形:
|
|
|
|
|
|
int value_int = inPutValue.ToInt();
|
|
|
|
|
|
if (UIInputDialog.ShowInputIntegerDialog(ref value_int, UIStyle.Inherited, desc: "请输入数据:"))
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
master.WriteMultipleRegisters(1, address, dc.intToushorts(value_int));
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
MessageBox.Show("操作失败!" + "\n" + "\n" + ex.Message, "错误");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-09 19:13:20 +08:00
|
|
|
|
public void WriteToPLCForNew(string inPutValue, ushort address, DataType dataType, bool isok = false, float max = 0, float min = 0)
|
2026-01-07 13:42:17 +08:00
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
//KeyboardHelper.ShowSoftKeyboard();
|
|
|
|
|
|
switch (dataType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case DataType.浮点型:
|
|
|
|
|
|
double value = inPutValue.ToDouble();
|
|
|
|
|
|
|
|
|
|
|
|
if (UIInputDialog.ShowInputDoubleDialog(ref value, UIStyle.Inherited, desc: "请输入值", showMask: false))
|
|
|
|
|
|
{
|
2026-02-09 19:13:20 +08:00
|
|
|
|
if (isok && value > max || value < min)
|
2026-01-07 13:42:17 +08:00
|
|
|
|
{
|
|
|
|
|
|
MessageBox.Show("数据不正确");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
modbusMaster.WriteMultipleRegisters(1, address, dc.SplitFloatToUShortArray((float)value));
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DataType.整形:
|
|
|
|
|
|
int value_int = inPutValue.ToInt();
|
2026-02-09 19:13:20 +08:00
|
|
|
|
|
2026-01-07 13:42:17 +08:00
|
|
|
|
if (UIInputDialog.ShowInputIntegerDialog(ref value_int, UIStyle.Inherited, desc: "请输入数据:"))
|
|
|
|
|
|
{
|
2026-02-09 19:13:20 +08:00
|
|
|
|
if (isok)
|
|
|
|
|
|
{
|
|
|
|
|
|
value_int = value_int * 10;
|
|
|
|
|
|
}
|
2026-01-07 13:42:17 +08:00
|
|
|
|
modbusMaster.WriteMultipleRegisters(1, address, dc.intToushorts(value_int));
|
|
|
|
|
|
//if (isok)
|
|
|
|
|
|
//{ modbusMaster.WriteSingleCoil(1, 25, true); }
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//KeyboardHelper.HideSoftKeyboard();
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
MessageBox.Show("操作失败!" + "\n" + "\n" + ex.Message, "错误");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void WriteToPLCForNew(string inPutValue, ushort address, DataType dataType, int d)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
//KeyboardHelper.ShowSoftKeyboard();
|
|
|
|
|
|
switch (dataType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case DataType.浮点型:
|
|
|
|
|
|
double value = inPutValue.ToDouble();
|
|
|
|
|
|
|
|
|
|
|
|
if (UIInputDialog.ShowInputDoubleDialog(ref value, UIStyle.Inherited, d, desc: "请输入值", showMask: false))
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
modbusMaster.WriteMultipleRegisters(1, address, dc.SplitFloatToUShortArray((float)value));
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DataType.整形:
|
|
|
|
|
|
int value_int = inPutValue.ToInt();
|
|
|
|
|
|
if (UIInputDialog.ShowInputIntegerDialog(ref value_int, UIStyle.Inherited, desc: "请输入数据:"))
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
modbusMaster.WriteMultipleRegisters(1, address, dc.intToushorts(value_int));
|
|
|
|
|
|
//if (isok)
|
|
|
|
|
|
//{ modbusMaster.WriteSingleCoil(1, 25, true); }
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//KeyboardHelper.HideSoftKeyboard();
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
MessageBox.Show("操作失败!" + "\n" + "\n" + ex.Message, "错误");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|