Files
2026-01-15 16:20:14 +08:00

491 lines
16 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Modbus.Device;
using Sunny.UI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.IO.Ports;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using .Data;
namespace
{
public partial class ManualDebugForm : UIForm
{
#region
private TcpClient _tcpClient => ModbusResourceManager.Instance.TcpClient;
private IModbusMaster _modbusMaster => ModbusResourceManager.Instance.ModbusMaster;
#endregion
Function ma;
DataChange c = new DataChange();
private System.Windows.Forms.Timer _readTimer;
private bool _isManualInput = false;
public ManualDebugForm()
{
InitializeComponent();
InitComboBoxPattern();
InitTimer();
}
private System.Windows.Forms.Timer InitTimer()
{
var timer = new System.Windows.Forms.Timer()
{
Interval = 500
};
timer.Tick += async (s, e) =>
{
if (!_isManualInput && _modbusMaster != null)
{
try
{
await ReadTestParametersAsync();
}
catch { }
}
};
timer.Start();
return timer;
}
private async System.Threading.Tasks.Task ReadTestParametersAsync()
{
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
{
return;
}
try
{
ushort[] Ray = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 250, 2)
);
if (Ray != null && Ray.Length >= 2)
{
float Value = c.UshortToFloat(Ray[1], Ray[0]);
this.Invoke(new Action(() => uiTextBox1.Text = Value.ToString("F1")));
}
}
catch (Exception ex)
{
this.Invoke(new Action(() =>
Debug.WriteLine($"读取系数失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)));
}
try
{
bool[] registers1 = await Task.Run(async () =>
{
if (_modbusMaster == null)
return null;
return await _modbusMaster?.ReadCoilsAsync(1, 20, 1);
});
if (registers1 != null && registers1.Length >= 1)
{
bool value = registers1[0];
this.Invoke(new Action(() =>
{
if (value)
{
uiLight3.State = UILightState.On;
}
else
{
uiLight3.State = UILightState.Off;
}
}));
}
}
catch (Exception ex)
{
Debug.WriteLine($"读取状态失败: {ex.Message}");
}
try
{
ushort[] Ray2 = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 102, 2)
);
if (Ray2 != null && Ray2.Length >= 2)
{
float Value2 = c.UshortToFloat(Ray2[1], Ray2[0]);
this.Invoke(new Action(() => uiLabel33.Text = Value2.ToString("F1")));
}
}
catch (Exception ex)
{
this.Invoke(new Action(() =>
Debug.WriteLine($"读取系数失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)));
}
}
private void ManualDebugForm_Load(object sender, EventArgs e)
{
string plcIp = "192.168.1.10";
bool initSuccess = Data.ModbusResourceManager.Instance.Init(plcIp, 502);
if (!initSuccess)
{
MessageBox.Show("连接Modbus服务器失败", "错误");
this.Close();
return;
}
// 检查连接状态
if (_tcpClient == null || !_tcpClient.Connected)
{
MessageBox.Show("Modbus连接异常", "错误");
this.Close();
return;
}
ma = new Function(_modbusMaster);
//_readTimer = InitTimer();
//if (_modbusMaster != null)
//{
// _readTimer.Start();
//}
_modbusMaster?.WriteSingleRegister(1, 2, 0);
this.FormClosed += (s, args) =>
{
// 当子窗体关闭时,显示主窗体
Application.OpenForms["MainForm"]?.Show();
};
initPort();
uiComboBox1.SelectedIndex = 0;
}
private void InitComboBoxPattern()
{
// 清空原有选项(可选,避免重复添加)
//Combox_pattern.Items.Clear();
// 定义需要添加的选项数组
string[] options = {
"环境空气 (21%)",
"富氧环境 (60%)",
"富氧环境 (98%)",
"无氧环境/灭火 (0%)"
};
uiComboBox1.Items.AddRange(options);
}
private void ManualDebugForm_FormClosed(object sender, FormClosedEventArgs e)
{
foreach (Form form in Application.OpenForms)
{
if (form.Name == "MainForm" || form.Text.Contains("主界面"))
{
form.Show();
form.Activate(); // 激活窗体
break;
}
}
Disconnect();
}
private void uiButton5_Click(object sender, EventArgs e)
{
this.Close();//返回主页面
}
private void ToggleButtonWithText(UIButton button, ref bool state, string onText, string offText)
{
state = !state;
button.ForeColor = state ? Color.Red : Color.White;
button.Text = state ? onText : offText;
}
bool isbt1on = false;
//bool isbt4on = false;
bool isbt2on=false;
bool isbt3on = false;
#region
private void uiButton1_Click(object sender, EventArgs e)
{
ToggleButtonWithText(uiButton1, ref isbt1on, "混氧中", "手动混氧");
ma?.BtnClickFunctionForNew(Function.ButtonType., 101);//混氧开关
}
private void uiButton4_Click(object sender, EventArgs e)
{
//ToggleButtonWithText(uiButton4, ref isbt4on, "光斑运行中", "⚫ 光斑开关");
ma?.BtnClickFunctionForNew(Function.ButtonType., 250);//光斑开关
}
private void uiButton2_Click(object sender, EventArgs e)
{
ToggleButtonWithText(uiButton2, ref isbt2on, "开灯中", "💡 灯开关");
ma?.BtnClickFunctionForNew(Function.ButtonType., 11);//灯开关
}
private void uiButton3_Click(object sender, EventArgs e)
{
ToggleButtonWithText(uiButton3, ref isbt3on, "灭火中", "🚨 灭火");
ma?.BtnClickFunctionForNew(Function.ButtonType., 99);//灭火
}
#endregion
private void uiComboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
ushort selectedIndex = ushort.Parse(uiComboBox1.SelectedIndex.ToString());
_modbusMaster?.WriteSingleRegister(1, 10, selectedIndex);//下拉框
}
private void uiTextBox1_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox1.Text.Trim(), 250, Function.DataType.);
}
private void ManualDebugForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (_readTimer != null)
{
_readTimer.Stop();
_readTimer.Dispose();
}
}
private string _serialBuffer = "";
SerialPort serialPort = null;
private System.Windows.Forms.Timer _powerMeterTimer;
private readonly object _serialLock = new object();
private bool _isSerialPortAvailable = false;
private void initPort()
{
lock (_serialLock)
{
try
{
// 创建串口对象
serialPort = new SerialPort();
serialPort.PortName = "COM2";
serialPort.BaudRate = 38400;
serialPort.DataBits = 8;
serialPort.Parity = Parity.None;
serialPort.StopBits = StopBits.One;
serialPort.NewLine = "\r\n";
// 设置数据接收事件
serialPort.DataReceived += SerialPort_DataReceived;
serialPort.Open();
_isSerialPortAvailable = true;
_powerMeterTimer = new System.Windows.Forms.Timer();
_powerMeterTimer.Interval = 200; // 100ms读取一次
_powerMeterTimer.Tick += PowerMeterTimer_Tick;
_powerMeterTimer.Start();
//SendCommand("S01");
}
catch (Exception ex)
{
MessageBox.Show($"串口连接失败:{ex.Message}");
_isSerialPortAvailable = false;
return;
}
}
}
// 串口数据接收事件
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
if (serialPort == null || !serialPort.IsOpen) return;
string data = serialPort.ReadExisting();
_serialBuffer += data; // 添加到缓冲区
// 检查是否有完整的行(以\r\n结尾
int newLineIndex;
while ((newLineIndex = _serialBuffer.IndexOf("\r\n")) >= 0)
{
// 提取一行完整数据
string line = _serialBuffer.Substring(0, newLineIndex);
// 移除已处理的部分
_serialBuffer = _serialBuffer.Substring(newLineIndex + 2);
if (!string.IsNullOrEmpty(line))
{
this.Invoke(new Action(() =>
{
ProcessPowerMeterData(line);
}));
}
}
}
catch (Exception ex)
{
Debug.WriteLine($"串口数据接收错误: {ex.Message}");
}
}
private void ProcessPowerMeterData(string data)
{
try
{
if (string.IsNullOrEmpty(data)) return;
string trimmedLine = data.Trim();
Debug.WriteLine($"处理完整数据行: '{trimmedLine}'");
// 处理功率值(浮点数)
if (double.TryParse(trimmedLine, NumberStyles.Float, CultureInfo.InvariantCulture, out double powerValue))
{
if (powerValue < 1000) // 功率值通常小于1000W
{
uiTextBox5.Text = $"{powerValue:F3} W";
_waitingResponse = false; // 收到响应,可以发送下一个命令
}
}
// S01命令的响应可能是空的但我们也需要处理
else if (string.IsNullOrEmpty(trimmedLine))
{
Debug.WriteLine("收到空响应可能是S01的响应");
_waitingResponse = false; // 收到响应
}
}
catch (Exception ex)
{
Debug.WriteLine($"处理功率计数据错误: {ex.Message}");
_waitingResponse = false; // 出错也重置标志
}
}
private int _commandCounter = 0;
private bool _waitingResponse = false; // 添加这个变量
private void PowerMeterTimer_Tick(object sender, EventArgs e)
{
if (_isSerialPortAvailable && serialPort != null && serialPort.IsOpen && !_waitingResponse)
{
if (_commandCounter == 0)
{
SendCommand("GD"); // 读取功率
}
else if (_commandCounter == 1)
{
SendCommand("GSC0"); // 读取校准系数
}
_waitingResponse = true; // 标记为等待响应
_commandCounter++;
if (_commandCounter >= 2) _commandCounter = 0; // 2个命令循环去掉了S01
}
}
// 发送命令到功率计
private void SendCommand(string command)
{
try
{
if (serialPort == null || !serialPort.IsOpen) return;
lock (_serialLock)
{
string fullCommand = command.ToUpper() + "\r\n";
serialPort.Write(fullCommand);
Debug.WriteLine($"发送命令: {command}");
// 超时保护2秒
Task.Delay(2000).ContinueWith(t =>
{
if (_waitingResponse)
{
Debug.WriteLine($"命令超时重置: {command}");
_waitingResponse = false;
}
});
}
}
catch (Exception ex)
{
Debug.WriteLine($"发送命令失败: {ex.Message}");
_waitingResponse = false; // 出错时重置
}
}
private void Disconnect()
{
_isSerialPortAvailable = false;
if (_powerMeterTimer != null)
{
_powerMeterTimer.Stop();
_powerMeterTimer.Dispose();
_powerMeterTimer = null;
}
try
{
if (serialPort != null && serialPort.IsOpen)
{
SendCommand("S00"); // 停止连续输出
}
}
catch { }
Task.Run(() =>
{
lock (_serialLock)
{
try
{
if (serialPort != null)
{
if (serialPort.IsOpen)
{
serialPort.Close();
}
serialPort.Dispose();
serialPort = null;
}
//WriteToLog("功率计已断开连接");
}
catch (Exception ex)
{
//WriteToLog($"断开连接异常:{ex.Message}");
}
}
});
}
}
}