简体   繁体   English

C#无法从串口Arduino读取完整缓冲区

[英]C# Can't read full buffer from serial port Arduino

I have Arduino connected to serial port. 我已将Arduino连接到串行端口。 Arduino has the following simple code to send bytes: Arduino具有以下简单的代码来发送字节:

void setup()
{
    Serial.begin(9600);
}

void loop()
{
    Serial.write((char)100);
}

Code to receive bytes (in separate thread): 接收字节的代码(在单独的线程中):

int buffersize = 100000;
byte[] buffer = new byte[buffersize];

SerialPort port = new SerialPort("COM3", 9600);
port.ReadBufferSize = buffersize;
port.Open();

int bytesread = 0;
do
{
    bytesread = port.BytesToRead;
}
while(bytesread < buffersize && bytesread != buffersize);

port.Read(buffer, 0, buffersize);

I read that BytesToRead can return more than ReadBufferSize because it includes one more buffer. 我读到BytesToRead可以返回比ReadBufferSize更多的值,因为它包含一个以上的缓冲区。 But instead I can receive only nearly 12000 and after that ReadBufferSize doesn't change. 但是相反,我只能接收将近12000,并且此后ReadBufferSize不变。 The same problem occurs with all baud rates. 所有波特率都出现相同的问题。

So how to read all 100000 bytes in buffer at once? 那么如何一次读取缓冲区中的所有100000字节? Maybe there are some driver settings etc? 也许有一些驱动程序设置等? Please help. 请帮忙。

If the Arduino is sending continuously the bytes at this baudrate, the speed will be maximum 9600/10 = 960 bytes/second (1 byte will take 10 bauds: 8 data bits + 1 start + 1 stop). 如果Arduino以这种波特率连续发送字节,则速度将最大为9600/10 = 960字节/秒(1字节将占用10个波特:8个数据位+ 1个开始+ 1个停止)。 Then 100000 bytes will be collected in more than 104 seconds. 然后将在104秒内收集100000字节。 If the communication is not disrupted, your code should work. 如果通信没有中断,则您的代码应该可以工作。 To debug it, you can add this in your while loop: 要调试它,可以在while循环中添加它:

System.Threading.Thread.Sleep(1000); //sleep 1 second
Console.WriteLine("Total accumulated = " + bytesread);

However, a better approach is to use the DataReceived event of SerialPort : 但是,更好的方法是使用SerialPortDataReceived事件:

int buffersize = 100000;
SerialPort port = new SerialPort("COM3", 9600);

port.DataReceived += port_DataReceived;

// To be safe, set the buffer size as double the size you want to read once
// This is for the case when the system is busy and delays the event processing
port.ReadBufferSize = 2 * buffersize;

// DataReceived event will be fired when in the receive buffer
// are at least ReceivedBytesThreshold bytes
port.ReceivedBytesThreshold = buffersize; 
port.Open();

The event handler: 事件处理程序:

private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    // The event will also be fired for EofChar (byte 0x1A), ignore it
    if (e.EventType == SerialData.Eof)
        return;

    // Read the BytesToRead value, 
    // don't assume it's exactly ReceivedBytesThreshold
    byte[] buffer = new byte[port.BytesToRead];
    port.Read(buffer, 0, buffer.Length);

    // ... Process the buffer ...
}

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

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