The Arduino Serial writes one byte at a time. There is a method for
writing a buffer of arbitrary length, but all this method does is
repeatedly call write(uint8_t) for each byte within the
buffer:
size_t Print::write(const uint8_t *buffer, size_t size)
{
size_t n = 0;
while (size--) {
if (write(*buffer++)) n++;
else break;
}
return n;
}
Notice that there is no waiting between the bytes.
If you do not fill the transmit buffer, this should be very fast: all
write(uint8_t) does is push the byte into a ring buffer. Unless your
timings are at the microseconds level, you can just send the six bytes
at once.
I've heard the Serial library processes 16bits (2bytes) at a time?
Very dubious. Do you have a reference for this statement?
Edit: If you are struggling with microsecond-range timings, you could send the bytes by directly writing to the UART data register, instead of relying on the Arduino core library to do so. In order to do this, you would:
Disable the "USART, Data Register Empty" interrupt, which is the interrupt used by the Arduino core for sending the bytes to the port.
Before sending a byte, test the "USART, Data Register Empty" flag in order to know whether the UART is ready to accept a byte for sending.
Write the byte you want to send directly into the UART data register, thus completely bypassing the TX buffer used by the Arduino core.
By bypassing the ring buffer and associated interrupt, you should be able to win a few microseconds this way.
Here is a version of your example code using this approach:
const uint8_t MSG_LEN = 6;
uint8_t snd_buffer[MSG_LEN];
uint32_t us_now = 0L;
uint8_t snd_byte_cnt = MSG_LEN;
uint8_t dummy_var = 0;
void setup() {
Serial.begin(115200);
UCSR0B &= ~_BV(UDRIE0); //disable "USART, Data Register Empty" interrupt
delay(1000);
}
void loop() {
us_now = micros();
operation_dummy();
com_dummy();
//the aim is to use no delay functions
}
void com_dummy(){ //ex communication
if (snd_byte_cnt < MSG_LEN && bit_is_set(UCSR0A, UDRE0)){ //bytes need to be sent and can be sent
UDR0 = snd_buffer[snd_byte_cnt]; //send the target byte
snd_byte_cnt++; //move to the next byte ind
} //else nothing to be sent
}
void operation_dummy() { //ex operation
dummy_var++; //do something (time sensitive in reality)
if (snd_byte_cnt == MSG_LEN){ //if no data pending to be sent
* (uint32_t *) &snd_buffer[1] = us_now; //modify buffer between 1st and 5th bytes (both inclusive)
snd_buffer[MSG_LEN - 1] = dummy_var;
snd_byte_cnt = 0; //trigger start sending
} //else wait for next cycle to send
}