From 28c4c7427f46f05e63b764010fc13f687f6df621 Mon Sep 17 00:00:00 2001
From: andrea <2404>
Date: Wed, 24 Dec 2025 16:41:31 +0100
Subject: [PATCH] Aggiungere i file di progetto.
---
OMControl.slnx | 3 +
OMControl/Form1.Designer.cs | 59 +++++++++++++
OMControl/Form1.cs | 46 ++++++++++
OMControl/Form1.resx | 120 ++++++++++++++++++++++++++
OMControl/OMControl.csproj | 15 ++++
OMControl/Program.cs | 17 ++++
OMControl/Serial/SerialDeviceProbe.cs | 112 ++++++++++++++++++++++++
OMControl/Serial/SerialManager.cs | 53 ++++++++++++
OMControl/Serial/SerialPortWatcher.cs | 52 +++++++++++
9 files changed, 477 insertions(+)
create mode 100644 OMControl.slnx
create mode 100644 OMControl/Form1.Designer.cs
create mode 100644 OMControl/Form1.cs
create mode 100644 OMControl/Form1.resx
create mode 100644 OMControl/OMControl.csproj
create mode 100644 OMControl/Program.cs
create mode 100644 OMControl/Serial/SerialDeviceProbe.cs
create mode 100644 OMControl/Serial/SerialManager.cs
create mode 100644 OMControl/Serial/SerialPortWatcher.cs
diff --git a/OMControl.slnx b/OMControl.slnx
new file mode 100644
index 0000000..3f8367c
--- /dev/null
+++ b/OMControl.slnx
@@ -0,0 +1,3 @@
+
+
+
diff --git a/OMControl/Form1.Designer.cs b/OMControl/Form1.Designer.cs
new file mode 100644
index 0000000..99bdfba
--- /dev/null
+++ b/OMControl/Form1.Designer.cs
@@ -0,0 +1,59 @@
+namespace OMControl
+{
+ partial class Form1
+ {
+
+
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ listBoxPorts = new ListBox();
+ SuspendLayout();
+ //
+ // listBoxPorts
+ //
+ listBoxPorts.FormattingEnabled = true;
+ listBoxPorts.Location = new Point(196, 150);
+ listBoxPorts.Name = "listBoxPorts";
+ listBoxPorts.Size = new Size(150, 104);
+ listBoxPorts.TabIndex = 0;
+ //
+ // Form1
+ //
+ AutoScaleDimensions = new SizeF(8F, 20F);
+ AutoScaleMode = AutoScaleMode.Font;
+ ClientSize = new Size(800, 450);
+ Controls.Add(listBoxPorts);
+ Name = "Form1";
+ Text = "Form1";
+ ResumeLayout(false);
+ }
+
+ #endregion
+
+ private ListBox listBoxPorts;
+ }
+}
diff --git a/OMControl/Form1.cs b/OMControl/Form1.cs
new file mode 100644
index 0000000..14c0678
--- /dev/null
+++ b/OMControl/Form1.cs
@@ -0,0 +1,46 @@
+using System.IO.Ports;
+
+namespace OMControl
+{
+ public partial class Form1 : Form
+ {
+ private SerialPortWatcher _watcher;
+ public Form1()
+ {
+ InitializeComponent();
+ this.Load += Form1_Load;
+
+ }
+
+
+ private void Form1_Load(object sender, EventArgs e)
+ {
+ listBoxPorts.Items.Clear();
+ foreach (var p in SerialPort.GetPortNames())
+ listBoxPorts.Items.Add(p);
+
+ // start watcher
+ _watcher = new SerialPortWatcher(1000);
+
+ _watcher.PortsAdded += ports => BeginInvoke(() =>
+ {
+ foreach (var p in ports)
+ if (!listBoxPorts.Items.Contains(p))
+ listBoxPorts.Items.Add(p);
+ });
+
+ _watcher.PortsRemoved += ports => BeginInvoke(() =>
+ {
+ foreach (var p in ports)
+ listBoxPorts.Items.Remove(p);
+ });
+
+ _watcher.Start();
+ }
+ protected override void OnFormClosing(FormClosingEventArgs e)
+ {
+ _watcher?.Dispose();
+ base.OnFormClosing(e);
+ }
+ }
+}
diff --git a/OMControl/Form1.resx b/OMControl/Form1.resx
new file mode 100644
index 0000000..8b2ff64
--- /dev/null
+++ b/OMControl/Form1.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/OMControl/OMControl.csproj b/OMControl/OMControl.csproj
new file mode 100644
index 0000000..80c58a3
--- /dev/null
+++ b/OMControl/OMControl.csproj
@@ -0,0 +1,15 @@
+
+
+
+ WinExe
+ net10.0-windows
+ enable
+ true
+ enable
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OMControl/Program.cs b/OMControl/Program.cs
new file mode 100644
index 0000000..a006931
--- /dev/null
+++ b/OMControl/Program.cs
@@ -0,0 +1,17 @@
+namespace OMControl
+{
+ internal static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ // To customize application configuration such as set high DPI settings or default font,
+ // see https://aka.ms/applicationconfiguration.
+ ApplicationConfiguration.Initialize();
+ Application.Run(new Form1());
+ }
+ }
+}
\ No newline at end of file
diff --git a/OMControl/Serial/SerialDeviceProbe.cs b/OMControl/Serial/SerialDeviceProbe.cs
new file mode 100644
index 0000000..77cfaaa
--- /dev/null
+++ b/OMControl/Serial/SerialDeviceProbe.cs
@@ -0,0 +1,112 @@
+using System;
+using System.Collections.Generic;
+using System.IO.Ports;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+public sealed class SerialDeviceProbe
+{
+ public record ProbeResult(string Port, bool Success, string? DeviceId, byte[]? RawResponse, string? Error);
+
+ // Define known signatures here
+ // Example: response contains ASCII "DEV:XYZ" or starts with 0xAA 0x55 etc.
+ private readonly List<(string Name, Func Match)> _signatures = new();
+
+ public SerialDeviceProbe AddSignature(string name, Func match)
+ {
+ _signatures.Add((name, match));
+ return this;
+ }
+
+ public async Task ProbeAsync(
+ string portName,
+ int baudRate,
+ byte[] probeBytes,
+ int readTimeoutMs = 250,
+ int writeTimeoutMs = 250,
+ int settleDelayMs = 80,
+ int maxReadBytes = 256,
+ CancellationToken ct = default)
+ {
+ try
+ {
+ return await Task.Run(() =>
+ {
+ ct.ThrowIfCancellationRequested();
+
+ using var sp = new SerialPort(portName, baudRate)
+ {
+ ReadTimeout = readTimeoutMs,
+ WriteTimeout = writeTimeoutMs,
+ Encoding = Encoding.ASCII,
+ DtrEnable = true, // often needed for Arduino-like boards
+ RtsEnable = true
+ };
+
+ sp.Open();
+
+ // Some devices reboot on open (Arduino). Give them a moment.
+ Thread.Sleep(settleDelayMs);
+
+ sp.DiscardInBuffer();
+ sp.DiscardOutBuffer();
+
+ sp.Write(probeBytes, 0, probeBytes.Length);
+
+ // Read available bytes up to timeout
+ var buffer = new List(maxReadBytes);
+ var start = Environment.TickCount;
+
+ while (buffer.Count < maxReadBytes && Environment.TickCount - start < readTimeoutMs)
+ {
+ ct.ThrowIfCancellationRequested();
+
+ try
+ {
+ int b = sp.ReadByte(); // blocks until byte or timeout
+ if (b >= 0) buffer.Add((byte)b);
+
+ // Optional: break early if you know response length or terminator
+ // e.g. if buffer ends with '\n'
+ if (buffer.Count >= 2 && buffer[^1] == (byte)'\n') break;
+ }
+ catch (TimeoutException)
+ {
+ break;
+ }
+ }
+
+ var resp = buffer.ToArray();
+ if (resp.Length == 0)
+ return new ProbeResult(portName, false, null, resp, "No response");
+
+ // Identify by signature
+ foreach (var sig in _signatures)
+ {
+ if (sig.Match(resp))
+ return new ProbeResult(portName, true, sig.Name, resp, null);
+ }
+
+ // Unknown but responded
+ return new ProbeResult(portName, true, "Unknown", resp, null);
+
+ }, ct);
+ }
+ catch (Exception ex)
+ {
+ return new ProbeResult(portName, false, null, null, ex.Message);
+ }
+ }
+
+ public async Task ProbeAllAsync(
+ IEnumerable ports,
+ int baudRate,
+ byte[] probeBytes,
+ CancellationToken ct = default)
+ {
+ var tasks = ports.Select(p => ProbeAsync(p, baudRate, probeBytes, ct: ct));
+ return await Task.WhenAll(tasks);
+ }
+}
diff --git a/OMControl/Serial/SerialManager.cs b/OMControl/Serial/SerialManager.cs
new file mode 100644
index 0000000..eaff1fd
--- /dev/null
+++ b/OMControl/Serial/SerialManager.cs
@@ -0,0 +1,53 @@
+using System;
+using System.IO.Ports;
+using System.Text;
+
+public class SerialManager : IDisposable
+{
+ private SerialPort _serialPort;
+
+ public event Action? DataReceived;
+
+ public bool IsOpen => _serialPort?.IsOpen ?? false;
+
+ public SerialManager(string portName, int baudRate)
+ {
+ _serialPort = new SerialPort(portName, baudRate)
+ {
+ Encoding = Encoding.ASCII,
+ NewLine = "\n"
+ };
+
+ _serialPort.DataReceived += OnDataReceived;
+ }
+
+ public void Open()
+ {
+ if (!_serialPort.IsOpen)
+ _serialPort.Open();
+ }
+
+ public void Close()
+ {
+ if (_serialPort.IsOpen)
+ _serialPort.Close();
+ }
+
+ public void Send(string data)
+ {
+ if (_serialPort.IsOpen)
+ _serialPort.WriteLine(data);
+ }
+
+ private void OnDataReceived(object sender, SerialDataReceivedEventArgs e)
+ {
+ string data = _serialPort.ReadLine();
+ DataReceived?.Invoke(data);
+ }
+
+ public void Dispose()
+ {
+ Close();
+ _serialPort.Dispose();
+ }
+}
diff --git a/OMControl/Serial/SerialPortWatcher.cs b/OMControl/Serial/SerialPortWatcher.cs
new file mode 100644
index 0000000..de73894
--- /dev/null
+++ b/OMControl/Serial/SerialPortWatcher.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using System.IO.Ports;
+using System.Linq;
+using System.Timers;
+
+public sealed class SerialPortWatcher : IDisposable
+{
+ private readonly System.Timers.Timer _timer;
+ private HashSet _last = new(StringComparer.OrdinalIgnoreCase);
+
+ public event Action? PortsAdded;
+ public event Action? PortsRemoved;
+
+ public SerialPortWatcher(double intervalMs = 1000)
+ {
+ _timer = new System.Timers.Timer(intervalMs);
+ _timer.Elapsed += (_, _) => Tick();
+ _timer.AutoReset = true;
+ }
+
+ public void Start()
+ {
+ _last = GetPorts();
+ _timer.Start();
+ }
+
+ public void Stop() => _timer.Stop();
+
+ private void Tick()
+ {
+ var current = GetPorts();
+
+ var added = current.Except(_last).ToArray();
+ var removed = _last.Except(current).ToArray();
+
+ if (added.Length > 0) PortsAdded?.Invoke(added);
+ if (removed.Length > 0) PortsRemoved?.Invoke(removed);
+
+ _last = current;
+ }
+
+ private static HashSet GetPorts()
+ => new HashSet(SerialPort.GetPortNames(), StringComparer.OrdinalIgnoreCase);
+
+ public void Dispose()
+ {
+ _timer.Stop();
+ _timer.Dispose();
+ }
+}
+