#:package System.IO.Ports@10.0.8 #:property LangVersion=latest #:property Nullable=enable using System; using System.Linq; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using System.IO.Ports; namespace ResponseTester { class Program { private static int spamCounter = 2048; static private Dictionary commands = Enumerable.Range(1, spamCounter).ToDictionary(i => $"{i}:ping\n", i => DateTime.MaxValue); static private Dictionary responses = new Dictionary(); static private void SerialReader(SerialPort serialPort, CancellationToken ct) { var responseCounter = 0; var timeout = DateTime.Now.AddSeconds(10); while (!ct.IsCancellationRequested && responseCounter < spamCounter && DateTime.Now < timeout) { try { var response = serialPort.ReadLine(); responses[response] = DateTime.Now; Console.WriteLine($"Received response: {response.Trim()}"); responseCounter++; } catch (TimeoutException) { // Ignore timeout exceptions } } } static void Main(string[] args) { Console.WriteLine("Starting response tester..."); var portName = "COM30"; var baudrate = 115200; using var serialPort = new SerialPort(portName, baudrate, Parity.None, 8, StopBits.One); serialPort.ReadTimeout = 100; serialPort.DtrEnable = true; // ← neu serialPort.RtsEnable = true; // ← neu (manche Stacks brauchen es) serialPort.NewLine = "\n"; // ← neu, sonst erwartet ReadLine "\r\n" try { serialPort.Open(); } catch (Exception ex) { Console.WriteLine($"Failed to open serial port: {ex.Message}"); return; } CancellationTokenSource cts = new(); var task = Task.Run(() => SerialReader(serialPort, cts.Token), cts.Token); var burst = 16; var counter = 0; foreach(var command in commands.Keys.ToList()) { serialPort.Write(command); commands[command] = DateTime.Now; Console.WriteLine($"Sent command: {command.Trim()}"); counter++; if (counter % burst == 0) { Thread.Sleep(10); } } task.Wait(); cts.Dispose(); var latencies = new List(); foreach(var command in commands) { var prefix = command.Key.Split(':')[0] + ":"; var response = responses.Keys.FirstOrDefault(r => r.StartsWith(prefix)); if (response != null) { var latency = responses[response] - command.Value; latencies.Add(latency); Console.WriteLine($"Command: {command.Key.Trim()} | Response: {response.Trim()} | Latency: {latency.TotalMilliseconds} ms"); } else Console.WriteLine($"Command: {command.Key.Trim()} | Response: No response received"); } var averageLatency = latencies.Count > 0 ? TimeSpan.FromMilliseconds(latencies.Average(l => l.TotalMilliseconds)) : TimeSpan.Zero; Console.WriteLine($"Average Latency: {averageLatency.TotalMilliseconds} ms"); } } }