Arduino Due Firmware Flaw: Problem With Using The USB Programming Port At 230400 Baud And Beyond
One of the improvements that came with the Arduino IDE's updates was an increased baud rate for the Serial Monitor.
Well, there are many time-sensitive applications that will benefit from the speed gain, specifically when using one of the fastest Arduinos around, the Arduino Due with its ARM Cortex M3 processor.
However, when you set the Serial Monitor to 230,400 baud (the maximum is 250,000 but that is not a standard rate), you will be in for an unpleasant surprise.
Have a look at the image to the left. It represents an extremely simple program: In the setup() routine we set the baud rate to 230,400 and in the loop() section we print the ever-popular "Hello World!" with a one-second frequency. Easy enough, right? However, the result is disastrous:
So what is the problem? The answer is easy (even though it took me quite some efforts to find out): The underlying ARM Cortex M3 code in the Setup.begin command, specifically the baud rate initialization, contains a bug that has been spread through the entire ARM community (including, just to name one very popular example, the Raspberry Pi). For more information see my post ARM Cortex Processors – UART Programming Problem At Baud Rates Higher Than 115200.
Just to stress the point, the initialization of the Due's Programming Port is wrong, while the Serial Monitor software is initialized correctly according to standard. In all consequence, the difference of the timing between the embedded Due board and the Serial Monitor is enough to cause problems.
If your application requires using the serial Programming Port at baud rates higher than 115,200, there are a few un-attractive options:
- Write your own C/C++ code to initialize the UART port, which requires good knowledge of ARM Cortex M3 programming.
- Use the Native USB port per SerialUSB command, which provides the maximum USB speed. However, handling the Native USB port comes with some obstacles by itself, and I will post another article about them.
Nevertheless, there is an almost stupid but reliably working solution: Initialize the port using a baud rate of 210,000: Serial.begin(210000);... And yes, it works!
Following a hunch, I wrote a simple program that utilized the Serial.begin() command using different baud rates, i.e. rates from 90% to 110% of 230,400 in increments of 1%. After each Serial.begin(), I printed "Hello World!" and looked at the result. Turns out that the communication works between 90% (207,360) and 94% (216,576), and I chose 210,000 as the closest round number.
For those who are interested in running even higher than 230,400:
- I haven't tested the 250,000 baud rate, since it's not a standard rate.
- Initializing the port to 460,800 works without problems (I tested using the RealTerm software under Windows 10).
- The Serial.begin() command does not support a baud rate of 921,600 whatsoever (I suspect that there is an undocumented limitation in the underlying code).
Serial Port Complete: COM Ports, USB Virtual COM Ports, and Ports for Embedded Systems
PC COM ports, USB virtual COM ports, and ports in embedded systems are all addressed in this updated guide to programming, interfacing, and using serial ports.
Topics include using .NET’s SerialPort class for COM-port communications on PCs; upgrading existing RS-232 designs to USB or wireless networks; and creating serial networks of embedded systems and PCs.
Example circuits and code provide a quick start to projects. Installation and maintenance staff will also find tips for ensuring reliable operation and problem tracking.