简体   繁体   中英

datareceived Event Handler in Serial C#

I am trying to implement the datarecieved based event handler, I think I am able to receive data from the port, but having difficulties executing the event.. I have tried both ReadLine and ReadExisting.. can you please comment on my code.. Thanks,

private void Form1_Load( object sender, EventArgs e )
        {
              // graphing stuff
            portname = "COM1";
            parity = Parity.None;
            BaudRate = 115200;
            stopbits = StopBits.One;
            databits = 8;
            port = new System.IO.Ports.SerialPort(portname);
            port.Parity = parity;
            port.BaudRate = BaudRate;
            port.StopBits = stopbits;
            port.DataBits = databits;
            port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
            port.Open();
            count = 0;
            }


    void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
      try
        {
         line = port.ReadLine();
         count++;
         this.BeginInvoke(new LineReceivedEvent(LineReceived),line);
            }
          catch (Exception ex)
          {
              MessageBox.Show(ex.Message);
          }
     }

  private delegate void LineReceivedEvent(string text);

  private void LineReceived(string text)
  {

         if (zedGraphControl1.GraphPane.CurveList.Count <= 0)
             return;
         LineItem curve = zedGraphControl1.GraphPane.CurveList[0] as LineItem;
         if (curve == null)
             return;
         IPointListEdit list = curve.Points as IPointListEdit;
         double value = double.Parse(text);
         list.Add(count, value);
        // graphing stuff
   }

// graphing stuff   
}

I have done a lot of work with Serial communications, and DataReceived never works like I want it to. There is a property on SerialPort called ReceivedBytesThreshold that is supposed to change when the event fires, but I have hit and miss luck with it. Do some googling on this event, and you'll have thousands of results reporting problems with it. The event can work sometimes, but I wouldn't rely on it for mission critical operation.

The better way I have found to do it if you're looking for line endings is to simply have a tight loop that continually reads bytes into a buffer if they are available, and then invokes the LineReceived method on the buffer when it encounters a line ending. Put this on its own thread, and it should do the trick. Add a few Thread.Sleep() inside the loop to keep it from taking over.

If you're not looking for instantaneous reactions to the serial stream, then run it on a threaded timer every second or half second. Each tick of the timer, read all the existing bytes into the buffer, and whenever you encounter a line ending invoke LineReceived .

I am also using the DataReceived event with great success in one of our products. The protocol I am implementing mandates a minimum packet size of 6 bytes, so I use that are my receive threshold.

I make sure to keep any orphaned data, and reconstruct it the next time the event occurs if I get an incomplete read or a malformed packet. I really have had very few issues with this implementation. I would suggest locking in the event handler so you don't end up with a race on the serial port, but that may not be needed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM