0

I am trying to receive data from a device via virtual COM port over USB. The device is basically a micro controller which continuously transmit few bytes of data. The baud rate is 921600. I can see the data on HyperTerminal as shown in image below:

Screenshot of receiving data

I have written a small code to receive this data:

    char[] charData = new char[1024];
    void ReadData()
    {
        while (true)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            for (int i = 0; i < 1024; i++)
            {
                charData[i] = (char)serialPort1.ReadChar();
            }
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);
            textBox1.Text = new string(charData);
        }
    }

I have called this code through a Thread. This code works fine when using lower baud rates (i.e 9600, tried using another microcontroller to simulate my desired data using lower baud rate). But is unable to work with higher baud rates. The code just simply doesn't receive any data and also doesn't generate any exception.

Please help my figure out this problem. Code sample is highly appreciated!

Thanks.

EDIT:

Serial Port configuration:

enter image description here

Microcontroller code: (The microcontroller is Arduino Due here is a code for reference):

void setup() 
{
  SerialUSB.begin(921600);
}

void loop() 
{
  SerialUSB.print("#A1G-5G11bng1");
}
Farid-ur-Rahman
  • 1,809
  • 9
  • 31
  • 47
  • 1
    You didn't show the serial port configuration code, but you're probably neglecting some important configuration options, like Handshaking. – Ben Voigt Apr 13 '23 at 18:55
  • Hi, Ben Voigt, Thanks for the reply. I have edited the question and added the missing details. Yes I am missing handshaking. – Farid-ur-Rahman Apr 13 '23 at 19:01
  • Wait, you don't have a real serial link on the microcontroller and a USB/serial converter, but it is a USB microcontroller? Baud rate is ignored in such a setup. Most configuration is ignored. – Ben Voigt Apr 13 '23 at 19:04
  • BTW, it's not great to read one byte at a time from a true serial port, and on a USB one it's a horrendous idea. Do you have any inkling how many bytes of overhead there are for a USB transfer? – Ben Voigt Apr 13 '23 at 19:05
  • Actually I am new to such things. I have tried reading byte by byte in the past and it worked. Yes the microcontroller has native USB interface but I appears as COM port when connected to the PC. – Farid-ur-Rahman Apr 13 '23 at 19:08
  • Dear Ben, "Do you have any inkling how many bytes of overhead there are for a USB transfer?" I am not able to understand this. I have a buffer size of 1024 bytes as defined in my C# code. – Farid-ur-Rahman Apr 13 '23 at 19:10
  • Your "microcontroller that appears as COM port" is entirely ignoring the serial configuration. Those options are available to virtual COM ports to support e.g. USB/serial converters that generate actual UART signalling at the other end, the baud rate tells them how fast their UART should run. You have no UART, no baud rate, no parity, no start and stop bits. You only have USB data transfers. – Ben Voigt Apr 13 '23 at 19:12
  • If talking to your device with a normal terminal emulator is working, and your C# isn't, the device must be working. In that case the most likely explanation is that the device sent less than 1024 bytes and is waiting for your next command, and therefore your `for` loop never completes. – Ben Voigt Apr 13 '23 at 19:13
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/253139/discussion-between-farid-ur-rahman-and-ben-voigt). – Farid-ur-Rahman Apr 13 '23 at 19:16
  • Dear Ben Voigt, with your help, I have found out the way to receive data a higher baud rates. Thank you so much for your very kind help. :-) – Farid-ur-Rahman Apr 13 '23 at 19:40

1 Answers1

0

Thanks to Ben Voigt idea of not reading data byte by byte, I have successfully managed to figure out the way, Here is my updated code function to read data:

    void ReadData()
    {
        byte[] bytesData = new byte[1024];
        while (true)
        {
            serialPort1.Read(bytesData, 0, 1024);
            char[] c = Encoding.UTF8.GetString(bytesData).ToCharArray();
            textBox1.Text = new string(c);
        }
    }

The code now read entire 1024 bytes of data at once and is efficient and faster then my previous approach of reading single byte of data at a time. All other configuration remained unchanged.

Farid-ur-Rahman
  • 1,809
  • 9
  • 31
  • 47
  • 2
    That code only works by accident, ignoring the return value of Read() is a bad idea. Use Serial.println() in the Arduino code, SerialPort.ReadLine() in C#. If you want utf8 then set the SerialPort.Encoding property. – Hans Passant Apr 13 '23 at 19:45