It depends. Serial data is received into, or sent from, buffers (one for sending and one for receiving). If you have a processor with 1024 bytes of RAM or more, then the buffer size is 64 bytes, otherwise it is 16 bytes. (See the HardwareSerial.h file in your distribution).
If the buffer fills up when sending, it will block (that is, the code will wait for the buffer to empty). If it fill up when receiving the extra bytes will be discarded.
If the buffer does not fill up, then the baud rate will not affect performance. That is because data is sent, or received, by an interrupt service routine, in the background.
As a rule of thumb, you can expect data to be sent or received at the baud rate divided by 10. That is because each byte is 8 bits, plus a start and a stop bit (10 bits in total).
So, for example, at 9600 baud you can send 960 characters per second. If you are sending something simple, like a temperature which is 20 bytes, every second, then the baud rate won't affect performance at all. If you are trying to send thousands of bytes per second, it will affect performance, because the Serial.println will probably block once the buffer fills up.
For instance, when I call Serial.prinlnt("test"), how does that get to the serial line?
If the buffer is not full, then "t" "e" "s" "t" are copied into the buffer, and the code returns immediately. If the buffer is full then it waits for it to become not-full.
As an efficiency measure, if you are sending a single byte, and the buffer is empty, then the byte is placed in the hardware register immediately (saving a small amount of time). In this case, if the buffer was empty, "t" would be sent immediately, and "est" would be sent afterwards, as a "byte has been sent" interrupt is raised.1
This is described in the code comments:
size_t HardwareSerial::write(uint8_t c)
{
_written = true;
// If the buffer and the data register is empty, just write the byte
// to the data register and be done. This shortcut helps
// significantly improve the effective datarate at high (>
// 500kbit/s) bitrates, where interrupt overhead becomes a slowdown.
if (_tx_buffer_head == _tx_buffer_tail && bit_is_set(*_ucsra, UDRE0)) {
*_udr = c;
sbi(*_ucsra, TXC0);
return 1;
}
tx_buffer_index_t i = (_tx_buffer_head + 1) % SERIAL_TX_BUFFER_SIZE;
// If the output buffer is full, there's nothing for it other than to
// wait for the interrupt handler to empty it a bit
while (i == _tx_buffer_tail) {
if (bit_is_clear(SREG, SREG_I)) {
// Interrupts are disabled, so we'll have to poll the data
// register empty flag ourselves. If it is set, pretend an
// interrupt has happened and call the handler to free up
// space for us.
if(bit_is_set(*_ucsra, UDRE0))
_tx_udr_empty_irq();
} else {
// nop, the interrupt handler will free up space for us
}
}
_tx_buffer[_tx_buffer_head] = c;
_tx_buffer_head = i;
sbi(*_ucsrb, UDRIE0);
return 1;
}
Notice that the byte is not placed in the buffer at all if it is empty, and nothing is being sent.
For more information see my question and answer about serial processing.
- Strictly speaking, after discussing this in the comments with Majenko, the interrupt that is raised is really that the hardware "send" buffer is empty. When the send buffer empties then the interrupt is called so that the interrupt code can put a new byte into it.
As an efficiency measure, if you are sending a single byte, and the buffer is empty, then the byte is placed in the hardware register immediately (saving a small amount of time).- actually that's not for the sake of efficiency - that's done so that a TX interrupt can be raised - otherwise you put stuff in the buffer and the TX interrupt never triggers (because there is nothing in the TX FIFO to send) and so the buffer never empties. You need that first manual entry in the TX FIFO to start the ball rolling. – Majenko Sep 27 '16 at 09:44write()which, if the transmit buffer is empty triggers the ISR to fill it. If it has triggered during the firstifand the buffer has been filled with the last byte in the ring buffer the IF will fail, it will fall through to placing the byte into the ring buffer, and the next time the interrupt fires it will be picked up. If it was the last time the interrupt would fire (empty ring buffer) then the interrupt is re-enabled anyway and fires because the TX buffer is empty. – Majenko Sep 27 '16 at 22:22otherwise you put stuff in the buffer and the TX interrupt never triggers. You agree that the TX complete interrupt is not the important one, but rather it is the TX buffer empty one? I just checked with a test program. There is no TX complete interrupt handler generated. The only thing it is interested in is the TX buffer being empty. Thus your statement that "the buffer never empties" because the "TX interrupt never triggers" is not correct. – Nick Gammon Sep 27 '16 at 22:55