Arduino Serial library (Synchronous or Asynchronous?)

On an Arduino 101, I have this code running:

void setup()
{
pinMode(2, INPUT);
Serial.begin(9600);
}

int counter = 0;

void loop()
{
Serial.print(millis()/1000);
Serial.print("\t");
Serial.print(counter);
Serial.print("\t");
counter++;
}


A wire can be used to jump Pin2 between 3.3V and GND.

When running with the Serial Monitor on, I see the values increment at a rate where counter increases by the hundreds very quickly and steadily ticks through the thousands over time.

If I close Serial Monitor momentarily and re-open it, I notice that this counter value has increased dramatically (by the tens-of-thousands). Another sign of this is when starting the program and waiting a moment to start the Serial Monitor. As the Arduino 101 does not restart when the Serial Monitor is opened, I see a large initial value in the tens of thousands despite having just started the program.

My question is this: is the Serial library operating synchronously or asynchronously? I was led to believe that it was asynchronous; however, if that was the case, why should the Arduino execute any slower when the serial monitor is on?

While I understand that increasing baud rate will increase the speed at which counter increases, I still see the same dramatic increase in this code when the monitor is closed and then re-opened.

Another possibility I thought of was that maybe counter was being stored in a buffer and what I was seeing was not an up-to-date time or count. To check this, the program prints the digitalRead value of pin2 as I swap the jumper between 3.3v and GND. This change in value was reflected instantaneously on the Serial Monitor, and I believe this means I am not seeing past data slowly being printed out to the monitor.

One last attempt at understanding what was going on was executing this code:

void setup()
{
pinMode(2, INPUT);
Serial.begin(9600);
}

int counter = 0;

void loop()
{
counter++;
if (counter%1000==0)
{
Serial.println(counter);
}


In this example, counter can be seen ticking through quite fast, by the hundreds of thousands, which indicates that the program is capable of running very quickly until a print statement is made. The effect is notably less when baud rate is increased to something like 115200 but is that saying that baud rate is literally slowing the processing speed of the controller?

Any kind of explanation as to what exactly is going on would be very appreciated.

Source of Arduino being supposedly Asynchronous: https://itp.nyu.edu/physcomp/lessons/serial-communication/serial-communication-the-basics/

migrated from electronics.stackexchange.comAug 3 '16 at 23:09

This question came from our site for electronics and electrical engineering professionals, students, and enthusiasts.

The Arduno 101 doesn't communicate to the PC using a UART. It uses CDC/ACM over USB, which looks like a UART to the PC. But it isn't.

• USB sends packets of data, not individual characters
• It only sends if there is something to receive it at the other end
• There is no such thing as baud rate with USB.

Basically, when the CDC/ACM port has been opened by an application (e.g., the serial monitor) the Arduino 101 starts to send the data down the line. When the port is closed all data to be sent gets silently dropped by the Arduino since there is nowhere to send it to.

Hence when the port is closed it runs much faster since the data that would normally have to be packed into packets and sent down USB isn't. It's just thrown away.

You are misunderstanding the concept of synchronous and asynchronous with regards to serial. There are basically two types of serial communication: Asynchronous, where both ends have to (pretty precisely) agree on the speed of communication (baud rate), and synchronous, where one end tells the other end what the speed is by providing a discrete clock signal. UART (RS-232, RS-485, etc) is asynchronous. It sends at a specific rate and has to rigidly stick to that rate for the other end to be able to receive it properly. SPI and I2C are synchronous - they both (as master) provide a clock signal to the receiving end (slave) and the receiver synchronises its reading and writing of data with that clock signal (hence synchronous).

You are confusing those concepts with another meaning of synchronous and asynchronous - terms that could better be used would be parallel and sequential processing. If something happens in parallel then two (or more) things happen at once. This is the case of the hardware UART where you submit characters to be sent to the buffer and they get transmitted out by the hardware separately to the sketch - in parallel. Sequential would mean that one thing has to happen after the other. If the UART behaved like that your program would stall every time you wanted to send a single character.

So UART processing happens in the background, in parallel to your sketch. So does USB data processing for CDC/ACM. These things are generally coupled with interrupts to allow the CPU to handle tasks such as placing more data in the buffer or storing data that has arrived somewhere that you can get to it. Interrupts aren't strictly parallel, in that they do stall your program while they run, but they are kind of in a different thread, or context. So they appear to be parallel.

• Your explanation of the CDC/ACM being the cause makes alot of sense but from what I'm seeing, adjusting the baud rate in the program makes quite a difference in the rate at which information is displayed. Do you have any explanation as to why this has an effect? Are the packets simply being filled with more information before they're sent at some other rate? – Cablenot Aug 4 '16 at 15:02
• Maybe the 101 is doing some artificial throttling to make it seem like the baud rate is real. Who knows? Baud rate is meaningless (normally) though since the USB runs at a constant rate. The baud rate setting is only (normally) used to configure whatever device is at the end of the USB connection - e.g., if the data is being forwarded on to a real UART output it would configure that UART output for the requested baud rate. – Majenko Aug 4 '16 at 15:04

The Universal asynchronous receiver/transmitter (UART) is a chip that control the actual wires for serial communication. The UART operates independently and asynchronously.

As far as I know the UART (or USART) has a buffer, and the serial.print* functions will write to this buffer, and if it is full will block until the buffer has room. The UART will consume the buffer and transmit it over the wire. So your code will run full speed until the buffer is full then it will have to wait for the UART to make space.

... but is that saying that baud rate is literally slowing the processing speed of the controller?

When the UART's buffer becomes full, the Serial API has no choice but to wait for the buffer to empty so it can fill it again. This makes it appear as if the code is running synchronously; waiting on the buffer is essentially acting as a synchronization device. So yes a slow baud rate can slow the micro-controller down since the code is forced to wait for the UART even though it is asynchronous!

You may not notice any of the above effects, since even 9600, a relatively slow rate, is much faster than humans can read. 300 baud is approximately the rate at which humans can read comfortlably. If you repeat your experiments with a higher baud rate you should see the text fly past on the serial monitor much faster than at 9600; if you lower the speed to 300 (the lowest supported by the library) you should be able to read along, and see that things do go slower. The buffer on the UART is rather small, and even when slowing down to 300 baud, it might be difficult to see the buffering behavior.

When the serial monitor is closed the serial communications are still happening, the UART on the receiving side is receiving the data, but it gets dropped on the floor since no one is reading it. If you were to disconnect the serial wires at some point this should stall the sending UART which should cause the serial.print* functions to block (alternatively the UART could be configured to drop the data if it can't physically transmit it over the wire.)

• I went ahead and tried setting baud rate to 300 as you suggested. It is more than easily legible; however, I still find that moving between 3.3V and GND, the change is instantaneous. With that being said, I do agree that baud rate does seem to affect the rate at which the microcontroller runs as counter's increase is dramatically slowed. So in short, I don't think there's a buffer being filled and drained but instead maybe the baud rate effects the timing for how long the Arduino waits while in the Serial.print() statement. – Cablenot Aug 4 '16 at 16:19