2013-07-11 17 views
5

Ultimamente sto lavorando con la classe SerialPort. Attualmente sto cercando di capire il modo corretto per verificare se un dispositivo è collegato alla porta di comunicazione utilizzata dall'applicazione. C'è un modo corretto per verificare se un dispositivo è collegato alla porta di comunicazione? Il mio metodo attuale è la seguente:C# Serial Port Verifica se il dispositivo è collegato

  while (isReading == true) 
      { 
       try 
       { 
        received += serialPort.ReadExisting(); 

        if (received.Contains('>')) 
         isReading = false; 
       } 
       catch (Exception e) 
       { 

       } 
       if (tick == 10000) 
        if (received == "") 
        { 
         Console.WriteLine("No Data Received. Device isn't connected."); 
         isReading = false; 
        } 
       tick++; 
      } 
      Console.WriteLine(received); 

Funziona, ma sento che è un po 'hacky e inaffidabile. Posso mantenerlo se necessario, ma mi piacerebbe se ci fosse una valida alternativa a questo.

Modifica: In realtà devo impostare il valore di spunta su circa 10.000 per garantire che sia affidabile. Altrimenti non riesco a ricevere dati occasionalmente. Anche impostarlo su 1000 o 5000 non è affidabile. Anche in questo caso, non è garantito che sia affidabile su più macchine.

+0

Stai programmazione del dispositivo come bene? – Rubixus

+0

@Rubixus No. Si tratta di un dispositivo medico denominato Calibratore multi-prodotto Fluke 5500A. Non sto nemmeno cambiando le impostazioni interne su di esso me stesso. – DanteTheEgregore

+0

Il dispositivo registra un driver nel registro quando è collegato? È un dispositivo USB? – Kcvin

risposta

7

Anch'io ho bisogno di lavorare con le porte seriali, e credimi sono un dolore. Il mio metodo per verificare se un dispositivo è connesso di solito ruota attorno all'emissione di un comando di polling. Mentre il metodo può funzionare, non posso fare a meno di essere riluttante a usare un ciclo while quando un evento è sufficiente.

La classe porta seriale NET offre alcuni eventi utili:

Serial.DataReceivedSerial.ErrorReceived e Serial.Write

solito avrebbe emesso un comando di polling ad un intervallo specificato per assicurare il dispositivo è collegato. Quando il dispositivo risponde, si attiva l'evento DataReceived e si può gestire la risposta di conseguenza (insieme ad altri dati necessari). Questo può essere usato in combinazione con un semplice Timer o una variabile incrementata per il tempo della risposta. Nota è necessario impostare il valore ReadTimeout e WriteTimeout in modo appropriato.Questo, insieme al metodo ReadExisting e/o ReadLine può essere utile nel gestore di eventi DataReceived.

Quindi, per riassumere, (in pseudo codice)

Send Polling command, Start Timer 
Timer to CountDown for a specified time 
If Timer fires, then assume no response 
If DataRecieved fires (and expected response) assume connection 
(of course handle any specific Exceptions (e.g TimeOutException, InvalidOperationException) 
0

Sono d'accordo che è un hacky perché qualsiasi dispositivo potrebbe essere collegato e l'invio di '>'; ma questo non significa che sia il tuo dispositivo.

Invece, essere dinamici e utilizzare qualcosa come SerialPort.GetPortNames e WMI Queries per interrogare i dispositivi collegati alle porte COM.

È possibile utilizzare l'esempio this come punto di partenza.

Dopo aver letto la documentazione e gli esempi, dovresti essere in grado di creare un elenco di tutte le informazioni sul dispositivo che registra i driver sul computer e sulla porta COM collegata.

Edit:

Dal momento che il dispositivo non registra se stesso, considerare guardando la product drivers per Visual Studio che potrebbero rendere il vostro lavoro molto più facile.

+0

'>' È solo il carattere del token che indica che il dispositivo ha finito di emettere un comando e tutto è stato scritto nel buffer. Il mio metodo attuale per verificare se il dispositivo è connesso è in attesa di un determinato periodo di tempo e quindi controllare se ricevuto contiene qualcosa di più di una semplice stringa vuota. Il problema è che su un buon computer, il valore del tick può aumentare di 10.000 volte prima che i dati vengano ricevuti. Non è qualcosa su cui posso facilmente dipendere. – DanteTheEgregore

+0

Questo metodo funziona solo con dispositivi seriali USB, non con RS232, che è l'OP specificato. – Rubixus

+0

@Rubixus Questo è l'esempio che ho dato. È possibile utilizzare query WMI con dispositivi su cui sono installati driver. Quando il driver è installato, verrà visualizzato nel tuo gestore dispositivi. Se è presente nel tuo gestore dispositivi, puoi trovarlo utilizzando le query WMI. Quindi il tuo commento non è valido. – Kcvin

2

Sfortunatamente con le porte seriali, non esiste un modo corretto per determinare se un determinato dispositivo è collegato. È possibile scrivere un messaggio magico a cui solo il dispositivo risponde correttamente, ma come descritto in this answer, questo metodo potrebbe causare problemi ad altri dispositivi collegati.

In definitiva, devi solo dipendere dall'utente che seleziona la porta corretta.

Inoltre, se ti capita di perdere la connessione al dispositivo, sapresti solo quando non riesci a leggere/scrivere su di esso. In questo caso, basta lanciare un evento LostConnection.

+0

Se il dispositivo ha un driver, è possibile identificare il dispositivo utilizzando le query WMI come indicato nella risposta. Questa risposta è fuorviante. Se non ha un driver, puoi imparare a scrivere un driver, scriverlo da solo e rilevare il dispositivo. – Kcvin

+0

@ NETscape Per i dispositivi RS232, le query WMI non funzionerebbero. – Rubixus

+1

@NETscape Non credo che la risposta sia fuorviante. Fa un ottimo punto. Le connessioni seriali sono estremamente incerte. Possono essere piuttosto difficili da lavorare. I driver non sono davvero un'opzione. – DanteTheEgregore

Problemi correlati