I am using serial.write in my code to write to serial port at 115200 baud. I measured the time it takes to perform 4 such write operations and I don't understand what's really happening.
The code is;
unsigned long Timer=micros();
int a=10;
Serial.write(a);
//Serial.write(a);
//Serial.write(a);
//Serial.write(a);
Timer=micros()-Timer;
Serial.println(",,");
Serial.println(Timer);
;
When I run this code, the time it shows is 3 micro seconds. When I un-comment the 2nd write function, it shows 4. But when I un-comment the 3rd one, the time jumps to 90 micro seconds. I thought it should be a bit more but its not. Un-commenting the 4th function makes it go up to 170 microseconds.
Can someone explain it to me about what's happening? I am using arduino zero.
Serial returns immediately if the associated buffer is not full and handles things with interrupts at lower level so your code does not really measure anything meaningful
I’m not sure how you run this code, It is not a full program. Show us the rest
Serial.write() (and everything above it) maintains a software buffer of ~64 bytes in each direction. If you do a Serial.write() when the buffer is NOT full, all that happens is that the byte is copied into that buffer, and the number of cycles taken is quite small (3us sounds about right.)
If the buffer IS full, then write() waits for some room to become available, which happens when a character that WAS in the buffer finishes transmitting, and the Interrupt-level driver removes the next byte from the buffer and starts it transmitting. This happens dependent on the bitrate of the serial connection - about 90us per byte at 115200 is again "about right."
knowing that On 16 MHz Arduino boards the micros() function has a resolution of four microseconds (i.e. the value returned is always a multiple of four) - there is really nothing too weird about it (and understanding what's happening in the background)
The SAMD core apparently does not have the buffer I was talking about (rather shockingly!)
So for one byte, you get to stuff it into the uart transmit register and return immediately. but for more than one byte you get to wait and are throttled by the actual transmit speed.
On a Zero you need to ensure the SAMD21 will wait for the SerialUSB port to open before executing the sketch. Can you add to the setup()
Serial.begin(115200);
while (!Serial);
and try again?
I don’t have my Zero with me but it has various Serial (and two physical connections)
Serial - Programming Port (the path is SAMD->uart->EDBG->usb->PC) Serial1 - Serial uart on pins 0 and 1 SerialUSB - Native Port, this is an emulated serial port (USB-CDC)
If you are using SerialUSB and you want to see the data sent by the micro put this code at the beginning of the sketch to make the CPU wait for the opening of the serial monitor:
SerialUSB.begin(115200);
while (!SerialUSB);
(if you don’t open the monitor your sketch will be stuck there though)