2026-04-18 18:14:12 +08:00
|
|
|
|
using Modbus.Device;
|
|
|
|
|
|
using Sunny.UI;
|
|
|
|
|
|
|
|
|
|
|
|
//using RecordDateView;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Net.Sockets;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
using System.Windows;
|
|
|
|
|
|
using System.Windows.Controls;
|
|
|
|
|
|
using System.Windows.Data;
|
|
|
|
|
|
using System.Windows.Documents;
|
|
|
|
|
|
using System.Windows.Input;
|
|
|
|
|
|
using System.Windows.Media;
|
|
|
|
|
|
using System.Windows.Media.Imaging;
|
|
|
|
|
|
using System.Windows.Navigation;
|
|
|
|
|
|
using System.Windows.Shapes;
|
|
|
|
|
|
using System.Windows.Threading;
|
|
|
|
|
|
using 头罩视野.Services;
|
|
|
|
|
|
using 头罩视野.Services.Data;
|
|
|
|
|
|
namespace 头罩视野.Views
|
|
|
|
|
|
{
|
|
|
|
|
|
public partial class PageTest : Page
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
private TcpClient _tcpClient => ModbusResourceManager.Instance.TcpClient;
|
|
|
|
|
|
private IModbusMaster _modbusMaster => ModbusResourceManager.Instance.ModbusMaster;
|
2026-04-20 14:03:01 +08:00
|
|
|
|
DispatcherTimer _timer;
|
2026-04-18 18:14:12 +08:00
|
|
|
|
DataChange c = new DataChange();
|
|
|
|
|
|
Function ma;
|
2026-04-21 10:35:43 +08:00
|
|
|
|
|
2026-04-21 10:19:14 +08:00
|
|
|
|
//// 定时采集用
|
|
|
|
|
|
private DispatcherTimer testTimer;
|
|
|
|
|
|
// 保存上一条数据(用于去重)
|
|
|
|
|
|
private TestDataStore.TestRecord _lastRecord;
|
2026-04-21 10:35:43 +08:00
|
|
|
|
|
2026-04-18 18:14:12 +08:00
|
|
|
|
public PageTest()
|
|
|
|
|
|
{
|
|
|
|
|
|
InitializeComponent();
|
2026-04-21 10:19:14 +08:00
|
|
|
|
|
2026-04-20 14:03:01 +08:00
|
|
|
|
_timer = InitDispatcherTimer();
|
2026-04-21 10:19:14 +08:00
|
|
|
|
// 2. 初始化定时器:500毫秒 执行一次
|
2026-04-21 10:35:43 +08:00
|
|
|
|
|
2026-04-21 10:19:14 +08:00
|
|
|
|
testTimer = new DispatcherTimer();
|
|
|
|
|
|
testTimer.Interval = TimeSpan.FromMilliseconds(500); // 500ms = 0.5秒
|
|
|
|
|
|
testTimer.Tick += Timer_Tick;
|
|
|
|
|
|
|
2026-04-18 18:14:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//复位btn
|
|
|
|
|
|
private void Button_Click_Reset(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.BtnClickFunction(Function.ButtonType.复归型, 90);
|
|
|
|
|
|
}
|
|
|
|
|
|
//左开眼
|
|
|
|
|
|
private void Button_Click_left(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.BtnClickFunction(Function.ButtonType.切换型, 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
//右开眼
|
|
|
|
|
|
private void Button_Click_Right(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.BtnClickFunction(Function.ButtonType.切换型, 1);
|
|
|
|
|
|
}
|
2026-04-20 14:03:01 +08:00
|
|
|
|
//反转
|
2026-04-21 11:15:37 +08:00
|
|
|
|
private bool _isPressing = false;
|
|
|
|
|
|
private async void Button_Click_ResDown(object sender, MouseButtonEventArgs e)
|
2026-04-18 18:14:12 +08:00
|
|
|
|
{
|
2026-04-21 11:15:37 +08:00
|
|
|
|
((Button)sender).CaptureMouse();
|
|
|
|
|
|
_isPressing = true;
|
|
|
|
|
|
await Task.Run(() => {
|
|
|
|
|
|
//重新占位写入
|
|
|
|
|
|
_modbusMaster.WriteSingleCoilAsync(1, 10, true);
|
|
|
|
|
|
Task.Delay(100);
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine("stard1111");
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void Button_Click_ResUp(object sender, MouseButtonEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
((Button)sender).ReleaseMouseCapture();
|
|
|
|
|
|
_isPressing = false;
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine("end1111");
|
|
|
|
|
|
|
2026-04-18 18:14:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
//正转
|
2026-04-21 11:15:37 +08:00
|
|
|
|
private bool _isPressing1 = false;
|
|
|
|
|
|
private async void Button_Click_ForDown(object sender, MouseButtonEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
((Button)sender).CaptureMouse();
|
|
|
|
|
|
_isPressing1 = true;
|
|
|
|
|
|
|
|
|
|
|
|
await Task.Run(() => {
|
|
|
|
|
|
//重新占位写入
|
|
|
|
|
|
_modbusMaster.WriteSingleCoilAsync(1, 11, true);
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine("正传start");
|
|
|
|
|
|
Task.Delay(100);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2026-04-18 18:14:12 +08:00
|
|
|
|
|
2026-04-21 11:15:37 +08:00
|
|
|
|
private void Button_Click_ForUp(object sender, MouseButtonEventArgs e)
|
2026-04-18 18:14:12 +08:00
|
|
|
|
{
|
2026-04-21 11:15:37 +08:00
|
|
|
|
((Button)sender).ReleaseMouseCapture();
|
|
|
|
|
|
|
|
|
|
|
|
_isPressing1 = false;
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine("正传end");
|
2026-04-18 18:14:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-21 11:15:37 +08:00
|
|
|
|
|
2026-04-21 10:19:14 +08:00
|
|
|
|
//测试btn 测试按钮:读取数据,存入共享列表
|
2026-04-18 18:14:12 +08:00
|
|
|
|
private void Button_Click_Test(object sender, RoutedEventArgs e)
|
2026-04-21 10:19:14 +08:00
|
|
|
|
|
2026-04-18 18:14:12 +08:00
|
|
|
|
{
|
2026-04-21 10:19:14 +08:00
|
|
|
|
|
|
|
|
|
|
testTimer.Start();
|
2026-04-18 18:14:12 +08:00
|
|
|
|
ma.BtnClickFunction(Function.ButtonType.复归型, 101);
|
|
|
|
|
|
}
|
2026-04-21 10:19:14 +08:00
|
|
|
|
|
|
|
|
|
|
private async void Timer_Tick(object sender, EventArgs e)
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine("定时器触发了!" + DateTime.Now);
|
|
|
|
|
|
// 调用你原来的读取方
|
|
|
|
|
|
//await ReadAddr262DataAsync();
|
|
|
|
|
|
|
|
|
|
|
|
// 组装当前数据
|
|
|
|
|
|
var data = new TestDataStore.TestRecord
|
|
|
|
|
|
{
|
|
|
|
|
|
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
|
|
|
|
|
Time = DateTime.Now.ToString("HH:mm:ss"),
|
|
|
|
|
|
LeftEyeArea = double.TryParse(zmsyarea.Text, out var l) ? l : 0,
|
|
|
|
|
|
RightEyeArea = double.TryParse(ymsyarea.Text, out var r) ? r : 0,
|
|
|
|
|
|
BinocularArea = double.TryParse(smsyarea.Text, out var b) ? b : 0,
|
|
|
|
|
|
LowerVision = double.TryParse(kbsyarea.Text, out var lv) ? lv : 0,
|
|
|
|
|
|
VisionRetentionRate = double.TryParse(sybhl.Text, out var vr) ? vr : 0
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== 去重判断 ====================
|
|
|
|
|
|
if (_lastRecord != null &&
|
|
|
|
|
|
data.LeftEyeArea == _lastRecord.LeftEyeArea &&
|
|
|
|
|
|
data.RightEyeArea == _lastRecord.RightEyeArea &&
|
|
|
|
|
|
data.BinocularArea == _lastRecord.BinocularArea &&
|
|
|
|
|
|
data.LowerVision == _lastRecord.LowerVision &&
|
|
|
|
|
|
data.VisionRetentionRate == _lastRecord.VisionRetentionRate)
|
|
|
|
|
|
{
|
|
|
|
|
|
return; // 一样就不添加
|
|
|
|
|
|
}
|
|
|
|
|
|
// 不一样 → 插入表格
|
|
|
|
|
|
TestDataStore.AddNewRecord(data);
|
|
|
|
|
|
_lastRecord = data;
|
|
|
|
|
|
}
|
|
|
|
|
|
private void Page_Unloaded(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
testTimer?.Stop();
|
|
|
|
|
|
}
|
2026-04-18 18:14:12 +08:00
|
|
|
|
//停止btn
|
|
|
|
|
|
private void Button_Click_Stop(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
2026-04-21 10:19:14 +08:00
|
|
|
|
testTimer.Stop();
|
|
|
|
|
|
MessageBox.Show("已停止");
|
2026-04-18 18:14:12 +08:00
|
|
|
|
ma.BtnClickFunction(Function.ButtonType.复归型, 103);
|
|
|
|
|
|
}
|
|
|
|
|
|
//打印
|
|
|
|
|
|
|
|
|
|
|
|
private void Button_Click_Print(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
2026-04-20 14:03:01 +08:00
|
|
|
|
|
2026-04-18 18:14:12 +08:00
|
|
|
|
ma.BtnClickFunction(Function.ButtonType.复归型, 103);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
//试样测试
|
|
|
|
|
|
|
|
|
|
|
|
private void RadioButton_Checked(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
ma.BtnClickFunction(Function.ButtonType.切换型, 41);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
private void RadioButton_Unchecked(object sender, RoutedEventArgs e)
|
2026-04-20 14:03:01 +08:00
|
|
|
|
{
|
2026-04-18 18:14:12 +08:00
|
|
|
|
|
|
|
|
|
|
ma.BtnClickFunction(Function.ButtonType.切换型, 41);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
private void Button_Click_home(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
NavigationService.Content = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//读取数据
|
|
|
|
|
|
private DispatcherTimer InitDispatcherTimer()
|
|
|
|
|
|
{
|
|
|
|
|
|
var timer = new DispatcherTimer
|
|
|
|
|
|
{
|
|
|
|
|
|
Interval = TimeSpan.FromMilliseconds(100)
|
|
|
|
|
|
};
|
|
|
|
|
|
timer.Tick += async (s, e) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_modbusMaster != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
await ReadAddr262DataAsync();
|
|
|
|
|
|
}
|
|
|
|
|
|
catch { }
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
return timer;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async System.Threading.Tasks.Task ReadAddr262DataAsync()
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
// 创建任务列表
|
|
|
|
|
|
var tasks = new List<Task>
|
|
|
|
|
|
{
|
|
|
|
|
|
ReadAndUpdateFloatAsync(200, 2, fbspeed, "F2", "°"),
|
|
|
|
|
|
ReadAndUpdateFloatAsync(202, 2, dqangle, "F2", "°"),
|
|
|
|
|
|
ReadAndUpdateFloatAsync(310, 2, zdangle, "F2", "°/S"),
|
|
|
|
|
|
|
|
|
|
|
|
ReadAndUpdateFloatAsync(204, 2, zmsyarea, "F2", "cm²"),
|
|
|
|
|
|
ReadAndUpdateFloatAsync(208, 2, smsyarea, "F2", "cm²"),
|
|
|
|
|
|
ReadAndUpdateFloatAsync(424 ,2, kbsyarea, "F2", "cm²"),
|
|
|
|
|
|
|
|
|
|
|
|
ReadAndUpdateFloatAsync(210 ,2, ymsyarea, "F2", " "),
|
|
|
|
|
|
ReadAndUpdateFloatAsync(206 ,2, xfsyarea, "F2", " "),
|
|
|
|
|
|
ReadAndUpdateFloatAsync(430 ,2, sybhl, "F2", " "),
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
await Task.WhenAll(tasks);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
ShowError($"读取数据失败:{ex.Message}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-04-20 14:03:01 +08:00
|
|
|
|
// 地址, 根据格式显示字符长度 32:2 16:1 ,绑定页面的name 值,F2 保留两位小数,单位
|
2026-04-18 18:14:12 +08:00
|
|
|
|
private async Task ReadAndUpdateFloatAsync(int address, int length, System.Windows.Controls.TextBox control, string format, string unit)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
ushort[] registers = await Task.Run(async () =>
|
|
|
|
|
|
await _modbusMaster.ReadHoldingRegistersAsync(1, (ushort)address, (ushort)length)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (registers != null && registers.Length >= 2)
|
|
|
|
|
|
{
|
|
|
|
|
|
float value = c.UshortToFloat(registers[1], registers[0]);
|
|
|
|
|
|
Dispatcher.Invoke(() => control.Text = value.ToString(format) + unit);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (registers != null && registers.Length >= 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
int value = registers[0];
|
|
|
|
|
|
Dispatcher.Invoke(() => control.Text = value.ToString(format) + unit);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine($"读取地址{address}失败:{ex.Message}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async Task ReadAndUpdateFloatAsync(int address, int length, System.Windows.Controls.TextBlock control, string format, string unit)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
ushort[] registers = await Task.Run(async () =>
|
|
|
|
|
|
await _modbusMaster.ReadHoldingRegistersAsync(1, (ushort)address, (ushort)length)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (registers != null && registers.Length >= 2)
|
|
|
|
|
|
{
|
|
|
|
|
|
float value = c.UshortToFloat(registers[1], registers[0]);
|
|
|
|
|
|
Dispatcher.Invoke(() => control.Text = value.ToString(format) + unit);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (registers != null && registers.Length >= 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
int value = registers[0];
|
|
|
|
|
|
Dispatcher.Invoke(() => control.Text = value.ToString(format) + unit);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine($"读取地址{address}失败:{ex.Message}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async Task ReadAndUpdateIntAsync(int address, int length, System.Windows.Controls.Control control, string format)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
ushort[] registers = await Task.Run(() =>
|
|
|
|
|
|
_modbusMaster.ReadHoldingRegisters(1, (ushort)address, (ushort)length)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (registers != null && registers.Length >= 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
int value = registers[0];
|
|
|
|
|
|
Dispatcher.Invoke(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (control is System.Windows.Controls.ContentControl contentControl)
|
|
|
|
|
|
contentControl.Content = value.ToString(format);
|
|
|
|
|
|
else if (control is System.Windows.Controls.TextBox textBox)
|
|
|
|
|
|
textBox.Text = value.ToString(format);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine($"读取地址{address}失败:{ex.Message}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//写入
|
|
|
|
|
|
private void fbspeed_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.WriteToPLCForNew(fbspeed.Text.Trim(), 200, Function.DataType.浮点型);
|
|
|
|
|
|
//程序等待50s 在进行
|
|
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
fbspeed.Focus();
|
|
|
|
|
|
}
|
|
|
|
|
|
private void dqangle_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.WriteToPLCForNew(fbspeed.Text.Trim(), 202, Function.DataType.浮点型);
|
|
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
fbspeed.Focus();
|
|
|
|
|
|
}
|
|
|
|
|
|
private void zdangle_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.WriteToPLCForNew(fbspeed.Text.Trim(), 310, Function.DataType.浮点型);
|
|
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
fbspeed.Focus();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//错误信息提示
|
|
|
|
|
|
private void ShowError(string msg) => MessageBox.Show(msg, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
|
|
|
|
private void GoHome(object s, RoutedEventArgs e) => NavigationService.Content = null;
|
|
|
|
|
|
private void GoTest(object s, RoutedEventArgs e) => NavigationService.Content = new Views.PageTest();
|
|
|
|
|
|
private void GoRecord(object s, RoutedEventArgs e) => NavigationService.Content = new Views.RecordDate();
|
|
|
|
|
|
private void GoView(object s, RoutedEventArgs e) => NavigationService.Content = new Views.RecordPage();
|
2026-04-21 10:19:14 +08:00
|
|
|
|
|
2026-04-18 18:14:12 +08:00
|
|
|
|
private void Page_Loaded(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
2026-04-20 14:03:01 +08:00
|
|
|
|
_timer.Start();
|
2026-04-21 11:15:37 +08:00
|
|
|
|
ma = new Function(_modbusMaster);
|
|
|
|
|
|
c = new DataChange();
|
2026-04-18 18:14:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|