Maximum Baudrate of Native USB Port ? Increase Communication Speed ?

Hi guys,

I have a problem with my Zero. I should transfert a lot of datas by the native USB Port, I set the baudrate at 1843200 (2 megabaud).

SerialUSB.begin(1843200);
while (!SerialUSB) {};

And I try this to measure the communication time:

unsigned long Timer = micros();

SerialUSB.println(Data1); // Double (32 bits)
SerialUSB.println(Data2); // Unsigned Long (16 bits)
SerialUSB.println(Data3); // Byte (8 Bits)
      
Timer = micros() - Timer;
      
SerialUSB.println(Timer);

In my Putty Terminal (Serial Monitor of Arduino doesn't support 2 megabauds), the measure of the 3 datas tranfert is about 5000 µs.

Whereas, If I use the Programming port with the same (change SerialUSB to Serial), I have a transfert of only 160 µs which is correct for 2 megabauds.

So, how can i have the same time for the native usb port ?

It's possible the problem can be on my computer and not my arduino.

Thanks for your help :)

SerialUSB.begin is a dummy function : it does nothing and you don't even need it. The SerialUSB class is a special Serial instance which use the hardware USB peripheral : the speed will always be as fast as the device can go, I think.

I think I have understood, SerialUSB emulates Serial Port using CDC.

On hardware\samd\cores\arduino\USB\CDC.cpp I've found this :

static volatile LineInfo _usbLineInfo = {
    115200, // dWDTERate
    0x00,   // bCharFormat
    0x00,   // bParityType
    0x08,   // bDataBits
    0x00    // lineState
};


...


Serial_ SerialUSB(USBDevice);

Maybe I'm wrong, but when I change the dWDTERate to 1843200, my computer recognize the arduino but can't find the drivers (it thinks that's a new device which try connection)

You could try to call SerialUSB.baud() to get the actual baudrate and see if it is in fact limited at 115200. (Not tested)

Indeed, I have a result of 115200..

No possibility to change this ?

baudrate = SerialUSB.baud();
SerialUSB.println(baudrate);

Also, I have exactly the same result when I do begin(9600). Always a baudrate of 115200.

But is the baud rate actually used?

On other boards, CDC transfers data at the full USB speed, but the USB only transports packets as rapidly as one side can create them and the other side can consume them. Arduino Zero probably works the same way.

Normally (other boards) the baud rate setting can be read in your sketch, even though it's not actually used by CDC, so you can use it to configure the real hardware serial baud rate. That allows you to make a USB-serial converter, where the hardware serial gets set to whatever the PC-side software wants.

Nope, I have just tried this sketch to measure a transfert time with different baudrates set in CDC.cpp

void setup() {
  SerialUSB.begin(9600); //115200 921600 1843200 etc..
  while (!SerialUSB) {};
}

void loop() {
  // put your main code here, to run repeatedly:
  unsigned long timer = micros();

  for (int i = 0; i < 1000; i++) {
    SerialUSB.println(i);
  }

  SerialUSB.println(micros() - timer);
  delay(10000);
}

This is my results
9600 :

  • 1.974036 s
  • 1.963778 s
  • 1.938866 s

115200 :

  • 1.984935 s
  • 1.971971 s
  • 1.928075 s

921600 :

  • 1.973776 s
  • 1.994513 s
  • 1.995619 s

I have always a time about 2 sec with any baudrate set in CDC.cpp…

But however I have found this in conf_usb.h

//! Default configuration of communication port
#if BOARD == UC3B_BOARD_CONTROLLER
#define  UDI_CDC_DEFAULT_RATE             57600
#else
#define  UDI_CDC_DEFAULT_RATE             115200
#endif
#define  UDI_CDC_DEFAULT_STOPBITS         CDC_STOP_BITS_1
#define  UDI_CDC_DEFAULT_PARITY           CDC_PAR_NONE
#define  UDI_CDC_DEFAULT_DATABITS         8

Maybe it’s here to “real” setting of the CDC baudrate, but I don’t know how to regenerate the .hex file to reprogram the bootloader of the zero.

Something is very wrong with your computer. This should never take 2 seconds to complete!

I just ran it here on Zero. I viewed with the Arduino Serial Monitor. I'm running 64 bit Linux on a desktop machine with i7-3930K CPU. It prints 56712, which is 0.056 seconds.

For comparison, I ran it on 6 different boards. Here are the results:

Zero            56712
Due             15776
Teensy LC       12378
Teensy 3.2      5640
Leonardo        162044
Teensy 2.0      35088

Aside from the fact that all of these are much faster than 2 seconds, they also really show how the CPU speed and efficiency dramatically affect performance. CDC uses the native USB speed, not a fixed (slow) baud rate, but the actual speed depends on the code because CDC uses end-to-end flow control.

What is your terminal ?

I have exactly 423635 with the Programmer Port on the Arduino Zero and Serial.begin(115200). But when I use the Native Port (which is configured with 115200), I have really the results on my last post using Arduino Serial Monitor or Termite with 2 differents computer.

|500x180

Here’s a screenshot of what I see.

screen.png

Your screenshot says "Arduino M0 Pro" in the title of the serial monitor window. Maybe you're using software from Arduino.org, rather than Arduino.cc? Perhaps that could be the problem?

Okay, the problem may be there. Indeed, I have one M0 Pro from arduino.org which exactly the same hardware board than the Zero from .cc (There is just 2 pins inverted). I have this board, because in the futur I'll transfer an other code in a M0 Board (Light version of the M0 Pro) which is the only arduino board operating in -40 to +85°C temperature range.

So I think there is something wrong with .org library for the configuration of the CDC. I'll check this ;)

I just tried Arduino.org's 1.7.10 software. It can't upload at all to the native port on Arduino Zero. It does upload to the programming port, but nothing 1.7.10 builds seems to run on Zero, not even LED blink.

Perhaps these 2 boards aren't as similar as they might seem?

Digital #2 and #4 are swapped and the boards have different bootloaders. And I think, the difference is in the bootloader files.

I have seen somewhere on this forum, that is possible to use the M0 Pro on the arduino.cc IDE 1.6.9.

I do not have a M0 Pro board. I only have Arduino Zero.

The Zero board does work with Arduino.cc 1.6.9, but it does not work at all with Arduino.org 1.7.10. Even the programming port using Atmel's EDBG chip, which does upload with 1.7.10, doesn't result in the programs compiled by 1.7.10 actually running properly on Zero (at least with the board I have here).

Did you try running your program on your M0 Pro using Arduino.cc 1.6.9? Does it make a speed difference?

@Paul The bootloader of the M0/M0 Pro is 16KB, VS 8KB for the Zero. So you manage to upload the program, but as soon as the Zero bootloader jumps to application, it jumps at adress 0x4000 + 4 instead of 0x8000+4, that's why the program doesn't execute : this memory space contains no code.

I made it work the Arduino M0 Pro on IDE 1.6.9. just burning the bootloader using this simple procedure from a post of BenStlr on this forum :

So, it took me 15 seconds to "turn" it into Zero(means to use this website IDE) -Download the Zero board to the IDE (in the boards menu) -Chose it from the boards menu -Chose Atmel EDBG programmer -Burn the boot loader, and it just worked

Now my M0 Pro seems work properly. I don't change the digital pin #2 to #4. And I have better result with the SerialUSB (2 sec to 0.2 sec) but it requires new driver installation.

|500x312

So it's looking like Arduino.org's CDC code is horribly slow, right?

Your result at 185974 us is still much slower than 56712 us I measured, but perhaps that's just the difference between Linux vs Windows?

I have a strong interest in optimizing CDC performance.... you can can probably see in the results I posted on msg #7. ;)

Exactly...

Yeah, it's a possibility for the difference with your board, I'm using Windows 7 Pro with an Intel Core i7-4770 at 3.40 GHz.

Moreover, here the 2 files CDC.cpp from arduino.cc and .org.

- CDC.cpp from Arduino.org

- CDC.cpp from Arduino.cc

I'll search the difference between the two files. I have best performances, but it's not enough for my project, I need to transfert 12kbytes/sec by the Native Port :sweat_smile:

loicb38: I need to transfert 12kbytes/sec by the Native Port :sweat_smile:

Your test transmits approx 5000 bytes in 0.2 seconds, with Arduino.cc's faster CDC code. That's 25 kbytes/sec, or about double your 12 kbytes/sec requirement.

Due & Teensy LC & 3.2 are much faster in my tests, and my test with Zero on Linux was also faster, but even Zero with Windows seems good enough if you only need 12k/sec.