How do I use dataReceived event of the SerialPort Port Object in C#?

后端 未结 7 1720
無奈伤痛
無奈伤痛 2020-11-28 07:26

I am attempting to create a small application to collect data received from an external sensor attached to COM10. I have successfully created a small C# console object and

相关标签:
7条回答
  • 2020-11-28 07:34

    I think your issue is the line:**

    sp.DataReceived += port_OnReceiveDatazz;

    Shouldn't it be:

    sp.DataReceived += new SerialDataReceivedEventHandler (port_OnReceiveDatazz);

    **Nevermind, the syntax is fine (didn't realize the shortcut at the time I originally answered this question).

    I've also seen suggestions that you should turn the following options on for your serial port:

    sp.DtrEnable = true;    // Data-terminal-ready
    sp.RtsEnable = true;    // Request-to-send
    

    You may also have to set the handshake to RequestToSend (via the handshake enumeration).


    UPDATE:

    Found a suggestion that says you should open your port first, then assign the event handler. Maybe it's a bug?

    So instead of this:

    sp.DataReceived += new SerialDataReceivedEventHandler (port_OnReceiveDatazz);
    sp.Open();
    

    Do this:

    sp.Open();
    sp.DataReceived += new SerialDataReceivedEventHandler (port_OnReceiveDatazz);
    

    Let me know how that goes.

    0 讨论(0)
  • 2020-11-28 07:39

    Might very well be the Console.ReadLine blocking your callback's Console.Writeline, in fact. The sample on MSDN looks ALMOST identical, except they use ReadKey (which doesn't lock the console).

    0 讨论(0)
  • 2020-11-28 07:40

    By the way, you can use next code in you event handler:

    switch(e.EventType)
    {
      case SerialData.Chars:
      {
        // means you receives something
        break;
      }
      case SerialData.Eof:
      {
        // means receiving ended
        break;
      }
    }
    
    0 讨论(0)
  • 2020-11-28 07:43

    I was having the very same problem with a modem that had previously worked and then one day just stopped raising the DataReceived event.

    The solution in my case, very randomly, was to enable RTS e.g.

    sp.RtsEnable = true;
    

    No idea why that worked on this particular bit of kit (not a comms man at all really), nor why it had worked and then stopped but it may help somebody else one day so just posting it just in case...

    0 讨论(0)
  • 2020-11-28 07:46

    First off I recommend you use the following constructor instead of the one you currently use:

    new SerialPort("COM10", 115200, Parity.None, 8, StopBits.One);
    

    Next, you really should remove this code:

    // Wait 10 Seconds for data...
    for (int i = 0; i < 1000; i++)
    {
        Thread.Sleep(10);
        Console.WriteLine(sp.Read(buf,0,bufSize)); //prints data directly to the Console
    }
    

    And instead just loop until the user presses a key or something, like so:

    namespace serialPortCollection
    {   class Program
        {
            static void Main(string[] args)
            {
                SerialPort sp = new SerialPort("COM10", 115200);
                sp.DataReceived += port_OnReceiveDatazz; // Add DataReceived Event Handler
    
                sp.Open();
                sp.WriteLine("$"); //Command to start Data Stream
    
                Console.ReadLine();
    
                sp.WriteLine("!"); //Stop Data Stream Command
                sp.Close();
            }
    
           // My Event Handler Method
            private static void port_OnReceiveDatazz(object sender, 
                                       SerialDataReceivedEventArgs e)
            {
                SerialPort spL = (SerialPort) sender;
                byte[] buf = new byte[spL.BytesToRead];
                Console.WriteLine("DATA RECEIVED!");
                spL.Read(buf, 0, buf.Length);
                foreach (Byte b in buf)
                {
                    Console.Write(b.ToString());
                }
                Console.WriteLine();
            }
        }
    }
    

    Also, note the revisions to the data received event handler, it should actually print the buffer now.

    UPDATE 1


    I just ran the following code successfully on my machine (using a null modem cable between COM33 and COM34)

    namespace TestApp
    {
        class Program
        {
            static void Main(string[] args)
            {
                Thread writeThread = new Thread(new ThreadStart(WriteThread));
                SerialPort sp = new SerialPort("COM33", 115200, Parity.None, 8, StopBits.One);
                sp.DataReceived += port_OnReceiveDatazz; // Add DataReceived Event Handler
    
                sp.Open();
                sp.WriteLine("$"); //Command to start Data Stream
    
                writeThread.Start();
    
                Console.ReadLine();
    
                sp.WriteLine("!"); //Stop Data Stream Command
                sp.Close();
            }
    
            private static void port_OnReceiveDatazz(object sender, 
                                       SerialDataReceivedEventArgs e)
            {
                SerialPort spL = (SerialPort) sender;
                byte[] buf = new byte[spL.BytesToRead];
                Console.WriteLine("DATA RECEIVED!");
                spL.Read(buf, 0, buf.Length);
                foreach (Byte b in buf)
                {
                    Console.Write(b.ToString() + " ");
                }
                Console.WriteLine();
            }
    
            private static void WriteThread()
            {
                SerialPort sp2 = new SerialPort("COM34", 115200, Parity.None, 8, StopBits.One);
                sp2.Open();
                byte[] buf = new byte[100];
                for (byte i = 0; i < 100; i++)
                {
                    buf[i] = i;
                }
                sp2.Write(buf, 0, buf.Length);
                sp2.Close();
            }
        }
    }
    

    UPDATE 2


    Given all of the traffic on this question recently. I'm beginning to suspect that either your serial port is not configured properly, or that the device is not responding.

    I highly recommend you attempt to communicate with the device using some other means (I use hyperterminal frequently). You can then play around with all of these settings (bitrate, parity, data bits, stop bits, flow control) until you find the set that works. The documentation for the device should also specify these settings. Once I figured those out, I would make sure my .NET SerialPort is configured properly to use those settings.

    Some tips on configuring the serial port:

    Note that when I said you should use the following constructor, I meant that use that function, not necessarily those parameters! You should fill in the parameters for your device, the settings below are common, but may be different for your device.

    new SerialPort("COM10", 115200, Parity.None, 8, StopBits.One);
    

    It is also important that you setup the .NET SerialPort to use the same flow control as your device (as other people have stated earlier). You can find more info here:

    http://www.lammertbies.nl/comm/info/RS-232_flow_control.html

    0 讨论(0)
  • 2020-11-28 07:47

    I believe this won't work because you are using a console application and there is no Event Loop running. An Event Loop / Message Pump used for event handling is setup automatically when a Winforms application is created, but not for a console app.

    0 讨论(0)
提交回复
热议问题