• <bdo id='9Kdhf'></bdo><ul id='9Kdhf'></ul>

      <small id='9Kdhf'></small><noframes id='9Kdhf'>

      1. <legend id='9Kdhf'><style id='9Kdhf'><dir id='9Kdhf'><q id='9Kdhf'></q></dir></style></legend>

        <i id='9Kdhf'><tr id='9Kdhf'><dt id='9Kdhf'><q id='9Kdhf'><span id='9Kdhf'><b id='9Kdhf'><form id='9Kdhf'><ins id='9Kdhf'></ins><ul id='9Kdhf'></ul><sub id='9Kdhf'></sub></form><legend id='9Kdhf'></legend><bdo id='9Kdhf'><pre id='9Kdhf'><center id='9Kdhf'></center></pre></bdo></b><th id='9Kdhf'></th></span></q></dt></tr></i><div id='9Kdhf'><tfoot id='9Kdhf'></tfoot><dl id='9Kdhf'><fieldset id='9Kdhf'></fieldset></dl></div>

        <tfoot id='9Kdhf'></tfoot>

        串口轮询和数据处理

        时间:2023-11-10

            <tbody id='T9m0Q'></tbody>
          1. <legend id='T9m0Q'><style id='T9m0Q'><dir id='T9m0Q'><q id='T9m0Q'></q></dir></style></legend>

                <bdo id='T9m0Q'></bdo><ul id='T9m0Q'></ul>
                <tfoot id='T9m0Q'></tfoot>
                  <i id='T9m0Q'><tr id='T9m0Q'><dt id='T9m0Q'><q id='T9m0Q'><span id='T9m0Q'><b id='T9m0Q'><form id='T9m0Q'><ins id='T9m0Q'></ins><ul id='T9m0Q'></ul><sub id='T9m0Q'></sub></form><legend id='T9m0Q'></legend><bdo id='T9m0Q'><pre id='T9m0Q'><center id='T9m0Q'></center></pre></bdo></b><th id='T9m0Q'></th></span></q></dt></tr></i><div id='T9m0Q'><tfoot id='T9m0Q'></tfoot><dl id='T9m0Q'><fieldset id='T9m0Q'></fieldset></dl></div>
                • <small id='T9m0Q'></small><noframes id='T9m0Q'>

                • 本文介绍了串口轮询和数据处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  I am trying to read from several serial ports from sensors through microcontrollers. Each serial port will receive more than 2000 measurements (each measurement is 7 bytes, all in hex). And they are firing at the same time. Right now I am polling from 4 serial ports. Also, I translate each measurement into String and append it to a Stringbuilder. When I finish receiving data, they will be ouput in to a file. The problem is the CPU consumption is very high, ranging from 80% to 100%.

                  I went though some articles and put Thread.Sleep(100) at the end. It reduces CPU time when there is no data coming. I also put Thread.Sleep at the end of each polling when the BytesToRead is smaller than 100. It only helps to a certain extent.

                  Can someone suggest a solution to poll from serial port and handle data that I get? Maybe appending every time I get something causes the problem?

                  //I use separate threads for all sensors
                  private void SensorThread(SerialPort mySerialPort, int bytesPerMeasurement, TextBox textBox,     StringBuilder data)
                      {
                          textBox.BeginInvoke(new MethodInvoker(delegate() { textBox.Text = ""; }));
                  
                          int bytesRead;
                          int t;
                          Byte[] dataIn;
                  
                          while (mySerialPort.IsOpen)
                          {
                              try
                              {
                                  if (mySerialPort.BytesToRead != 0)
                                  {
                                    //trying to read a fix number of bytes
                                      bytesRead = 0;
                                      t = 0;
                                      dataIn = new Byte[bytesPerMeasurement];
                                      t = mySerialPort.Read(dataIn, 0, bytesPerMeasurement);
                                      bytesRead += t;
                                      while (bytesRead != bytesPerMeasurement)
                                      {
                                          t = mySerialPort.Read(dataIn, bytesRead, bytesPerMeasurement - bytesRead);
                                          bytesRead += t;
                                      }
                                      //convert them into hex string
                                      StringBuilder s = new StringBuilder();
                                      foreach (Byte b in dataIn) { s.Append(b.ToString("X") + ","); }
                                      var line = s.ToString();
                  
                                                              var lineString = string.Format("{0}  ----          {2}",
                                                                        line,
                                                                      mySerialPort.BytesToRead);
                                      data.Append(lineString + "
                  ");//append a measurement to a huge Stringbuilder...Need a solution for this.
                  
                                      ////use delegate to change UI thread...
                                      textBox.BeginInvoke(new MethodInvoker(delegate() { textBox.Text = line; }));
                  
                                      if (mySerialPort.BytesToRead <= 100) { Thread.Sleep(100); }
                                  }
                              else{Thread.Sleep(100);}
                  
                              }
                              catch (Exception ex)
                              {
                                  //MessageBox.Show(ex.ToString());
                              }
                          }
                  
                  
                      }
                  

                  解决方案

                  this is not a good way to do it, it far better to work on the DataReceived event.

                  basically with serial ports there's a 3 stage process that works well.

                  • Receiving the Data from the serial port
                  • Waiting till you have a relevant chunk of data
                  • Interpreting the data

                  so something like

                  class DataCollector
                  {
                      private readonly Action<List<byte>> _processMeasurement;
                      private readonly string _port;
                      private SerialPort _serialPort;
                      private const int SizeOfMeasurement = 4;
                      List<byte> Data = new List<byte>();
                  
                      public DataCollector(string port, Action<List<byte>> processMeasurement)
                      {
                          _processMeasurement = processMeasurement;
                          _serialPort = new SerialPort(port);
                          _serialPort.DataReceived +=SerialPortDataReceived;
                      }
                  
                      private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
                      {
                          while(_serialPort.BytesToRead > 0)
                          {
                             var count = _serialPort.BytesToRead;
                             var bytes = new byte[count];
                             _serialPort.Read(bytes, 0, count);
                             AddBytes(bytes);
                          }
                      }
                  
                      private void AddBytes(byte[] bytes)
                      {
                          Data.AddRange(bytes);
                          while(Data.Count > SizeOfMeasurement)            
                          {
                              var measurementData = Data.GetRange(0, SizeOfMeasurement);
                              Data.RemoveRange(0, SizeOfMeasurement);
                              if (_processMeasurement != null) _processMeasurement(measurementData);
                          }
                  
                      }
                  }
                  

                  Note: Add Bytes keeps collecting data till you have enough to count as a measurement, or if you get a burst of data, splits it up into seperate measurements.... so you can get 1 byte one time, 2 the next, and 1 more the next, and it will then take that an turn it into a measurement. Most of the time if your micro sends it in a burst, it will come in as one, but sometimes it will get split into 2.

                  then somewhere you can do

                  var collector = new DataCollector("COM1", ProcessMeasurement);
                  

                  and

                    private void ProcessMeasurement(List<byte> bytes)
                              {
                                  // this will get called for every measurement, so then
                                  // put stuff into a text box.... or do whatever
                              }
                  

                  这篇关于串口轮询和数据处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:等待串口的响应,然后发送下一个数据 下一篇:在 C# 中查找有关通过 USB 连接的所有串行设备的信息

                  相关文章

                • <small id='Th8ze'></small><noframes id='Th8ze'>

                    <i id='Th8ze'><tr id='Th8ze'><dt id='Th8ze'><q id='Th8ze'><span id='Th8ze'><b id='Th8ze'><form id='Th8ze'><ins id='Th8ze'></ins><ul id='Th8ze'></ul><sub id='Th8ze'></sub></form><legend id='Th8ze'></legend><bdo id='Th8ze'><pre id='Th8ze'><center id='Th8ze'></center></pre></bdo></b><th id='Th8ze'></th></span></q></dt></tr></i><div id='Th8ze'><tfoot id='Th8ze'></tfoot><dl id='Th8ze'><fieldset id='Th8ze'></fieldset></dl></div>
                    <tfoot id='Th8ze'></tfoot>
                  1. <legend id='Th8ze'><style id='Th8ze'><dir id='Th8ze'><q id='Th8ze'></q></dir></style></legend>
                    • <bdo id='Th8ze'></bdo><ul id='Th8ze'></ul>