initial version with serial link

This commit is contained in:
2026-01-18 02:25:38 +01:00
parent d432db9985
commit 2311647885
11 changed files with 582 additions and 463 deletions

View File

@@ -0,0 +1,158 @@
#nullable enable
using System;
using System.IO.Ports;
using System.Linq;
using System.Threading;
public class SerialManager : IDisposable
{
private SerialPort? port;
private DateTime lastResponse = DateTime.UtcNow;
private const int BaudRate = 115200;
private const int PingTimeoutMs = 300;
private const int WatchdogTimeoutMs = 3000;
public bool IsConnected => port != null && port.IsOpen;
// ---------------- DEVICE DISCOVERY ----------------
public void DiscoverDevice()
{
DisposePort();
foreach (string com in SerialPort.GetPortNames().OrderBy(s => s))
{
string? response = null;
try
{
using (var testPort = CreatePort(com, PingTimeoutMs))
{
testPort.Open();
Thread.Sleep(350); // RP2040 resets on open
testPort.DiscardInBuffer();
testPort.DiscardOutBuffer();
testPort.Write("PING\n");
try
{
if (testPort.BytesToRead > 0)
response = testPort.ReadLine();
}
catch (TimeoutException)
{
// No response — move to next port
}
}
if (response != null &&
response.StartsWith("Analog_System_Monitor_"))
{
port = CreatePort(com, 500);
port.Open();
Thread.Sleep(350); // allow RP2040 reboot again
lastResponse = DateTime.UtcNow;
return;
}
}
catch
{
// Silent fail — move to next COM port
}
}
port = null;
}
// ---------------- PORT FACTORY ----------------
private SerialPort CreatePort(string com, int timeout)
{
return new SerialPort(com, BaudRate)
{
Parity = Parity.None,
DataBits = 8,
StopBits = StopBits.One,
Handshake = Handshake.None,
NewLine = "\n",
Encoding = System.Text.Encoding.ASCII,
ReadTimeout = timeout,
WriteTimeout = timeout,
DtrEnable = true, // REQUIRED for RP2040 USB CDC
RtsEnable = true
};
}
// ---------------- WATCHDOG ----------------
public bool WatchdogExpired =>
(DateTime.UtcNow - lastResponse).TotalMilliseconds > WatchdogTimeoutMs;
// ---------------- SEND COMMAND ----------------
public void SendSetAll(string cmd)
{
if (!IsConnected)
return;
try
{
port!.Write(cmd + "\n");
string? response = null;
try
{
if (port.BytesToRead > 0)
response = port.ReadLine();
}
catch (TimeoutException)
{
// No response this tick — totally fine
}
if (response != null &&
(response.StartsWith("OK") || response.StartsWith("ERROR")))
{
lastResponse = DateTime.UtcNow;
}
}
catch
{
// Silent fail — watchdog will trigger reconnect
}
}
// ---------------- CLEANUP ----------------
private void DisposePort()
{
try
{
if (port != null)
{
port.Close();
port.Dispose();
}
}
catch
{
// ignore
}
port = null;
}
public void Dispose()
{
DisposePort();
}
}