Przeglądaj źródła

读取照片,初步测试通过

djs 4 miesięcy temu
rodzic
commit
ab9242ce4e
3 zmienionych plików z 86 dodań i 11 usunięć
  1. 1 0
      MV485/MV485.csproj
  2. 39 11
      MV485/helper/XModemReceiver.cs
  3. 46 0
      MV485/uc/UCRunConfig.xaml.cs

+ 1 - 0
MV485/MV485.csproj

@@ -101,6 +101,7 @@
     <Compile Include="helper\RWRunConfig.cs" />
     <Compile Include="helper\SerialHelper.cs" />
     <Compile Include="helper\Tools.cs" />
+    <Compile Include="helper\XModemReceiver.cs" />
     <Compile Include="model\BasicConfig.cs" />
     <Compile Include="model\LogEntry.cs" />
     <Compile Include="model\RunConfig.cs" />

+ 39 - 11
MV485/helper/XModemReceiver.cs

@@ -65,6 +65,7 @@ namespace MV485.helper
                 _isReceiving = true;
                 blResult = ReceiveFile(savePath,fileSize);
             }
+            CloseSerial();
 
             return blResult;
         }
@@ -80,9 +81,12 @@ namespace MV485.helper
                 _serialPort.DiscardInBuffer();
                 //发送NAK请求数据(使用校验和)
                 _serialPort.Write(new byte[] { NAK }, 0, 1);
+                RWLog?.Invoke($"发送NAK: {NAK:X2}");
+                Thread.Sleep(100);
 
                 while (_isReceiving)
                 {
+                    //Thread.Sleep(10);
                     //---开始接收一帧数据---
                     DateTime frameStartTime = DateTime.Now;
                     bool frameReceived = false;
@@ -90,8 +94,17 @@ namespace MV485.helper
                     // 在内部循环中尝试接收完整一帧,2秒内必须完成
                     while (!frameReceived)
                     {
-                        if ((DateTime.Now - frameStartTime).TotalMilliseconds > 2000)
+                        //Thread.Sleep(10);
+                        if ((DateTime.Now - frameStartTime).TotalMilliseconds > FRAME_MAX_MILLISECONDS)
                         {
+                            //int n = _serialPort.Read(data, read, PACKET_SIZE - read);
+                            byte[] tempData = new byte[PACKET_SIZE];
+                            int n = _serialPort.Read(tempData, 0, PACKET_SIZE);
+                            if (n > 0)
+                            {
+                                _message = BitConverter.ToString(tempData, 0, n).Replace("-", " ");
+                                RWLog?.Invoke($"读取到: {_message}");
+                            }
                             RWLog?.Invoke("接收当前帧超时(超过2秒),终止文件接收。");
                             return false;
                         }
@@ -102,6 +115,7 @@ namespace MV485.helper
                         {
                             // 未读取到数据,发送 NAK 重试
                             _serialPort.Write(new byte[] { NAK }, 0, 1);
+                            RWLog?.Invoke($"发送NAK: {NAK:X2}");
                             continue;
                         }
 
@@ -109,17 +123,20 @@ namespace MV485.helper
                         if (b == EOT)
                         {
                             _serialPort.Write(new byte[] { ACK }, 0, 1);
+                            RWLog?.Invoke($"发送ACK: {ACK:X2}");
                             RWLog?.Invoke("文件传输完成");
                             blResult = true;
                             frameReceived = true; // 退出当前帧循环
+                            _isReceiving = false;
                             break;
                         }
 
                         //头标志不是SOH(128字节的xModem的头标志)
                         if (b != SOH)
                         {
+                            RWLog?.Invoke($"收到数据帧头标志错误: 0x{b:X2}");
                             _serialPort.Write(new byte[] { NAK }, 0, 1);
-                            RWLog?.Invoke($"数据帧头标志错误: {b:X2}");
+                            RWLog?.Invoke($"发送NAK: {NAK:X2}");
                             continue;
                         }
 
@@ -129,6 +146,7 @@ namespace MV485.helper
                         if ((blockNum + blockNumComp) != 0xFF)
                         {
                             _serialPort.Write(new byte[] { NAK }, 0, 1);
+                            RWLog?.Invoke($"发送NAK: {NAK:X2}");
                             RWLog?.Invoke("包号补码错误");
                             continue;
                         }
@@ -138,6 +156,7 @@ namespace MV485.helper
                         {
                             RWLog?.Invoke($"重复数据包 #{blockNum},重新发送 ACK");
                             _serialPort.Write(new byte[] { ACK }, 0, 1);
+                            RWLog?.Invoke($"发送ACK: {ACK:X2}");
                             frameReceived = true;
                             break;
                         }
@@ -145,8 +164,9 @@ namespace MV485.helper
                         // 读取 128 字节数据,整个读取也必须在2秒内完成
                         if (blockNum != (blockNumber & 0xFF))
                         {
-                            _serialPort.Write(new byte[] { NAK }, 0, 1);
                             RWLog?.Invoke("包号不符合预期");
+                            _serialPort.Write(new byte[] { NAK }, 0, 1);
+                            RWLog?.Invoke($"发送NAK: {NAK:X2}");                            
                             continue;
                         }
 
@@ -170,6 +190,7 @@ namespace MV485.helper
                         {
                             RWLog?.Invoke("数据包接收超时或不完整");
                             _serialPort.Write(new byte[] { NAK }, 0, 1);
+                            RWLog?.Invoke($"发送NAK: {NAK:X2}");
                             continue;
                         }
 
@@ -184,17 +205,19 @@ namespace MV485.helper
                         //校验和不通过
                         if (checksum != sum)
                         {
-                            _serialPort.Write(new byte[] { NAK }, 0, 1);
                             RWLog?.Invoke($"校验和验证不通过");
+                            _serialPort.Write(new byte[] { NAK }, 0, 1);                            
+                            RWLog?.Invoke($"发送NAK: {NAK:X2}");
                             continue;
                         }
 
-                        // 当前帧数据接收成功
-                        _serialPort.Write(new byte[] { ACK }, 0, 1);
+                        // 当前帧数据接收成功                        
                         dataByteList.AddRange(data);
-                        RWLog?.Invoke($"已接受第{blockNumber}包数据");
+                        //RWLog?.Invoke($"第{blockNumber}包");                                              
                         blockNumber++;
                         frameReceived = true;
+                        _serialPort.Write(new byte[] { ACK }, 0, 1);
+                        //RWLog?.Invoke($"发送ACK: {ACK:X2}");                        
                     }// end of while(!frameReceived)
 
                     //double progress = ((double)dataByteList.Count) / fileSize;
@@ -202,13 +225,14 @@ namespace MV485.helper
                     OnProgress?.Invoke((ushort)dataByteList.Count,fileSize);
 
                     // 如果文件数据已经足够,则退出整体接收循环
-                    if (dataByteList.Count >= fileSize || blResult)
-                        break;
+                    //if (dataByteList.Count >= fileSize || blResult)
+                    //    break;
 
                 }// end of while(_isReceiving)
 
                 //保存文件
-                if (blResult && dataByteList.Count >= fileSize)
+                //if (blResult && dataByteList.Count >= fileSize)
+                if (blResult || dataByteList.Count >= fileSize)
                 {
                     //移除填充的0x1A,因为已经知道文件大小了
                     byte[] fileBytes = new byte[fileSize];
@@ -220,7 +244,11 @@ namespace MV485.helper
                         Directory.CreateDirectory(directory);
                     }
                     File.WriteAllBytes(savePath, fileBytes);
-                    RWLog?.Invoke($"已保存文件{savePath}");                    
+                    RWLog?.Invoke($"已保存文件{savePath}");
+                }
+                else
+                {
+                    RWLog?.Invoke($"未完整接收采样照片");
                 }
             }
             catch(IOException ex)

+ 46 - 0
MV485/uc/UCRunConfig.xaml.cs

@@ -45,6 +45,47 @@ namespace MV485.uc
             _rwRunConfig.RWLog += _rwRunConfig_RWLog;
             _rwRunConfig.SerialConnected += _rwRunConfig_SerialConnected;
             _rwRunConfig.SerialStatusChanged += _rwRunConfig_SerialStatusChanged;
+
+            LoadConfigLog();
+        }
+
+        //读取并加载日志
+        private void LoadConfigLog()
+        {
+            Dispatcher.BeginInvoke(new Action(() =>
+            {
+                LoadLogs();
+            }));
+        }
+
+        private void LoadLogs()
+        {
+            if (!File.Exists(LogFilePath))
+                return;
+
+            _logEntries.Clear(); // 先清空已有的日志记录
+
+            //var lines = File.ReadAllLines("config_log.txt");
+            var lines = File.ReadAllLines(LogFilePath);
+
+            foreach (var line in lines)
+            {
+                var parts = line.Split(new[] { " - " }, 2, StringSplitOptions.None);
+                if (parts.Length == 2)
+                {
+                    _logEntries.Add(new LogEntry { Time = parts[0], Message = parts[1] });
+                }
+            }
+
+            // 更新 ListView
+            lvLogs.ItemsSource = null;
+            lvLogs.ItemsSource = _logEntries;
+
+            // 滚动到最后一条
+            if (_logEntries.Count > 0)
+            {
+                lvLogs.ScrollIntoView(_logEntries[_logEntries.Count - 1]);
+            }
         }
 
         private void _rwRunConfig_RWLog(string message)
@@ -173,6 +214,7 @@ namespace MV485.uc
             {
                 return;
             }
+            imgMeter.Source = null;
 
             ushort imageSize = _rwRunConfig.ReadImageSize(portName, baudrate, devId);
 
@@ -219,6 +261,10 @@ namespace MV485.uc
                 {
                     return receiver.StartReceiveFile(portName, baudrate, ImageFilePath, imageSize);
                 });
+                if (blRecv)
+                {
+                    imgMeter.Source = new BitmapImage(new Uri(ImageFilePath, UriKind.RelativeOrAbsolute));
+                }
             }
             catch { }
             finally