繁体   English   中英

C#-SerialPort接收不会一次获取所有数据

[英]C# - SerialPort Receive Doesn't Get All the Data at Once

对于串行端口,我有一个奇怪的难题。 我正在向具有微控制器的设备发送一堆命令,并获得响应。 很典型的东西。 无论如何,我遇到一个问题,当我发送命令时,DataReceived事件处理程序确实会响应,但是问题是我没有从中获取所有数据。 结果,DataReceived事件处理程序最终被调用了4次。

因此,而不是得到这样的东西:

0 - 2:16:38 PM: 126 23 100 69 0 0 99 3 225 2 203 2 174 2 179 2 125 93 3 15 3 
0 0 0 15 255 0 214 12 105 15 33 15 33 15 13 15 54 15 39 5 68 4 197 5 199 5 57 
5 0 0 0 134 225 
1 - 2:16:38 PM: 126 23 100 69 0 0 99 3 226 2 203 2 174 2 179 2 125 93 3 16 3 
0 0 0 15 255 0 224 12 105 15 23 15 33 15 2 15 74 15 39 5 58 4 197 5 198 5 57 
5 0 0 0 65 163 
2 - 2:16:38 PM: 126 23 100 69 0 0 99 3 226 2 202 2 174 2 178 2 125 93 3 15 3 
0 0 0 15 255 0 214 12 95 15 23 15 33 15 23 15 105 15 39 5 58 4 197 5 198 5 57 
5 0 0 0 63 128 

代码最终如下所示(不精确,但给出了一个示例):

0 - 2:16:38 PM: 126 23 100 69 0 0 99 3 225 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 - 2:16:38 PM: 2 203 2 174 2 179 2 125 93 3 15 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0              
0 - 2:16:38 PM: 15 255 0 214 12 105 15 33 15 33 15 13 15 54 0 0 0 0 0 0 0 0 0 
0 - 2:16:38 PM: 15 39 5 68 4 197 5 199 5 57 5 0 0 0 134 225 0 0 0 0 0 0 0 0 0

第一条数据线接受4个事件调用而不是1个事件调用,我假设微控制器仍在发送数据,因为我一次发送所有写数据。 但是我希望有一种控制它的方法,这样我就不会收到所有这些事件调用(因为我更喜欢将字节数组放在一个数组而不是块中)。

这一切都由Visual Studio 2010进行编程,但是如果需要的话,我可以尝试2013。 这是我用来获得与上述结果相似的示例代码(我知道文件流编写器在使用该代码时不会关闭,但是我仅以主要代码为例):

namespace SerialCommunicationsTest
{
    class Program
    {
        static UInt64 count = 0;
        static SerialPort port;
        static System.IO.StreamWriter file;
        static void Main(string[] args)
        {
            file = new System.IO.StreamWriter(@"C:\Users\li\Desktop\Serial.txt");
            port = new SerialPort("COM6", 9600, Parity.None, 8, StopBits.One);
            port.Handshake = Handshake.None;
            port.Open();

            port.ReadTimeout = 400;
            port.WriteTimeout = 400;
            byte[] output = { 0x7E, 0x64, 0x17, 0x01, 0x45, 0x40, 0xFA, 0x7E };
            port.DataReceived += new SerialDataReceivedEventHandler(SerialPortDataReceived);
            /* Loop, send message, and have event handler handler handle incoming event */
            while (count < UInt64.MaxValue)
            {
                port.Write(output, 0, output.Length);
            }

            return;
        }
        static void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
        {

            SerialPort port = (SerialPort)sender;
            byte[] test = new byte[256];

            try
            {
                string data2 = "";
                port.Read(test, 0, 256);
                for (int i = 0; i < 60; i++)
                {
                    data2 += test[i] + " ";
                }
                string writeOut = count + " - " + DateTime.Now.ToString("h:mm:ss tt") + ": " + data2;
                Console.WriteLine(writeOut);
                file.WriteLine(writeOut);
                count++;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
            }

        }
    }
}

如果您知道多个消息的固定长度,可以重复调用Read直到您读完所有字节以填充一个byte[]然后将该数组传递给另一个,这是您的责任:将多个读取调用组合成一个“消息”职能。

    const int MessageSize = 256;
    byte[] test = new byte[MessageSize];
    int offset = 0;


    static void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
    {

        SerialPort port = (SerialPort)sender;
        try
        {
            offset += port.Read(test, offset, MessageSize - offset);

            if(offset == MessageSize)
            {
                string data2 = "";
                for (int i = 0; i < 60; i++)
                {
                    data2 += test[i] + " ";
                }
                string writeOut = count + " - " + DateTime.Now.ToString("h:mm:ss tt") + ": " + data2;
                Console.WriteLine(writeOut);
                file.WriteLine(writeOut);
                count++;
                offset = 0;
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.StackTrace);
        }

    }

尝试这个:

List<byte> dataBuffer = new List<byte>();
byte[] tempBuff;
var bytesReaded = pt.Read(inBuff, 0, inBuffSize);
while (bytesReaded > 0)
{
    tempBuff = new byte[bytesReaded];
    Array.Copy(inBuff, tempBuff, bytesReaded);
    dataBuffer.AddRange(tempBuff);
    bytesReaded = pt.Read(inBuff, 0, inBuffSize);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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