This commit is contained in:
@@ -5,6 +5,7 @@ using Sunny.UI;
|
|||||||
//using RecordDateView;
|
//using RecordDateView;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO.Ports;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Reflection.Metadata;
|
using System.Reflection.Metadata;
|
||||||
@@ -292,49 +293,49 @@ namespace 头罩视野.Views
|
|||||||
|
|
||||||
//读取灯泡的数据
|
//读取灯泡的数据
|
||||||
|
|
||||||
private async Task ReadLightBarData()
|
//private async Task ReadLightBarData()
|
||||||
{
|
//{
|
||||||
if (_modbusMaster == null || !ModbusHelper.TcpClient.Connected)
|
// if (_modbusMaster == null || !ModbusHelper.TcpClient.Connected)
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
try
|
// try
|
||||||
{
|
// {
|
||||||
ushort[] registers = await _modbusMaster.ReadHoldingRegistersAsync(1, 350, 15);
|
// ushort[] registers = await _modbusMaster.ReadHoldingRegistersAsync(1, 350, 15);
|
||||||
var tempList = new List<int>(240); // 240 是预期长度
|
// var tempList = new List<int>(240); // 240 是预期长度
|
||||||
|
|
||||||
foreach (ushort reg in registers)
|
// foreach (ushort reg in registers)
|
||||||
{
|
// {
|
||||||
for (int bit = 0; bit < 16; bit++)
|
// for (int bit = 0; bit < 16; bit++)
|
||||||
{
|
// {
|
||||||
int lightBit = (reg & (1 << bit)) != 0 ? 1 : 0;
|
// int lightBit = (reg & (1 << bit)) != 0 ? 1 : 0;
|
||||||
|
|
||||||
if (tbTest.Content.ToString() == "空白测试")
|
// if (tbTest.Content.ToString() == "空白测试")
|
||||||
{
|
// {
|
||||||
lightBit = 1;
|
// lightBit = 1;
|
||||||
|
|
||||||
if (tempList.Where(s => s == 1).Count() > 194)
|
// if (tempList.Where(s => s == 1).Count() > 194)
|
||||||
{
|
// {
|
||||||
lightBit = 0;
|
// lightBit = 0;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
tempList.Add(lightBit);
|
// tempList.Add(lightBit);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
lock (_lock)
|
// lock (_lock)
|
||||||
{
|
// {
|
||||||
DataList.Clear();
|
// DataList.Clear();
|
||||||
DataList.AddRange(tempList.Cast<dynamic>());
|
// DataList.AddRange(tempList.Cast<dynamic>());
|
||||||
}
|
// }
|
||||||
|
|
||||||
System.Diagnostics.Debug.WriteLine($"灯条二进制数据总长度:{DataList.Count}");
|
// System.Diagnostics.Debug.WriteLine($"灯条二进制数据总长度:{DataList.Count}");
|
||||||
}
|
// }
|
||||||
catch (Exception ex)
|
// catch (Exception ex)
|
||||||
{
|
// {
|
||||||
Console.WriteLine($"灯条数据读取失败:{ex.Message}");
|
// Console.WriteLine($"灯条数据读取失败:{ex.Message}");
|
||||||
// 出错时不清空 DataList,保留旧数据
|
// // 出错时不清空 DataList,保留旧数据
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
private async void Timer_Tick(object sender, EventArgs e)
|
private async void Timer_Tick(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
@@ -401,6 +402,7 @@ namespace 头罩视野.Views
|
|||||||
//计算
|
//计算
|
||||||
private async Task calCurrentangle()
|
private async Task calCurrentangle()
|
||||||
{
|
{
|
||||||
|
|
||||||
await ReadLightBarData();
|
await ReadLightBarData();
|
||||||
|
|
||||||
int[] lightData;
|
int[] lightData;
|
||||||
@@ -415,17 +417,30 @@ namespace 头罩视野.Views
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 打印原始数据(假设灯条顺序:上81,中81,下81)
|
||||||
|
void PrintSegment(int[] data, int start, int length, string title)
|
||||||
|
{
|
||||||
|
int end = Math.Min(start + length, data.Length);
|
||||||
|
var values = data.Skip(start).Take(end - start).ToArray();
|
||||||
|
string first20 = string.Join("", values.Take(20));
|
||||||
|
string last20 = string.Join("", values.Skip(Math.Max(0, values.Length - 20)).Take(20));
|
||||||
|
System.Diagnostics.Debug.WriteLine($"{title} (共{values.Length}个): 前20:{first20} ... 后20:{last20}");
|
||||||
|
}
|
||||||
|
|
||||||
|
System.Diagnostics.Debug.WriteLine("=== 原始灯条数据 ===");
|
||||||
|
PrintSegment(lightData, 0, 81, "上爪灯条");
|
||||||
|
PrintSegment(lightData, 81, 81, "下爪灯条");
|
||||||
|
PrintSegment(lightData, 162, 81, "左右灯条");
|
||||||
|
|
||||||
double singleArea = GetArea.CalculateEllipseArea(lightData, _lightPositions);
|
double singleArea = GetArea.CalculateEllipseArea(lightData, _lightPositions);
|
||||||
double bottomViewAngle;
|
double bottomViewAngle;
|
||||||
|
|
||||||
if (tbTest.Content.ToString() == "试样测试")
|
if (tbTest.Content.ToString() == "试样测试")
|
||||||
{
|
{
|
||||||
// 1. 修正下爪灯条的不连续性:填充空洞,使所有1连续
|
// 修正下爪灯条:填充空洞使连续
|
||||||
int startIdx = 81;
|
int startIdx = 81;
|
||||||
int endIdx = 162; // 81+81=162
|
int endIdx = startIdx + 81;
|
||||||
int firstOne = -1;
|
int firstOne = -1, lastOne = -1;
|
||||||
int lastOne = -1;
|
|
||||||
|
|
||||||
// 找到第一个1和最后一个1
|
|
||||||
for (int i = startIdx; i < endIdx; i++)
|
for (int i = startIdx; i < endIdx; i++)
|
||||||
{
|
{
|
||||||
if (lightData[i] == 1)
|
if (lightData[i] == 1)
|
||||||
@@ -434,38 +449,31 @@ namespace 头罩视野.Views
|
|||||||
lastOne = i;
|
lastOne = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果存在1,则将 firstOne 到 lastOne 之间的所有灯设为1(填充空洞)
|
|
||||||
if (firstOne != -1 && lastOne != -1)
|
if (firstOne != -1 && lastOne != -1)
|
||||||
{
|
{
|
||||||
for (int i = firstOne; i <= lastOne; i++)
|
for (int i = firstOne; i <= lastOne; i++)
|
||||||
{
|
|
||||||
lightData[i] = 1;
|
lightData[i] = 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 基于修正后的数据,计算下爪灯条亮灯比例
|
PrintSegment(lightData, 81, 81, "修正后的下爪灯条");
|
||||||
|
|
||||||
|
// 计算亮灯比例
|
||||||
int bottomLampCount = 0;
|
int bottomLampCount = 0;
|
||||||
const int totalBottomLamps = 81;
|
for (int i = startIdx; i < endIdx; i++)
|
||||||
for (int i = 0; i < lightData.Length && i < _lightPositions.Count; i++)
|
if (lightData[i] == 1) bottomLampCount++;
|
||||||
{
|
double ratio = bottomLampCount / 81.0;
|
||||||
var (m, n) = _lightPositions[i];
|
bottomViewAngle = 90.0 * ratio;
|
||||||
if (n == 1 && lightData[i] == 1)
|
// 可选钳位
|
||||||
bottomLampCount++;
|
// if (bottomViewAngle < 52) bottomViewAngle = 52;
|
||||||
}
|
// if (bottomViewAngle > 60) bottomViewAngle = 60;
|
||||||
double ratio = (double)bottomLampCount / totalBottomLamps;
|
|
||||||
double estimatedAngle = 90.0 * ratio; // 全亮时90°,全灭时0°
|
|
||||||
|
|
||||||
// 3. 可选:钳位到52-60(如果需要)
|
|
||||||
// if (estimatedAngle < 52) estimatedAngle = 52;
|
|
||||||
// if (estimatedAngle > 60) estimatedAngle = 60;
|
|
||||||
|
|
||||||
bottomViewAngle = estimatedAngle;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bottomViewAngle = GetArea.CalculateBottomViewAngle(lightData, _lightPositions);
|
bottomViewAngle = GetArea.CalculateBottomViewAngle(lightData, _lightPositions);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
System.Diagnostics.Debug.WriteLine($"角度: {dqangle.Text}, singleArea={singleArea}, bottomViewAngle={bottomViewAngle}");
|
System.Diagnostics.Debug.WriteLine($"角度: {dqangle.Text}, singleArea={singleArea}, bottomViewAngle={bottomViewAngle}");
|
||||||
|
|
||||||
@@ -526,6 +534,7 @@ namespace 头罩视野.Views
|
|||||||
xfsyarea.Text = maxBottomViewAngle.ToString("0");
|
xfsyarea.Text = maxBottomViewAngle.ToString("0");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//数据共享
|
//数据共享
|
||||||
private async void ShowAreaData()
|
private async void ShowAreaData()
|
||||||
@@ -944,6 +953,115 @@ namespace 头罩视野.Views
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private IModbusMaster _serialMaster;
|
||||||
|
|
||||||
|
private void InitSerialModbus()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 请根据实际 COM 口和参数修改
|
||||||
|
string portName = "COM3"; // 实际串口号
|
||||||
|
int baudRate = 9600;
|
||||||
|
Parity parity = Parity.None;
|
||||||
|
int dataBits = 8;
|
||||||
|
StopBits stopBits = StopBits.One;
|
||||||
|
|
||||||
|
var serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
|
||||||
|
if (!serialPort.IsOpen)
|
||||||
|
serialPort.Open();
|
||||||
|
|
||||||
|
_serialMaster = ModbusSerialMaster.CreateRtu(serialPort);
|
||||||
|
|
||||||
|
// 推荐加上超时,避免卡死
|
||||||
|
_serialMaster.Transport.Retries = 2;
|
||||||
|
_serialMaster.Transport.ReadTimeout = 500;
|
||||||
|
_serialMaster.Transport.WriteTimeout = 500;
|
||||||
|
|
||||||
|
System.Diagnostics.Debug.WriteLine($"RS485 串口 {portName} 初始化成功");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"串口初始化失败:{ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ReadLightBarData()
|
||||||
|
{
|
||||||
|
// ===================== 最小修改,不丢次 =====================
|
||||||
|
if (_serialMaster == null)
|
||||||
|
{
|
||||||
|
InitSerialModbus(); // 立即初始化,不跳过本次
|
||||||
|
}
|
||||||
|
if (_serialMaster == null) return; // 真的失败才退出
|
||||||
|
// ==========================================================
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte slaveId = 1;
|
||||||
|
|
||||||
|
var allLights = new List<int>();
|
||||||
|
|
||||||
|
// 通道一:10001~10081
|
||||||
|
bool[] ch1 = await _serialMaster.ReadInputsAsync(slaveId, 0, 81);
|
||||||
|
allLights.AddRange(ch1.Select(b => b ? 1 : 0));
|
||||||
|
|
||||||
|
// 通道二:10097~10177
|
||||||
|
bool[] ch2 = await _serialMaster.ReadInputsAsync(slaveId, 96, 81);
|
||||||
|
allLights.AddRange(ch2.Select(b => b ? 1 : 0));
|
||||||
|
|
||||||
|
// 通道三
|
||||||
|
bool[] s1 = await _serialMaster.ReadInputsAsync(slaveId, 192, 8);
|
||||||
|
bool[] s2 = await _serialMaster.ReadInputsAsync(slaveId, 208, 16);
|
||||||
|
bool[] s3 = await _serialMaster.ReadInputsAsync(slaveId, 224, 16);
|
||||||
|
bool[] s4 = await _serialMaster.ReadInputsAsync(slaveId, 240, 1);
|
||||||
|
bool[] s5 = await _serialMaster.ReadInputsAsync(slaveId, 256, 16);
|
||||||
|
bool[] s6 = await _serialMaster.ReadInputsAsync(slaveId, 272, 16);
|
||||||
|
bool[] s7 = await _serialMaster.ReadInputsAsync(slaveId, 288, 8);
|
||||||
|
|
||||||
|
allLights.AddRange(s1.Select(b => b ? 1 : 0));
|
||||||
|
allLights.AddRange(s2.Select(b => b ? 1 : 0));
|
||||||
|
allLights.AddRange(s3.Select(b => b ? 1 : 0));
|
||||||
|
allLights.AddRange(s4.Select(b => b ? 1 : 0));
|
||||||
|
allLights.AddRange(s5.Select(b => b ? 1 : 0));
|
||||||
|
allLights.AddRange(s6.Select(b => b ? 1 : 0));
|
||||||
|
allLights.AddRange(s7.Select(b => b ? 1 : 0));
|
||||||
|
|
||||||
|
int total = 81 + 81 + 8 + 16 + 16 + 1 + 16 + 16 + 8;
|
||||||
|
if (allLights.Count != total)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine($"灯条数据总数错误:{allLights.Count},预期 {total}");
|
||||||
|
}
|
||||||
|
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
DataList.Clear();
|
||||||
|
if (tbTest.Content.ToString()=="空白测试")
|
||||||
|
{
|
||||||
|
allLights.ForEach(s =>
|
||||||
|
{
|
||||||
|
int item = 1;
|
||||||
|
DataList.Add(item);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
DataList.AddRange(allLights.Cast<dynamic>());
|
||||||
|
}
|
||||||
|
|
||||||
|
int onCount = DataList.Count(s => s == 1);
|
||||||
|
System.Diagnostics.Debug.WriteLine($"当前亮灯数量:{onCount}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"灯条数据读取失败:{ex.Message}");
|
||||||
|
System.Diagnostics.Debug.WriteLine(ex.StackTrace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user