连续串口读取 [英] Continuosly serial port read

查看:121
本文介绍了连续串口读取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在连续读取硬件设备,问题是设备停止发送数据,我认为是我的datareceive事件的问题,但我不确定

那个。



I am reading from hardware device continuosly, the problem is the device stop sending data, i think is problem of my datareceive event but i am not sure of
that.

serialPort.PortName = porta;
serialPort.BaudRate = 115200;
serialPort.DataBits = 8;
serialPort.ReadBufferSize = 409600;
serialPort.Open();
CrearTramaConect();
serialPort.Write(TramaConect, 0, TramaConect.Length);







void serialPort_DataReceived(object s, SerialDataReceivedEventArgs e)
{

 while (serialPort.BytesToRead >= 14)
     {    
       
      for (int i = 0; i < 14; i++)
      {
          data[i] = (byte)serialPort.ReadByte();
      }

       if (data[13] == (byte)'F')
           {

             data.ToList().ForEach(b => recievedData.Enqueue(b));
             processData();
             //trato los datos en este metodo 
             LineReceived(this, new LineReceivedEventArgs(packet));

            }else{

                  while ((charend != (byte)'F') && serialPort.BytesToRead != 0))
                   charend = (byte)serialPort.ReadByte();

            }
     }
}













public event LineReceivedEventHandler LineReceived;

sp1.LineReceived += new LineReceivedEventHandler(sp1_LineReceived);


void sp1_LineReceived(object sender, LineReceivedEventArgs Args)
        {

            this.Invoke((MethodInvoker)(()=>cargarDatosEnSerie(sender,Args)));

        }










private void cargarDatosEnSerie(object sender, LineReceivedEventArgs Args)
       {

         this.Invoke((MethodInvoker)(() => addPoints(new Dato(Args.packet, false, false, 1, false, false,j))) );

         dataGridView1.Update();

         label1.Text = "numero de puntos: " + j;
         this.Refresh();

       }

byte[] packet;
        private byte[] processData()
        {
            // Determine if we have a "packet" in the queue
           
           if(recievedData.Count>=14)               
                    packet = Enumerable.Range(0, 14).Select(i => recievedData.Dequeue()).ToArray();              
                
          
            return packet;
        }





发表评论



From comment

That is the data (frame) i receive (always 14 bytes):
68 -->'D'
65 -->'A'
84 -->'T'
0
127 Xh
254 Xl
0
0
115 Yh
51 Yl
5
0
196
70 -->'F'

i do the job with this, (127254) is my X value and 11551 my Y value, i use these to plot it in a chart,my hardware now is sending frames continuosly
x = 1 y = 0,001 'D' 'A' 'T'.............'F'
x = 2 y = 0,002 'D' 'A' 'T'.............'F'
x = 3 y = 0,003 'D' 'A' 'T'.............'F'

All data with this 'D' 'A' 'T'.............'F' frame format is interesting for me, and continuosly read.










<pre lang="C#">thanks George, i have a problem with that

<pre><pre lang="c#">

if(serialPort.BytesToRead> 13)//例如

{

string data = serialPort.ReadLine();









if(data.ToCharArray()。Count()== 13)

{







dataArray = Encoding.ASCII.GetBytes(data);





dataArray.ToList()。ForEach(b =& amp; gt; recievedData.Enqueue(b));



processData();

LineReceived(这个,新的LineReceivedEventArgs(dataArray));

}



}



这条线我认为



if (serialPort.BytesToRead > 13) // For example
{
string data = serialPort.ReadLine();




if (data.ToCharArray().Count() == 13)
{



dataArray = Encoding.ASCII.GetBytes(data);


dataArray.ToList().ForEach(b =&amp;gt; recievedData.Enqueue(b));

processData();
LineReceived(this, new LineReceivedEventArgs(dataArray));
}

}

with this line i think

dataArray = Encoding.ASCII.GetBytes(data);





dato:68 --- 65- --84 --- 1 --- 3 --- 63 --- 1 --- 1 --- 1 --- 122 --- 1 --- 1 --- 63 ---

dato:68 --- 65 --- 84 --- 1 --- 3 --- 63 --- 1 --- 1 --- 1 --- 123 --- 1 --- 1 --- 63 ---

dato:68 --- 65 --- 84 --- 1 --- 3 --- 63 --- 1 --- 1 --- 1 --- 124 --- 1 --- 1 --- 63 ---

dato:68 --- 65 --- 84 --- 1 --- 3 --- 63 --- 1 --- 1 --- 1 --- 125 --- 1 --- 1 --- 63 ---

dato:68 --- 65 --- 84 --- 1 --- 3 --- 63 --- 1 --- 1 --- 1 --- 126 --- 1 --- 1 --- 63 ---

dato:68 --- 65 --- 84 --- 1 --- 3 --- 63 --- 1 --- 1 --- 1 --- 127 --- 1 --- 1- - 63 ---

dato:68 --- 65 --- 84 --- 1 --- 3 --- 63 --- 1 --- 1 --- 1 --- 63 --- 1 --- 1 --- 107 ---这将是128

dato:68 --- 65 --- 84 --- 1 --- 3 --- 63 --- 1 --- 1 --- 1 --- 63 --- 1 --- 1 --- 106 ---

dato:68 --- 65 --- 84 --- 1 --- 3 --- 63 --- 1 --- 1 --- 1 --- 63 --- 1 --- 1 --- 105 ---

dato:68 --- 65 --- 84 --- 1 --- 3 --- 63 --- 1 --- 1 --- 1 --- 63 --- 1 --- 1- --104 ---

dato:68 --- 65 --- 84 --- 1 --- 3 --- 63 --- 1 --- 1 --- 1- --63 --- 1 --- 1 --- 111 ---

dato:68 --- 65 --- 84 --- 1 --- 3 --- 63- --1 --- 1 --- 1 --- 63 --- 1 --- 1 --- 110 ---

dato:68 --- 65 --- 84- --1 --- 3 --- 63 --- 1 --- 1 --- 1 --- 63 --- 1 --- 1 --- 109 ---



dato: 68---65---84---1---3---63---1---1---1---122---1---1---63---
dato: 68---65---84---1---3---63---1---1---1---123---1---1---63---
dato: 68---65---84---1---3---63---1---1---1---124---1---1---63---
dato: 68---65---84---1---3---63---1---1---1---125---1---1---63---
dato: 68---65---84---1---3---63---1---1---1---126---1---1---63---
dato: 68---65---84---1---3---63---1---1---1---127---1---1---63---
dato: 68---65---84---1---3---63---1---1---1---63---1---1---107--- this will be 128
dato: 68---65---84---1---3---63---1---1---1---63---1---1---106---
dato: 68---65---84---1---3---63---1---1---1---63---1---1---105---
dato: 68---65---84---1---3---63---1---1---1---63---1---1---104---
dato: 68---65---84---1---3---63---1---1---1---63---1---1---111---
dato: 68---65---84---1---3---63---1---1---1---63---1---1---110---
dato: 68---65---84---1---3---63---1---1---1---63---1---1---109---

推荐答案

你需要坐下来思考你在做什么。



你的方法serialPort_DataReceived很可能每次都被触发收到字节。



所以当收到一个字节时,你会怎么做?



嗯,如果您希望接收一定数量的字节,则可以读取可用字节并将它们放入缓冲区中直到你满足要求。



如果你正在等待传输结束字符ETX,那么你读取传入的字节并将它们放入缓冲区,直到你看到你的ETX角色。



这意味着您需要一个全局缓冲区来保存收到的数据,并且只有在符合条件时才会触发事件。然后你清除缓冲区。



你不要在事件中放置一个循环。期间。



[更新]

如果您的数据始终以ASCII字符F结尾,则可以修改属性 ^ ]



You need to sit down and think about what you are doing.

Your method serialPort_DataReceived is, most likely, triggered every time a byte is received.

So when a byte is received, what do you do?

Well, if you expect a certain number of bytes to be received you can read the available bytes and put them into a buffer until you fulfill the requirements.

If you are waiting for a end of transmission character, ETX, then you read the incoming bytes and put them into a buffer until you see your ETX character.

This means that you need a "global" buffer to hold received data, and that you only fire an event if your criteria is fulfilled. Then you clear the buffer.

You don't put a loop inside the event. Period.

[UPDATE]
If your data always end with the ASCII character F, you can modify the property SerialPort.NewLine[^]

serialPort.PortName = porta;
serialPort.BaudRate = 115200;
serialPort.DataBits = 8;
serialPort.ReadBufferSize = 409600;
serialPort.NewLine = "F";
serialPort.ReadTimeOut = 1000;  // When using ReadLine it is good to set a timeout.





然后在数据的事件处理程序中收到你可以做这样的事情



Then in the event handler for the data received you can do something like this

void serialPort_DataReceived(object s, SerialDataReceivedEventArgs e)
{
    if (serialPort.BytesToRead > 13) // For example
    {
        // ReadLine blocks until the NewLine character appears or time out
        string data = serialPort.ReadLine();

        // The F is not included in the data so if you need it you have to add it again
        // data += "F";

        // Do your stuff
    }
}


that is all right, thanks to George, the problem was, coding and decoding, the hardware send me an byte array, when i read from de serial, i recieve this, when i use readLine whitought any decoding, i lost the order of bytes, the solution, encoding the port, and decoding the string when we use read line method 


这篇关于连续串口读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆