I use Serial.write()
to transmit 53 bytes to PC. For the time measurement I use micros()
(before and after the write function). There is a delay of 1s after each transmission.
The time of the Serial.write()
function is 532 us with 1000000 baud rate, and 360 us with 9600 baud rate.
The Serial.write()
function is clearly asynchronous because the transmission of 53 bytes with 9600 baud rate is 53*8/9600*1e6 = 44167 us. (By the way, in the case of 1000000 baud rate, it is not so obvious that the function is asynchronous.)
I use Serial.availableForWrite()
before Serial.write()
to confirm that there is enough space in the buffer (this returns 63 each time, the buffer size is default 64).
I don't understand these numbers. Using memcpy()
to copy the 53 bytes only takes 32 us. Is copying to the serial buffer not the same as the memcpy()
function? And why is there a difference in the copy times when the baud rate is different? Serial.write() is even slower with higher baud rates according to the results. Why does Serial.availableForWrite()
return 63 while the buffer size is 64 (according to SERIAL_TX_BUFFER_SIZE)?
Update: Thanks for all of your answers.
I have tried another library for serial communication: https://github.com/greiman/SerialPort
It seems to be faster than the original one. I use 2 time measurements and a delay in the code, these 3 deltaTimes represents the whole step as follows:
writeTime + memcpyTime + delaymicros = computedTime != realTime
The first 2 times are measured, the delaymicros is the theoretical delay (900 us), I can compute the step time from these. This computed step time is different from realTime (the measured step time, I measure the whole step too). It seems that the additional time can be found in the delay.
SerialPort library: 100 + 30 + 900 = 1030 != 1350
writeReal = 100 + 1350 - 1030 = 430
Arduino Serial: 570 + 30 + 900 = 1500 != 1520
writeReal = 570 + 1520 - 1500 = 590
Then I measured the delaymicros time (which is 900 us in theory), the missing time can be found there. I programmed 900 us delay, but the real delay was around 1200 in the first, and 920 in the second test.
These measurements can prove the existence of the interrupts, because measuring only the write functions doesn't give all of the writing time (especially with the downloaded serial library). The downloaded library can work faster, but requires bigger tx buffer because of errors (256 works properly instead of 64).
Here is the code: I use a checkSum in the sendig function (which is 570-532 = 38 us). I use Simulink to receive and process the data.
struct sendMsg1 {
byte errorCheck;//1
unsigned long dT1;//4
unsigned long dT2;//4
unsigned long t;//4
unsigned long plus[10];//40
};//53
sendMsg1 msg1;
byte copyMsg1[53];
unsigned long time1;
unsigned long time2;
unsigned long time3;
unsigned long time4;
void setup() {
Serial.begin(1000000);
}
void loop() {
sensorRead();
sendMsg1_f();
//time3 = micros();
delayMicroseconds(900);
//time4 = micros();
}
void sensorRead() {
time3 = micros();
msg1.t = micros();
for (unsigned long i = 0; i < 1; i++) {
memcpy((void*)&(copyMsg1[i*sizeof(sendMsg1)]), (void*)&msg1, sizeof(sendMsg1));
}
time4 = micros();
msg1.dT2 = time4 - time3;
}
void sendMsg1_f() {
time1 = micros();
msg1.errorCheck = 0;
for (int i = 0; i < sizeof(sendMsg1) - 1; i++) {
msg1.errorCheck += ((byte*)&msg1)[i];
}
Serial.write((byte*)&msg1,sizeof(sendMsg1));
time2 = micros();
msg1.dT1 = time2 - time1;
}