2012-12-06 10 views
20

मैंने .NET SerialPort क्लास का उपयोग करके धारावाहिक बंदरगाहों से डेटा को पढ़ने के तरीके के बारे में बहुत सारे प्रश्न पढ़े हैं लेकिन कोई भी सिफारिश किए गए दृष्टिकोण मेरे लिए पूरी तरह से सक्षम साबित हुए हैं।.NET ढांचे का उपयोग कर सीरियल पोर्ट को पढ़ने का सही तरीका क्या है?

SerialPort port = new SerialPort("COM1"); 
port.DataReceived += new SerialDataReceivedEventHandler(MyDataReceivedHandler); 

और ईवेंट हैंडलर:

यहाँ कोड मैं अब के लिए उपयोग कर रहा हूँ है

void MyDataReceivedHandler(object sender, SerialDataReceivedEventArgs e) 
{ 
    int count = port.BytesToRead; 
    byte[] ByteArray = new byte[count]; 
    port.Read(ByteArray, 0, count); 
} 

लेकिन मैं अभी भी कुछ डेटा कभी कभी याद आ रही है। मैंने इवेंट हैंडलर में डेटा पढ़ने के अलग-अलग तरीके की कोशिश की है लेकिन बिना किसी किस्मत के।

चूंकि .NET 4.5 कुछ एसिंक्रोनस कार्यों को करने के लिए नई संभावनाएं लाता है, जैसे ReadAsync विधि जो सीरियलपोर्ट स्ट्रीम पर उपयोग करने योग्य प्रतीत होता है, मुझे यह देखने के लिए उत्सुकता है कि उन मामलों को संभालने के लिए अनुशंसित दृष्टिकोण क्या होगा।

+3

आपका प्रश्न वास्तव में अस्पष्ट है। "मुझे अभी भी कुछ डेटा याद आ रहा है" यह आपके मैकेनिक को कहने जैसा है "मेरी कार कभी-कभी एक मजेदार शोर बनाती है" और पूछती है कि इसे ठीक करने के लिए कितना खर्च आएगा। शायद [यह उत्तर] (http://stackoverflow.com/a/2966357/62576) किसी संबंधित प्रश्न में मदद कर सकता है। हालांकि, मुझे लगता है कि यदि आप सहायता चाहते हैं तो आपको बहुत अधिक विशिष्ट होने की आवश्यकता है; जैसा कि है, इस विषय पर अन्य प्रश्नों को देखकर बहुत कुछ नहीं दिया जा सकता है। –

+0

आप सही हैं, मैं एक वास्तविक उदाहरण प्रस्तुत करूँगा ताकि बेहतर हो सके कि क्या हो रहा है ... –

+3

आरएस 232 या 485 पर एक सीरियल संचार प्रोटोकॉल को कार्यान्वित करना वास्तव में एक कठिन काम है। इसके लिए बहुत सारे अनुभव की आवश्यकता है। मैं अच्छे पुराने डॉस दिनों से इसे कार्यान्वित कर रहा हूं और अभी भी कुछ आम नुकसान में फंस गया हूं। धारावाहिक संचार से निपटने के लिए आप एक विश्वसनीय तृतीय-पक्ष की पेशकश क्यों नहीं ढूंढते? वे संभवत: आपके द्वारा गिरने वाली कई सारी, कई, कई बगों को लोहे से निकाल देंगे :-) यदि यह एक अभ्यास है, तो आगे बढ़ें, यह अंततः मास्टर धारावाहिक संचार के लिए बड़ी संतुष्टि प्रदान करता है! :-) – Loudenvier

उत्तर

14

आप उदाहरण के लिए कुछ इस तरह की कोशिश कर सकते हैं मुझे लगता है कि आप का उपयोग करने के लिए इच्छुक रहे हैं port.ReadExisting() विधि

class SerialPortProgram 
{ 
    // Create the serial port with basic settings 
    private SerialPort port = new SerialPort("COM1", 
     9600, Parity.None, 8, StopBits.One); 
    [STAThread] 
    static void Main(string[] args) 
    { 
     // Instatiate this 
     class new SerialPortProgram(); 
    } 

    private SerialPortProgram() 
    { 
     Console.WriteLine("Incoming Data:"); 
     // Attach a method to be called when there 
     // is data waiting in the port's buffer 
     port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived); 
     // Begin communications 
     port.Open(); 
     // Enter an application loop to keep this thread alive 
     Application.Run(); 
    } 

    private void port_DataReceived(object sender, SerialDataReceivedEventArgs e) 
    { 
     // Show all the incoming data in the port's buffer 
     Console.WriteLine(port.ReadExisting()); 
    } 
} 

है या आप के आधार पर यह करना चाहता हूँ कि तुम क्या कोशिश कर रहे थे है ऐसा करने के लिए, तुम कोशिश कर सकते इस

public class MySerialReader : IDisposable 
{ 
    private SerialPort serialPort; 
    private Queue<byte> recievedData = new Queue<byte>(); 

    public MySerialReader() 
    { 
    serialPort = new SerialPort(); 
    serialPort.Open(); 
    serialPort.DataReceived += serialPort_DataReceived; 
    } 

    void serialPort_DataReceived(object s, SerialDataReceivedEventArgs e) 
    { 
    byte[] data = new byte[serialPort.BytesToRead]; 
    serialPort.Read(data, 0, data.Length); 
    data.ToList().ForEach(b => recievedData.Enqueue(b)); 
    processData(); 
    } 

    void processData() 
    { 
    // Determine if we have a "packet" in the queue 
    if (recievedData.Count > 50) 
    { 
     var packet = Enumerable.Range(0, 50).Select(i => recievedData.Dequeue()); 
    } 
    } 

    public void Dispose() 
    { 
     if (serialPort != null) 
     { 
      serialPort.Dispose(); 
     } 
    } 
+1

आपकी मदद के लिए धन्यवाद, मैं अंत में एक ब्लॉकिंग संग्रह के साथ उपयोग किए गए 'ReadExisting' के साथ चला गया। मैं अभी भी नए 'ReadAsync' फ़ंक्शन को आजमाने की योजना बना रहा हूं ... –

+0

प्रक्रिया नहीं हैडेटा() विधि को mutex की आवश्यकता है? मेरा मतलब है, प्रक्रिया डेटा() अभी भी चल रहा है जब datareceived घटना फिर से ट्रिगर कर सकता है? यही है ना? तो हम प्रक्रिया (डेटा) के अंदर चल रहे दो (या इससे भी अधिक?) धागे के साथ समाप्त हो सकते हैं .... –

+0

मैंने उस सीमा तक इसकी कोशिश नहीं की है और ऊपर दिए गए टिप्पणी में यैनिक ने जो कहा है उसके आधार पर मैं सोच रहा हूं कि यह होगा अगर वह असीमित रूप से पढ़ने के साथ आगे बढ़ना था तो कोई फर्क नहीं पड़ता – MethodMan

4

मैं @MethodMan के समान कोड का इस्तेमाल किया है, लेकिन मैं डेटा सीरियल पोर्ट भेज रहा था का ट्रैक रखने और एक समाप्त चरित्र को पता है के लिए देखो जब सीरियल पोर्ट भेजने के लिए किया गया था के लिए था डेटा।

private string buffer { get; set; } 
private SerialPort _port { get; set; } 

public Port() 
{ 
    _port = new SerialPort(); 
    _port.DataReceived += new SerialDataReceivedEventHandler(dataReceived); 
    buffer = string.Empty; 
} 

private void dataReceived(object sender, SerialDataReceivedEventArgs e) 
{  
    buffer += _port.ReadExisting(); 

    //test for termination character in buffer 
    if (buffer.Contains("\r\n")) 
    { 
     //run code on data received from serial port 
    } 
} 
0

मुझे लगता है कि एक SerialDataReceivedEvent का उपयोग न करें। टाइमर बेहतर चयन में से एक है, और निरंतर समय के बाद, डेटा प्राप्त करने के लिए:

For i = 1 To Me.objSerialPort.BytesToRead 
    strReceiveData &= Convert.ToChar(Me.objSerialPort.ReadByte) 
Next i 
संबंधित मुद्दे