diff --git a/CSI-H238M/CSI-H238M/Models/AppConfig.cs b/CSI-H238M/CSI-H238M/Models/AppConfig.cs
index f4b9666..f423c0d 100644
--- a/CSI-H238M/CSI-H238M/Models/AppConfig.cs
+++ b/CSI-H238M/CSI-H238M/Models/AppConfig.cs
@@ -174,6 +174,9 @@ namespace COFTester.Models
public ushort TestStrokeRegister { get; set; } = 26; // 測試行程 (mm),Float,2個寄存器
public ushort SamplingRateRegister { get; set; } = 28; // 採樣頻率 (Hz),Float,2個寄存器
+ // === 校準寄存器(寫入)===
+ public ushort CalibrationRegister { get; set; } = 1300; // 校準命令寄存器 M1300
+
public int RetryCount { get; set; } = 3; // 重試次數
public int RetryDelay { get; set; } = 500; // 重試延遲(毫秒)
}
@@ -208,6 +211,9 @@ namespace COFTester.Models
public ushort TestStrokeRegister { get; set; } = 26; // 測試行程 (mm),Float,2個寄存器
public ushort SamplingRateRegister { get; set; } = 28; // 採樣頻率 (Hz),Float,2個寄存器
+ // === 校準寄存器(寫入)===
+ public ushort CalibrationRegister { get; set; } = 1300; // 校準命令寄存器 M1300
+
public int RetryCount { get; set; } = 3;
public int RetryDelay { get; set; } = 500;
}
diff --git a/CSI-H238M/CSI-H238M/Models/Model.cs b/CSI-H238M/CSI-H238M/Models/Model.cs
index 81904ed..54d502b 100644
--- a/CSI-H238M/CSI-H238M/Models/Model.cs
+++ b/CSI-H238M/CSI-H238M/Models/Model.cs
@@ -338,6 +338,22 @@ namespace COFTester.Models
void StartAcquisition(TestParameters parameters);
void StopAcquisition();
void ResetSensors();
+
+ ///
+ /// 零點標定
+ ///
+ void ZeroCalibration();
+
+ ///
+ /// 拉力校準
+ ///
+ void ForceCalibration();
+
+ ///
+ /// 復歸
+ ///
+ void ReturnToOrigin();
+
bool IsConnected { get; }
}
diff --git a/CSI-H238M/CSI-H238M/Resources/LanguageResources.cs b/CSI-H238M/CSI-H238M/Resources/LanguageResources.cs
index c500bc0..41809b3 100644
--- a/CSI-H238M/CSI-H238M/Resources/LanguageResources.cs
+++ b/CSI-H238M/CSI-H238M/Resources/LanguageResources.cs
@@ -130,6 +130,10 @@ namespace COFTester.Resources
["CalibrationInstruction"] = "请确保设备已连接,然后执行以下标定步骤:",
["ZeroCalibration"] = "零点标定",
["ZeroCalibrationNote"] = "说明:在无负载状态下执行零点标定,将当前读数设为零点。",
+ ["ForceCalibration"] = "拉力校准",
+ ["ForceCalibrationNote"] = "说明:在已知标准负载下执行拉力校准,校准传感器精度。",
+ ["ReturnToOrigin"] = "复归",
+ ["ReturnToOriginNote"] = "说明:将设备返回到初始位置。",
// 测试参数标签
["SpeedLabel"] = "速度:",
@@ -271,6 +275,10 @@ namespace COFTester.Resources
["CalibrationInstruction"] = "Please ensure the device is connected, then perform the following calibration steps:",
["ZeroCalibration"] = "Zero Calibration",
["ZeroCalibrationNote"] = "Note: Perform zero calibration under no-load condition to set the current reading as zero point.",
+ ["ForceCalibration"] = "Force Calibration",
+ ["ForceCalibrationNote"] = "Note: Perform force calibration under known standard load to calibrate sensor accuracy.",
+ ["ReturnToOrigin"] = "Return to Origin",
+ ["ReturnToOriginNote"] = "Note: Return the device to the initial position.",
// Test Parameter Labels
["SpeedLabel"] = "Speed:",
@@ -406,6 +414,10 @@ namespace COFTester.Resources
public string CalibrationInstruction => GetString("CalibrationInstruction");
public string ZeroCalibration => GetString("ZeroCalibration");
public string ZeroCalibrationNote => GetString("ZeroCalibrationNote");
+ public string ForceCalibration => GetString("ForceCalibration");
+ public string ForceCalibrationNote => GetString("ForceCalibrationNote");
+ public string ReturnToOrigin => GetString("ReturnToOrigin");
+ public string ReturnToOriginNote => GetString("ReturnToOriginNote");
// Test Parameter Labels
public string SpeedLabel => GetString("SpeedLabel");
@@ -542,6 +554,10 @@ namespace COFTester.Resources
OnPropertyChanged(nameof(CalibrationInstruction));
OnPropertyChanged(nameof(ZeroCalibration));
OnPropertyChanged(nameof(ZeroCalibrationNote));
+ OnPropertyChanged(nameof(ForceCalibration));
+ OnPropertyChanged(nameof(ForceCalibrationNote));
+ OnPropertyChanged(nameof(ReturnToOrigin));
+ OnPropertyChanged(nameof(ReturnToOriginNote));
// Test Parameter Labels
OnPropertyChanged(nameof(SpeedLabel));
diff --git a/CSI-H238M/CSI-H238M/Services/ModbusService.cs b/CSI-H238M/CSI-H238M/Services/ModbusService.cs
index 6c56a19..55a5e71 100644
--- a/CSI-H238M/CSI-H238M/Services/ModbusService.cs
+++ b/CSI-H238M/CSI-H238M/Services/ModbusService.cs
@@ -22,6 +22,21 @@ namespace COFTester.Services
Reset = 2
}
+ ///
+ /// Modbus 校準命令枚舉(寄存器 M1300)
+ ///
+ public enum ModbusCalibrationCommand : ushort
+ {
+ /// 無操作
+ None = 0,
+ /// 零點標定
+ ZeroCalibration = 1,
+ /// 拉力校準
+ ForceCalibration = 2,
+ /// 復歸
+ Return = 3
+ }
+
///
/// Modbus 設備狀態枚舉
///
@@ -139,10 +154,72 @@ namespace COFTester.Services
}
}
+ ///
+ /// 零點標定,向 M1300 寫入命令 1
+ ///
+ public virtual void ZeroCalibration()
+ {
+ try
+ {
+ if (_modbusMaster != null && _isConnected)
+ {
+ System.Diagnostics.Debug.WriteLine("[Modbus] 發送零點標定命令 (1) 到 M1300");
+ WriteCalibrationRegisterAsync((ushort)ModbusCalibrationCommand.ZeroCalibration).Wait();
+ }
+ }
+ catch (Exception ex)
+ {
+ OnErrorOccurred($"零點標定失敗: {ex.Message}");
+ }
+ }
+
+ ///
+ /// 拉力校準,向 M1300 寫入命令 2
+ ///
+ public virtual void ForceCalibration()
+ {
+ try
+ {
+ if (_modbusMaster != null && _isConnected)
+ {
+ System.Diagnostics.Debug.WriteLine("[Modbus] 發送拉力校準命令 (2) 到 M1300");
+ WriteCalibrationRegisterAsync((ushort)ModbusCalibrationCommand.ForceCalibration).Wait();
+ }
+ }
+ catch (Exception ex)
+ {
+ OnErrorOccurred($"拉力校準失敗: {ex.Message}");
+ }
+ }
+
+ ///
+ /// 復歸,向 M1300 寫入命令 3
+ ///
+ public virtual void ReturnToOrigin()
+ {
+ try
+ {
+ if (_modbusMaster != null && _isConnected)
+ {
+ System.Diagnostics.Debug.WriteLine("[Modbus] 發送復歸命令 (3) 到 M1300");
+ WriteCalibrationRegisterAsync((ushort)ModbusCalibrationCommand.Return).Wait();
+ }
+ }
+ catch (Exception ex)
+ {
+ OnErrorOccurred($"復歸失敗: {ex.Message}");
+ }
+ }
+
protected abstract Task AcquisitionLoopAsync(TestParameters parameters, CancellationToken token);
protected abstract Task ReadSensorDataAsync();
protected abstract Task WriteControlRegisterAsync(ushort value);
+ ///
+ /// 寫入校準命令到 M1300 寄存器
+ ///
+ protected abstract Task WriteCalibrationRegisterAsync(ushort value);
+
///
/// 寫入測試參數到 PLC 寄存器
///
@@ -392,6 +469,23 @@ namespace COFTester.Services
}
}
+ ///
+ /// 寫入校準命令到 M1300
+ /// 0 = 無操作
+ /// 1 = 零點標定
+ /// 2 = 拉力校準
+ /// 3 = 復歸
+ ///
+ protected override async Task WriteCalibrationRegisterAsync(ushort value)
+ {
+ if (_modbusMaster != null)
+ {
+ await _modbusMaster.WriteSingleRegisterAsync(
+ _config.SlaveId, _config.CalibrationRegister, value);
+ System.Diagnostics.Debug.WriteLine($"[ModbusTCP] 校準寄存器[{_config.CalibrationRegister}] = {value}");
+ }
+ }
+
///
/// 寫入測試參數到 PLC 寄存器
/// 參數映射:
@@ -674,6 +768,23 @@ namespace COFTester.Services
}
}
+ ///
+ /// 寫入校準命令到 M1300
+ /// 0 = 無操作
+ /// 1 = 零點標定
+ /// 2 = 拉力校準
+ /// 3 = 復歸
+ ///
+ protected override async Task WriteCalibrationRegisterAsync(ushort value)
+ {
+ if (_modbusMaster != null)
+ {
+ await _modbusMaster.WriteSingleRegisterAsync(
+ _config.SlaveId, _config.CalibrationRegister, value);
+ System.Diagnostics.Debug.WriteLine($"[ModbusRTU] 校準寄存器[{_config.CalibrationRegister}] = {value}");
+ }
+ }
+
///
/// 寫入測試參數到 PLC 寄存器
///
@@ -957,6 +1068,19 @@ namespace COFTester.Services
}
}
+ ///
+ /// 寫入校準命令到 M1300
+ ///
+ protected override async Task WriteCalibrationRegisterAsync(ushort value)
+ {
+ if (_modbusMaster != null)
+ {
+ await _modbusMaster.WriteSingleRegisterAsync(
+ _config.SlaveId, _config.CalibrationRegister, value);
+ System.Diagnostics.Debug.WriteLine($"[ModbusASCII] 校準寄存器[{_config.CalibrationRegister}] = {value}");
+ }
+ }
+
///
/// 寫入測試參數到 PLC 寄存器
///
@@ -1164,6 +1288,51 @@ namespace COFTester.Services
}
}
+ public void ZeroCalibration()
+ {
+ try
+ {
+ if (_serialPort != null && _isConnected)
+ {
+ _serialPort.WriteLine("ZERO_CAL");
+ }
+ }
+ catch (Exception ex)
+ {
+ OnErrorOccurred($"零點標定失败: {ex.Message}");
+ }
+ }
+
+ public void ForceCalibration()
+ {
+ try
+ {
+ if (_serialPort != null && _isConnected)
+ {
+ _serialPort.WriteLine("FORCE_CAL");
+ }
+ }
+ catch (Exception ex)
+ {
+ OnErrorOccurred($"拉力校準失败: {ex.Message}");
+ }
+ }
+
+ public void ReturnToOrigin()
+ {
+ try
+ {
+ if (_serialPort != null && _isConnected)
+ {
+ _serialPort.WriteLine("RETURN");
+ }
+ }
+ catch (Exception ex)
+ {
+ OnErrorOccurred($"復歸失败: {ex.Message}");
+ }
+ }
+
private async Task AcquisitionLoopAsync(TestParameters parameters, CancellationToken token)
{
try
diff --git a/CSI-H238M/CSI-H238M/Services/Services.cs b/CSI-H238M/CSI-H238M/Services/Services.cs
index 40fade8..533329e 100644
--- a/CSI-H238M/CSI-H238M/Services/Services.cs
+++ b/CSI-H238M/CSI-H238M/Services/Services.cs
@@ -511,5 +511,23 @@ namespace COFTester.Services
{
// 模擬傳感器清零(無實際操作)
}
+
+ public void ZeroCalibration()
+ {
+ // 模擬零點標定(無實際操作)
+ System.Diagnostics.Debug.WriteLine("[Simulated] 零點標定完成");
+ }
+
+ public void ForceCalibration()
+ {
+ // 模擬拉力校準(無實際操作)
+ System.Diagnostics.Debug.WriteLine("[Simulated] 拉力校準完成");
+ }
+
+ public void ReturnToOrigin()
+ {
+ // 模擬復歸(無實際操作)
+ System.Diagnostics.Debug.WriteLine("[Simulated] 復歸完成");
+ }
}
}
diff --git a/CSI-H238M/CSI-H238M/ViewModels/ViewModel.cs b/CSI-H238M/CSI-H238M/ViewModels/ViewModel.cs
index 3ce4d56..fb60cf9 100644
--- a/CSI-H238M/CSI-H238M/ViewModels/ViewModel.cs
+++ b/CSI-H238M/CSI-H238M/ViewModels/ViewModel.cs
@@ -66,6 +66,11 @@ namespace COFTester.ViewModels
OpenConfigCommand = new RelayCommand(OpenConfig);
ClearAllTestsCommand = new RelayCommand(ClearAllTests, () => !_isTesting && TestRecords?.Count > 0);
GenerateReportCommand = new RelayCommand(GenerateReport, () => TestRecords?.Count > 0);
+
+ // 校準命令
+ ZeroCalibrationCommand = new RelayCommand(ZeroCalibration, () => !_isTesting && IsConnected);
+ ForceCalibrationCommand = new RelayCommand(ForceCalibration, () => !_isTesting && IsConnected);
+ ReturnToOriginCommand = new RelayCommand(ReturnToOrigin, () => !_isTesting && IsConnected);
Parameters = _config.DefaultTestParameters ?? new TestParameters();
TestRecords = new ObservableCollection();
@@ -418,6 +423,11 @@ namespace COFTester.ViewModels
public ICommand OpenConfigCommand { get; }
public ICommand ClearAllTestsCommand { get; }
public ICommand GenerateReportCommand { get; }
+
+ // 校準命令
+ public ICommand ZeroCalibrationCommand { get; }
+ public ICommand ForceCalibrationCommand { get; }
+ public ICommand ReturnToOriginCommand { get; }
#endregion
#region Event Handlers
@@ -622,6 +632,111 @@ namespace COFTester.ViewModels
_daqService.ResetSensors();
}
+ ///
+ /// 零點標定 - 向 M1300 寫入命令 1
+ ///
+ private void ZeroCalibration()
+ {
+ try
+ {
+ if (!IsConnected)
+ {
+ StatusMessage = "请先连接设备";
+ MessageBox.Show("请先连接设备后再执行零点标定", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
+ return;
+ }
+
+ StatusMessage = "正在执行零点标定...";
+ _daqService.ZeroCalibration();
+ StatusMessage = "零点标定完成";
+
+ System.Diagnostics.Debug.WriteLine("[ViewModel] 零点标定命令已发送");
+
+ MessageBox.Show("零点标定完成!\n\n当前读数已设为零点。",
+ "标定成功",
+ MessageBoxButton.OK,
+ MessageBoxImage.Information);
+ }
+ catch (Exception ex)
+ {
+ StatusMessage = $"零点标定失败: {ex.Message}";
+ MessageBox.Show($"零点标定时发生错误:\n{ex.Message}",
+ "错误",
+ MessageBoxButton.OK,
+ MessageBoxImage.Error);
+ }
+ }
+
+ ///
+ /// 拉力校准 - 向 M1300 写入命令 2
+ ///
+ private void ForceCalibration()
+ {
+ try
+ {
+ if (!IsConnected)
+ {
+ StatusMessage = "请先连接设备";
+ MessageBox.Show("请先连接设备后再执行拉力校准", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
+ return;
+ }
+
+ StatusMessage = "正在执行拉力校准...";
+ _daqService.ForceCalibration();
+ StatusMessage = "拉力校准完成";
+
+ System.Diagnostics.Debug.WriteLine("[ViewModel] 拉力校准命令已发送");
+
+ MessageBox.Show("拉力校准完成!\n\n传感器已校准。",
+ "校准成功",
+ MessageBoxButton.OK,
+ MessageBoxImage.Information);
+ }
+ catch (Exception ex)
+ {
+ StatusMessage = $"拉力校准失败: {ex.Message}";
+ MessageBox.Show($"拉力校准时发生错误:\n{ex.Message}",
+ "错误",
+ MessageBoxButton.OK,
+ MessageBoxImage.Error);
+ }
+ }
+
+ ///
+ /// 复归 - 向 M1300 写入命令 3
+ ///
+ private void ReturnToOrigin()
+ {
+ try
+ {
+ if (!IsConnected)
+ {
+ StatusMessage = "请先连接设备";
+ MessageBox.Show("请先连接设备后再执行复归", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
+ return;
+ }
+
+ StatusMessage = "正在执行复归...";
+ _daqService.ReturnToOrigin();
+ StatusMessage = "复归完成";
+
+ System.Diagnostics.Debug.WriteLine("[ViewModel] 复归命令已发送");
+
+ MessageBox.Show("复归完成!\n\n设备已返回原点。",
+ "复归成功",
+ MessageBoxButton.OK,
+ MessageBoxImage.Information);
+ }
+ catch (Exception ex)
+ {
+ StatusMessage = $"复归失败: {ex.Message}";
+ MessageBox.Show($"复归时发生错误:\n{ex.Message}",
+ "错误",
+ MessageBoxButton.OK,
+ MessageBoxImage.Error);
+ }
+ }
+
///
/// 添加曲线到图表
///
diff --git a/CSI-H238M/CSI-H238M/Views/CalibrationPage.xaml b/CSI-H238M/CSI-H238M/Views/CalibrationPage.xaml
index 556ab6c..a04a81c 100644
--- a/CSI-H238M/CSI-H238M/Views/CalibrationPage.xaml
+++ b/CSI-H238M/CSI-H238M/Views/CalibrationPage.xaml
@@ -71,7 +71,8 @@
-