简体   繁体   中英

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

I have Arduino connected to serial port. Arduino has the following simple code to send bytes:

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. But instead I can receive only nearly 12000 and after that ReadBufferSize doesn't change. The same problem occurs with all baud rates.

So how to read all 100000 bytes in buffer at once? 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). Then 100000 bytes will be collected in more than 104 seconds. If the communication is not disrupted, your code should work. To debug it, you can add this in your while loop:

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 :

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 ...
}

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