private void SerThread() { while (!stopSerThread_Token.Token.IsCancellationRequested) { SerialTask task; try { task = toSerThreadQueue.Take(stopSerThread_Token.Token); } catch { break; } if (!stopSerThread_Token.Token.IsCancellationRequested) { int bytesWritten = serialPort.Write(task.Send); if (bytesWritten < 0) { break; } if (task.WaitTime > 0) { task.Recv = ""; string temp = serialPort.ReadString(SERIAL_RECV_LEN_HINT, (uint)task.WaitTime, (uint)serialPortByteTimeout); if (temp != null) { //no serport error ocurred task.Recv = temp; } fromSerThreadQueue.Add(task); } } } if (!stopSerThread_Token.Token.IsCancellationRequested) { //if we're not volantarily stopping, notify the error Console.WriteLine("[SerThread] port error"); NotifySerPortError(); } Console.WriteLine("[SerThread] exit"); }
/// <summary> /// Fase di connessione. /// </summary> private static void ThreadedConnection() { Utilities.LogD(TAG, "In attesa di connessione..."); do { has_Connected = false; while (!has_Connected) { string[] porte = SerialPort.GetPortNames(); //Ottiene la lista dei nomi delle porte correntemente utilizzate dal sistema operativo for (int i = 0; i < porte.Length; i++) { Utilities.LogD(TAG, "Presente porta: " + porte[i]); } for (int i = 0; i < porte.Length; i++) //Scorre le porte alla ricerca di quella giusta { if (porte != null) { if (porte[i].Contains("ACM") || porte[i].Contains("COM")) //Arduino usa l'abstract control model (ACM), per cui in linux based os le porte di arduino iniziano sempre per ACM, non per COM. { seriale = new BetterSerialPort(porte[i], baudrate); //Inizializza la porta scelta al baudrate scelto seriale.ReadTimeout = timeout; //setta il timeout, cioé la quantità di tempo dopo il quale, se non si riceve risposta, la connessione al dispositivo viene annullata. seriale.Handshake = Handshake.None; //Nessaun handshaking col dispositivo perché ne faccio uno manuale. seriale.DtrEnable = true; //Abilito il data terminal ready (DTR) per segnalare ad arduino che il PC è pronto a comunicare. seriale.Encoding = System.Text.Encoding.ASCII; //seriale.DataReceived += new SerialDataReceivedEventHandler(ParseData); //Event listener NON FUNZIONA CON UNITY (BUG NOTO) if (seriale.IsOpen) { Utilities.LogD(TAG, "Impossibile aprire arduino: seriale già aperto!"); seriale.Close(); } else { try { seriale.Open(); //Apro la comunicazione col seriale Utilities.LogD(TAG, "Connesso alla porta [" + porte[i] + "]"); i = porte.Length; has_Connected = true; } catch (UnauthorizedAccessException uae) { Utilities.LogD(TAG, "Accesso non autorizzato alla porta [" + porte[i] + "] -> [" + uae + "]"); } catch (ArgumentOutOfRangeException aoore) { Utilities.LogD(TAG, "Argument out of range alla porta [" + porte[i] + "] -> [" + aoore + "]"); } catch (IOException ioe) { Utilities.LogD(TAG, "IO exception alla porta [" + porte[i] + "] -> [" + ioe + "]"); } catch (IndexOutOfRangeException ioore) { Utilities.LogD(TAG, "Index out of range -> [" + ioore + "]"); } } } } Thread.Sleep(100); } } while (seriale != null && seriale.IsOpen) { //IN string incoming = seriale.ReadLine(); if (incoming.Length > 0 && incoming != null) { Utilities.LogD(TAG, "Ricevuto messaggio da arduino [" + incoming + "]"); //Do something with this data here. } //OUT ASYNC if (outgoingQueue.TryDequeue(out string msg)) { if (msg != "" && msg != null) { Utilities.LogD(TAG, "Invio messaggio ad arduino [" + msg + "]"); try { seriale.Write(msg); seriale.Clear(); } catch (InvalidOperationException e) { Utilities.LogE(TAG, "Operazione non valida [" + e + "]"); } catch (ArgumentNullException e) { Utilities.LogE(TAG, "Argomento nullo [" + e + "]"); } catch (TimeoutException e) { Utilities.LogE(TAG, "Timeout [" + e + "]"); } } } Thread.Sleep(5); //Giusto per non schiattare la board. Tanto 5 ms non si sentono. } //seriale.Close(); //seriale.Dispose(); has_Connected = false; Utilities.LogD(TAG, "arduino disconesso, tento la riconnessione..."); } while (true); }