using System.IO.Ports; using System.Windows; namespace WpfMaiTouchEmulator; internal class MaiTouchComConnector { private static SerialPort? serialPort; private bool isActiveMode; private bool _connected; private bool _shouldReconnect = true; private readonly MaiTouchSensorButtonStateManager _buttonState; public Action OnConnectStatusChange { get; internal set; } public Action OnConnectError { get; internal set; } public Action OnDataSent { get; internal set; } public Action OnDataRecieved { get; internal set; } public MaiTouchComConnector(MaiTouchSensorButtonStateManager buttonState) { _buttonState = buttonState; } public async Task StartTouchSensorPolling() { if (!_connected && _shouldReconnect) { var virtualPort = "COM23"; // Adjust as needed try { OnConnectStatusChange("Conecting..."); serialPort = new SerialPort(virtualPort, 9600, Parity.None, 8, StopBits.One); serialPort.WriteTimeout = 100; serialPort.DataReceived += SerialPort_DataReceived; serialPort.Open(); Console.WriteLine("Serial port opened successfully."); OnConnectStatusChange("Connected to port"); _connected = true; while (true) { if (isActiveMode) { SendTouchscreenState(); await Task.Delay(1); } else { await Task.Delay(100); } } } catch (TimeoutException) { } catch (Exception ex) { OnConnectError(); Application.Current.Dispatcher.Invoke(() => { MessageBox.Show(ex.Message, "Error connecting to COM port", MessageBoxButton.OK, MessageBoxImage.Error); }); } finally { _connected = false; OnConnectStatusChange("Not Connected"); if (serialPort?.IsOpen == true) { serialPort.Close(); } } } } public async Task Disconnect() { _shouldReconnect = false; _connected = false; try { serialPort.DtrEnable = false; serialPort.RtsEnable = false; serialPort.DataReceived -= SerialPort_DataReceived; await Task.Delay(200); if (serialPort.IsOpen == true) { serialPort.DiscardInBuffer(); serialPort.DiscardOutBuffer(); serialPort.Close(); } } catch (Exception ex) { MessageBox.Show(ex.Message); } } void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { var recievedData = serialPort.ReadExisting(); var commands = recievedData.Split(new[] { '}' }, StringSplitOptions.RemoveEmptyEntries); foreach (var command in commands) { var cleanedCommand = command.TrimStart('{'); Console.WriteLine($"Received data: {cleanedCommand}"); OnDataRecieved(cleanedCommand); if (cleanedCommand == "STAT") { isActiveMode = true; } else if (cleanedCommand == "RSET") { } else if (cleanedCommand == "HALT") { isActiveMode = false; } else if (cleanedCommand[2] == 'r' || cleanedCommand[2] == 'k') { var leftOrRight = cleanedCommand[0]; var sensor = cleanedCommand[1]; var ratio = cleanedCommand[3]; var newString = $"({leftOrRight}{sensor}{cleanedCommand[2]}{ratio})"; serialPort.Write(newString); OnDataSent(newString); } else { Console.WriteLine(cleanedCommand); } } } void SendTouchscreenState() { if (_connected) { var currentState = _buttonState.GetCurrentState(); serialPort?.Write(currentState, 0, currentState.Length); } } }