Why is Serial.Write that slower when writing x+1 characters than when it is writing x characters?
Clash Royale CLAN TAG#URR8PPP
up vote
4
down vote
favorite
Using Serial.Write()
in a time sensitive application. I realize that the number of characters being written not only had an impact on the time spent writing in the buffer, but actually had a bigger impact than expected.
Consider the following sketch, which measures the time it takes to write NB_CHARS characters, using Serial.Write()
. I sampled 1000 times in order to get a more reliable measure.
#define NB_CHARS 100
void setup()
Serial.begin(115200);
uint8_t chars[NB_CHARS];
for (int i=0; i<NB_CHARS; i++)
chars[i] = 66;
unsigned long time1, time2;
unsigned long totalTime = 0;
delay(100);
for (int i=0; i<1000; i++)
time1 = micros();
Serial.write(chars, NB_CHARS);
time2 = micros();
totalTime += time2 - time1;
delay(10);
Serial.println("");
delay(10);
float meanTime = (float)totalTime / 1000.0f;
Serial.print("meanTime = ");
Serial.println(meanTime);
void loop()
Here are some results for different NB_CHARS values:
NB_CHARS: Time (microseconds)
1: 12
2: 18
3: 24
[...]
99: 2912
100: 2997
101: 3082
[...]
199: 11412
200: 11497
201: 11582
It seems that at first, each new character adds around 6 microseconds of delay, but afterward it becomes 85 microseconds. I tested every values from 1 to 100 to find where it changes and it seems to be right after 70:
It seems weird to me.
A quick Google search gets me to this 2013 post by Tom Carpenter. I am not sure how true this is or if it is still relevant.
Part of the trouble is that the Hardware Serial library is so
incredibly inefficient (I don't think they could have made it less
efficient if they tried!). After each byte is sent, there is an
interrupt called which spends a lifetime loading the next byte into
the buffer to send. The write function also wastes lots of time doing
calculations as to where to put a character in a ring buffer.
[...]
Why is there such a "long" delay for each character and is there a way to make it faster?
What happens after 70 characters that slows it down even further?
serial performance
add a comment |Â
up vote
4
down vote
favorite
Using Serial.Write()
in a time sensitive application. I realize that the number of characters being written not only had an impact on the time spent writing in the buffer, but actually had a bigger impact than expected.
Consider the following sketch, which measures the time it takes to write NB_CHARS characters, using Serial.Write()
. I sampled 1000 times in order to get a more reliable measure.
#define NB_CHARS 100
void setup()
Serial.begin(115200);
uint8_t chars[NB_CHARS];
for (int i=0; i<NB_CHARS; i++)
chars[i] = 66;
unsigned long time1, time2;
unsigned long totalTime = 0;
delay(100);
for (int i=0; i<1000; i++)
time1 = micros();
Serial.write(chars, NB_CHARS);
time2 = micros();
totalTime += time2 - time1;
delay(10);
Serial.println("");
delay(10);
float meanTime = (float)totalTime / 1000.0f;
Serial.print("meanTime = ");
Serial.println(meanTime);
void loop()
Here are some results for different NB_CHARS values:
NB_CHARS: Time (microseconds)
1: 12
2: 18
3: 24
[...]
99: 2912
100: 2997
101: 3082
[...]
199: 11412
200: 11497
201: 11582
It seems that at first, each new character adds around 6 microseconds of delay, but afterward it becomes 85 microseconds. I tested every values from 1 to 100 to find where it changes and it seems to be right after 70:
It seems weird to me.
A quick Google search gets me to this 2013 post by Tom Carpenter. I am not sure how true this is or if it is still relevant.
Part of the trouble is that the Hardware Serial library is so
incredibly inefficient (I don't think they could have made it less
efficient if they tried!). After each byte is sent, there is an
interrupt called which spends a lifetime loading the next byte into
the buffer to send. The write function also wastes lots of time doing
calculations as to where to put a character in a ring buffer.
[...]
Why is there such a "long" delay for each character and is there a way to make it faster?
What happens after 70 characters that slows it down even further?
serial performance
set higher baud rate. at least 460800 baud should go with good connections.
â Juraj
Sep 10 at 20:18
the quote is not true anymore. at bit rates over 500kbit/s the interrupt is not used if the buffer is empty. (bit rate, not baud rate)
â Juraj
Sep 10 at 20:21
add a comment |Â
up vote
4
down vote
favorite
up vote
4
down vote
favorite
Using Serial.Write()
in a time sensitive application. I realize that the number of characters being written not only had an impact on the time spent writing in the buffer, but actually had a bigger impact than expected.
Consider the following sketch, which measures the time it takes to write NB_CHARS characters, using Serial.Write()
. I sampled 1000 times in order to get a more reliable measure.
#define NB_CHARS 100
void setup()
Serial.begin(115200);
uint8_t chars[NB_CHARS];
for (int i=0; i<NB_CHARS; i++)
chars[i] = 66;
unsigned long time1, time2;
unsigned long totalTime = 0;
delay(100);
for (int i=0; i<1000; i++)
time1 = micros();
Serial.write(chars, NB_CHARS);
time2 = micros();
totalTime += time2 - time1;
delay(10);
Serial.println("");
delay(10);
float meanTime = (float)totalTime / 1000.0f;
Serial.print("meanTime = ");
Serial.println(meanTime);
void loop()
Here are some results for different NB_CHARS values:
NB_CHARS: Time (microseconds)
1: 12
2: 18
3: 24
[...]
99: 2912
100: 2997
101: 3082
[...]
199: 11412
200: 11497
201: 11582
It seems that at first, each new character adds around 6 microseconds of delay, but afterward it becomes 85 microseconds. I tested every values from 1 to 100 to find where it changes and it seems to be right after 70:
It seems weird to me.
A quick Google search gets me to this 2013 post by Tom Carpenter. I am not sure how true this is or if it is still relevant.
Part of the trouble is that the Hardware Serial library is so
incredibly inefficient (I don't think they could have made it less
efficient if they tried!). After each byte is sent, there is an
interrupt called which spends a lifetime loading the next byte into
the buffer to send. The write function also wastes lots of time doing
calculations as to where to put a character in a ring buffer.
[...]
Why is there such a "long" delay for each character and is there a way to make it faster?
What happens after 70 characters that slows it down even further?
serial performance
Using Serial.Write()
in a time sensitive application. I realize that the number of characters being written not only had an impact on the time spent writing in the buffer, but actually had a bigger impact than expected.
Consider the following sketch, which measures the time it takes to write NB_CHARS characters, using Serial.Write()
. I sampled 1000 times in order to get a more reliable measure.
#define NB_CHARS 100
void setup()
Serial.begin(115200);
uint8_t chars[NB_CHARS];
for (int i=0; i<NB_CHARS; i++)
chars[i] = 66;
unsigned long time1, time2;
unsigned long totalTime = 0;
delay(100);
for (int i=0; i<1000; i++)
time1 = micros();
Serial.write(chars, NB_CHARS);
time2 = micros();
totalTime += time2 - time1;
delay(10);
Serial.println("");
delay(10);
float meanTime = (float)totalTime / 1000.0f;
Serial.print("meanTime = ");
Serial.println(meanTime);
void loop()
Here are some results for different NB_CHARS values:
NB_CHARS: Time (microseconds)
1: 12
2: 18
3: 24
[...]
99: 2912
100: 2997
101: 3082
[...]
199: 11412
200: 11497
201: 11582
It seems that at first, each new character adds around 6 microseconds of delay, but afterward it becomes 85 microseconds. I tested every values from 1 to 100 to find where it changes and it seems to be right after 70:
It seems weird to me.
A quick Google search gets me to this 2013 post by Tom Carpenter. I am not sure how true this is or if it is still relevant.
Part of the trouble is that the Hardware Serial library is so
incredibly inefficient (I don't think they could have made it less
efficient if they tried!). After each byte is sent, there is an
interrupt called which spends a lifetime loading the next byte into
the buffer to send. The write function also wastes lots of time doing
calculations as to where to put a character in a ring buffer.
[...]
Why is there such a "long" delay for each character and is there a way to make it faster?
What happens after 70 characters that slows it down even further?
serial performance
serial performance
edited Sep 11 at 8:29
Peter Mortensen
288211
288211
asked Sep 10 at 18:45
Alex Millette
1264
1264
set higher baud rate. at least 460800 baud should go with good connections.
â Juraj
Sep 10 at 20:18
the quote is not true anymore. at bit rates over 500kbit/s the interrupt is not used if the buffer is empty. (bit rate, not baud rate)
â Juraj
Sep 10 at 20:21
add a comment |Â
set higher baud rate. at least 460800 baud should go with good connections.
â Juraj
Sep 10 at 20:18
the quote is not true anymore. at bit rates over 500kbit/s the interrupt is not used if the buffer is empty. (bit rate, not baud rate)
â Juraj
Sep 10 at 20:21
set higher baud rate. at least 460800 baud should go with good connections.
â Juraj
Sep 10 at 20:18
set higher baud rate. at least 460800 baud should go with good connections.
â Juraj
Sep 10 at 20:18
the quote is not true anymore. at bit rates over 500kbit/s the interrupt is not used if the buffer is empty. (bit rate, not baud rate)
â Juraj
Sep 10 at 20:21
the quote is not true anymore. at bit rates over 500kbit/s the interrupt is not used if the buffer is empty. (bit rate, not baud rate)
â Juraj
Sep 10 at 20:21
add a comment |Â
3 Answers
3
active
oldest
votes
up vote
12
down vote
accepted
The Arduino core has a 64 byte transmission buffer. Characters are sent out of that buffer by the hardware.
When you blast lots of characters out of serial the first 64 just get put into that buffer - almost instantly.
Once that buffer is full your sketch blocks until the hardware has sent a character to make room.
Since it's sending right from the moment you place the first character into the buffer you get a little more than 64 bytes worth of buffering time (64 + the number that have been sent by the time the buffer fills).
From that point on you are entirely at the mercy of the baud rate you have chosen.
To get more predictable throughput (and maximise the speed) you should bypass the Ardiuno core and manipulate the UART registers directly.
"you should bypass the Ardiuno core and manipulate the UART registers directly". Any good library for this?
â Alex Millette
Sep 10 at 18:59
5
@AlexMillette Ummm... no. That's the whole point. You will be avoiding any library / core functions and using the registers directly. Read the datasheet.
â Majenkoâ¦
Sep 10 at 19:02
2
I think it would be handy @Majenko if you could point Alex at some example code....
â boatcoder
Sep 11 at 1:25
3
There is a fair chance that once you bypass the core, your code will run as slow as the right part, and not as fast as the left one.
â IMil
Sep 11 at 3:27
1
For smooth serial communication you really want an MCU with DMA to do the transfers for you...
â Majenkoâ¦
Sep 11 at 9:21
 |Â
show 1 more comment
up vote
3
down vote
Majenko already gave the right answer: as soon as the buffer is full, everything falls apart (for a time sensitive application).
It is possible to enlarge the serial buffer for your project. However, in the future, with a new Arduino version, you might have forgotten that you have changed a library and the project does no longer work that well.
I want to point out that you can use the usb serial port that is inside some microcontrollers and processors. That is not a real serial uart with a baudrate and a clock, but a usb CDC device.
A atmega32u4 and the arm m0+ have such a usb CDC serial port.
The arduino leonardo, micro and pro micro use the atmega32u4.
The arduino zero, m0, mkr series use the arm m0+ processor.
What about these numbers:
NB_CHARS: Time (microsec)
1: 6.93
2: 7.60
3: 8.06
[...]
99: 153
100: 154
101: 152
[...]
199: 1685
200: 1624
201: 1705
That is with a arm m0+ processor. I used the same sketch as you, but I changed the Serial
to SerialUSB
.
add a comment |Â
up vote
2
down vote
Your "long" delay is not too long at all.
If you measure the throughput of the right part, you have about 30 characters sent in 2500 microseconds. This means the rate is roughly (30 * 8 * 1,000,000) / 2500, which is 96,000 bits/sec.
It's a bit less than 115,200 you specified, but serial protocols use service bits, so in fact you'd have to replace 8 with 10. This gives 120,000 baud which is within measurement error.
The left part is actually much faster than you required, but as @Majenko correctly noticed, this is thanks to buffering. Apparently, you can increase the buffer size up to 256 bytes. If you need consistency instead of maximum speed, you may decrease the buffer size instead.
Finally, you should test performance in a realistic scenario. In your example you just keep sending data in a loop; obviously you soon fill up the buffer and run into port speed limit. However, in real life your loop would probably read some input, do some calculations, then send the result. In this case, you'd be using the buffer more effectively.
add a comment |Â
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
12
down vote
accepted
The Arduino core has a 64 byte transmission buffer. Characters are sent out of that buffer by the hardware.
When you blast lots of characters out of serial the first 64 just get put into that buffer - almost instantly.
Once that buffer is full your sketch blocks until the hardware has sent a character to make room.
Since it's sending right from the moment you place the first character into the buffer you get a little more than 64 bytes worth of buffering time (64 + the number that have been sent by the time the buffer fills).
From that point on you are entirely at the mercy of the baud rate you have chosen.
To get more predictable throughput (and maximise the speed) you should bypass the Ardiuno core and manipulate the UART registers directly.
"you should bypass the Ardiuno core and manipulate the UART registers directly". Any good library for this?
â Alex Millette
Sep 10 at 18:59
5
@AlexMillette Ummm... no. That's the whole point. You will be avoiding any library / core functions and using the registers directly. Read the datasheet.
â Majenkoâ¦
Sep 10 at 19:02
2
I think it would be handy @Majenko if you could point Alex at some example code....
â boatcoder
Sep 11 at 1:25
3
There is a fair chance that once you bypass the core, your code will run as slow as the right part, and not as fast as the left one.
â IMil
Sep 11 at 3:27
1
For smooth serial communication you really want an MCU with DMA to do the transfers for you...
â Majenkoâ¦
Sep 11 at 9:21
 |Â
show 1 more comment
up vote
12
down vote
accepted
The Arduino core has a 64 byte transmission buffer. Characters are sent out of that buffer by the hardware.
When you blast lots of characters out of serial the first 64 just get put into that buffer - almost instantly.
Once that buffer is full your sketch blocks until the hardware has sent a character to make room.
Since it's sending right from the moment you place the first character into the buffer you get a little more than 64 bytes worth of buffering time (64 + the number that have been sent by the time the buffer fills).
From that point on you are entirely at the mercy of the baud rate you have chosen.
To get more predictable throughput (and maximise the speed) you should bypass the Ardiuno core and manipulate the UART registers directly.
"you should bypass the Ardiuno core and manipulate the UART registers directly". Any good library for this?
â Alex Millette
Sep 10 at 18:59
5
@AlexMillette Ummm... no. That's the whole point. You will be avoiding any library / core functions and using the registers directly. Read the datasheet.
â Majenkoâ¦
Sep 10 at 19:02
2
I think it would be handy @Majenko if you could point Alex at some example code....
â boatcoder
Sep 11 at 1:25
3
There is a fair chance that once you bypass the core, your code will run as slow as the right part, and not as fast as the left one.
â IMil
Sep 11 at 3:27
1
For smooth serial communication you really want an MCU with DMA to do the transfers for you...
â Majenkoâ¦
Sep 11 at 9:21
 |Â
show 1 more comment
up vote
12
down vote
accepted
up vote
12
down vote
accepted
The Arduino core has a 64 byte transmission buffer. Characters are sent out of that buffer by the hardware.
When you blast lots of characters out of serial the first 64 just get put into that buffer - almost instantly.
Once that buffer is full your sketch blocks until the hardware has sent a character to make room.
Since it's sending right from the moment you place the first character into the buffer you get a little more than 64 bytes worth of buffering time (64 + the number that have been sent by the time the buffer fills).
From that point on you are entirely at the mercy of the baud rate you have chosen.
To get more predictable throughput (and maximise the speed) you should bypass the Ardiuno core and manipulate the UART registers directly.
The Arduino core has a 64 byte transmission buffer. Characters are sent out of that buffer by the hardware.
When you blast lots of characters out of serial the first 64 just get put into that buffer - almost instantly.
Once that buffer is full your sketch blocks until the hardware has sent a character to make room.
Since it's sending right from the moment you place the first character into the buffer you get a little more than 64 bytes worth of buffering time (64 + the number that have been sent by the time the buffer fills).
From that point on you are entirely at the mercy of the baud rate you have chosen.
To get more predictable throughput (and maximise the speed) you should bypass the Ardiuno core and manipulate the UART registers directly.
answered Sep 10 at 18:49
Majenkoâ¦
62.3k42773
62.3k42773
"you should bypass the Ardiuno core and manipulate the UART registers directly". Any good library for this?
â Alex Millette
Sep 10 at 18:59
5
@AlexMillette Ummm... no. That's the whole point. You will be avoiding any library / core functions and using the registers directly. Read the datasheet.
â Majenkoâ¦
Sep 10 at 19:02
2
I think it would be handy @Majenko if you could point Alex at some example code....
â boatcoder
Sep 11 at 1:25
3
There is a fair chance that once you bypass the core, your code will run as slow as the right part, and not as fast as the left one.
â IMil
Sep 11 at 3:27
1
For smooth serial communication you really want an MCU with DMA to do the transfers for you...
â Majenkoâ¦
Sep 11 at 9:21
 |Â
show 1 more comment
"you should bypass the Ardiuno core and manipulate the UART registers directly". Any good library for this?
â Alex Millette
Sep 10 at 18:59
5
@AlexMillette Ummm... no. That's the whole point. You will be avoiding any library / core functions and using the registers directly. Read the datasheet.
â Majenkoâ¦
Sep 10 at 19:02
2
I think it would be handy @Majenko if you could point Alex at some example code....
â boatcoder
Sep 11 at 1:25
3
There is a fair chance that once you bypass the core, your code will run as slow as the right part, and not as fast as the left one.
â IMil
Sep 11 at 3:27
1
For smooth serial communication you really want an MCU with DMA to do the transfers for you...
â Majenkoâ¦
Sep 11 at 9:21
"you should bypass the Ardiuno core and manipulate the UART registers directly". Any good library for this?
â Alex Millette
Sep 10 at 18:59
"you should bypass the Ardiuno core and manipulate the UART registers directly". Any good library for this?
â Alex Millette
Sep 10 at 18:59
5
5
@AlexMillette Ummm... no. That's the whole point. You will be avoiding any library / core functions and using the registers directly. Read the datasheet.
â Majenkoâ¦
Sep 10 at 19:02
@AlexMillette Ummm... no. That's the whole point. You will be avoiding any library / core functions and using the registers directly. Read the datasheet.
â Majenkoâ¦
Sep 10 at 19:02
2
2
I think it would be handy @Majenko if you could point Alex at some example code....
â boatcoder
Sep 11 at 1:25
I think it would be handy @Majenko if you could point Alex at some example code....
â boatcoder
Sep 11 at 1:25
3
3
There is a fair chance that once you bypass the core, your code will run as slow as the right part, and not as fast as the left one.
â IMil
Sep 11 at 3:27
There is a fair chance that once you bypass the core, your code will run as slow as the right part, and not as fast as the left one.
â IMil
Sep 11 at 3:27
1
1
For smooth serial communication you really want an MCU with DMA to do the transfers for you...
â Majenkoâ¦
Sep 11 at 9:21
For smooth serial communication you really want an MCU with DMA to do the transfers for you...
â Majenkoâ¦
Sep 11 at 9:21
 |Â
show 1 more comment
up vote
3
down vote
Majenko already gave the right answer: as soon as the buffer is full, everything falls apart (for a time sensitive application).
It is possible to enlarge the serial buffer for your project. However, in the future, with a new Arduino version, you might have forgotten that you have changed a library and the project does no longer work that well.
I want to point out that you can use the usb serial port that is inside some microcontrollers and processors. That is not a real serial uart with a baudrate and a clock, but a usb CDC device.
A atmega32u4 and the arm m0+ have such a usb CDC serial port.
The arduino leonardo, micro and pro micro use the atmega32u4.
The arduino zero, m0, mkr series use the arm m0+ processor.
What about these numbers:
NB_CHARS: Time (microsec)
1: 6.93
2: 7.60
3: 8.06
[...]
99: 153
100: 154
101: 152
[...]
199: 1685
200: 1624
201: 1705
That is with a arm m0+ processor. I used the same sketch as you, but I changed the Serial
to SerialUSB
.
add a comment |Â
up vote
3
down vote
Majenko already gave the right answer: as soon as the buffer is full, everything falls apart (for a time sensitive application).
It is possible to enlarge the serial buffer for your project. However, in the future, with a new Arduino version, you might have forgotten that you have changed a library and the project does no longer work that well.
I want to point out that you can use the usb serial port that is inside some microcontrollers and processors. That is not a real serial uart with a baudrate and a clock, but a usb CDC device.
A atmega32u4 and the arm m0+ have such a usb CDC serial port.
The arduino leonardo, micro and pro micro use the atmega32u4.
The arduino zero, m0, mkr series use the arm m0+ processor.
What about these numbers:
NB_CHARS: Time (microsec)
1: 6.93
2: 7.60
3: 8.06
[...]
99: 153
100: 154
101: 152
[...]
199: 1685
200: 1624
201: 1705
That is with a arm m0+ processor. I used the same sketch as you, but I changed the Serial
to SerialUSB
.
add a comment |Â
up vote
3
down vote
up vote
3
down vote
Majenko already gave the right answer: as soon as the buffer is full, everything falls apart (for a time sensitive application).
It is possible to enlarge the serial buffer for your project. However, in the future, with a new Arduino version, you might have forgotten that you have changed a library and the project does no longer work that well.
I want to point out that you can use the usb serial port that is inside some microcontrollers and processors. That is not a real serial uart with a baudrate and a clock, but a usb CDC device.
A atmega32u4 and the arm m0+ have such a usb CDC serial port.
The arduino leonardo, micro and pro micro use the atmega32u4.
The arduino zero, m0, mkr series use the arm m0+ processor.
What about these numbers:
NB_CHARS: Time (microsec)
1: 6.93
2: 7.60
3: 8.06
[...]
99: 153
100: 154
101: 152
[...]
199: 1685
200: 1624
201: 1705
That is with a arm m0+ processor. I used the same sketch as you, but I changed the Serial
to SerialUSB
.
Majenko already gave the right answer: as soon as the buffer is full, everything falls apart (for a time sensitive application).
It is possible to enlarge the serial buffer for your project. However, in the future, with a new Arduino version, you might have forgotten that you have changed a library and the project does no longer work that well.
I want to point out that you can use the usb serial port that is inside some microcontrollers and processors. That is not a real serial uart with a baudrate and a clock, but a usb CDC device.
A atmega32u4 and the arm m0+ have such a usb CDC serial port.
The arduino leonardo, micro and pro micro use the atmega32u4.
The arduino zero, m0, mkr series use the arm m0+ processor.
What about these numbers:
NB_CHARS: Time (microsec)
1: 6.93
2: 7.60
3: 8.06
[...]
99: 153
100: 154
101: 152
[...]
199: 1685
200: 1624
201: 1705
That is with a arm m0+ processor. I used the same sketch as you, but I changed the Serial
to SerialUSB
.
answered Sep 10 at 22:38
Jot
1,647416
1,647416
add a comment |Â
add a comment |Â
up vote
2
down vote
Your "long" delay is not too long at all.
If you measure the throughput of the right part, you have about 30 characters sent in 2500 microseconds. This means the rate is roughly (30 * 8 * 1,000,000) / 2500, which is 96,000 bits/sec.
It's a bit less than 115,200 you specified, but serial protocols use service bits, so in fact you'd have to replace 8 with 10. This gives 120,000 baud which is within measurement error.
The left part is actually much faster than you required, but as @Majenko correctly noticed, this is thanks to buffering. Apparently, you can increase the buffer size up to 256 bytes. If you need consistency instead of maximum speed, you may decrease the buffer size instead.
Finally, you should test performance in a realistic scenario. In your example you just keep sending data in a loop; obviously you soon fill up the buffer and run into port speed limit. However, in real life your loop would probably read some input, do some calculations, then send the result. In this case, you'd be using the buffer more effectively.
add a comment |Â
up vote
2
down vote
Your "long" delay is not too long at all.
If you measure the throughput of the right part, you have about 30 characters sent in 2500 microseconds. This means the rate is roughly (30 * 8 * 1,000,000) / 2500, which is 96,000 bits/sec.
It's a bit less than 115,200 you specified, but serial protocols use service bits, so in fact you'd have to replace 8 with 10. This gives 120,000 baud which is within measurement error.
The left part is actually much faster than you required, but as @Majenko correctly noticed, this is thanks to buffering. Apparently, you can increase the buffer size up to 256 bytes. If you need consistency instead of maximum speed, you may decrease the buffer size instead.
Finally, you should test performance in a realistic scenario. In your example you just keep sending data in a loop; obviously you soon fill up the buffer and run into port speed limit. However, in real life your loop would probably read some input, do some calculations, then send the result. In this case, you'd be using the buffer more effectively.
add a comment |Â
up vote
2
down vote
up vote
2
down vote
Your "long" delay is not too long at all.
If you measure the throughput of the right part, you have about 30 characters sent in 2500 microseconds. This means the rate is roughly (30 * 8 * 1,000,000) / 2500, which is 96,000 bits/sec.
It's a bit less than 115,200 you specified, but serial protocols use service bits, so in fact you'd have to replace 8 with 10. This gives 120,000 baud which is within measurement error.
The left part is actually much faster than you required, but as @Majenko correctly noticed, this is thanks to buffering. Apparently, you can increase the buffer size up to 256 bytes. If you need consistency instead of maximum speed, you may decrease the buffer size instead.
Finally, you should test performance in a realistic scenario. In your example you just keep sending data in a loop; obviously you soon fill up the buffer and run into port speed limit. However, in real life your loop would probably read some input, do some calculations, then send the result. In this case, you'd be using the buffer more effectively.
Your "long" delay is not too long at all.
If you measure the throughput of the right part, you have about 30 characters sent in 2500 microseconds. This means the rate is roughly (30 * 8 * 1,000,000) / 2500, which is 96,000 bits/sec.
It's a bit less than 115,200 you specified, but serial protocols use service bits, so in fact you'd have to replace 8 with 10. This gives 120,000 baud which is within measurement error.
The left part is actually much faster than you required, but as @Majenko correctly noticed, this is thanks to buffering. Apparently, you can increase the buffer size up to 256 bytes. If you need consistency instead of maximum speed, you may decrease the buffer size instead.
Finally, you should test performance in a realistic scenario. In your example you just keep sending data in a loop; obviously you soon fill up the buffer and run into port speed limit. However, in real life your loop would probably read some input, do some calculations, then send the result. In this case, you'd be using the buffer more effectively.
edited Sep 11 at 13:16
answered Sep 11 at 3:55
IMil
1213
1213
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2farduino.stackexchange.com%2fquestions%2f55993%2fwhy-is-serial-write-that-slower-when-writing-x1-characters-than-when-it-is-writ%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
set higher baud rate. at least 460800 baud should go with good connections.
â Juraj
Sep 10 at 20:18
the quote is not true anymore. at bit rates over 500kbit/s the interrupt is not used if the buffer is empty. (bit rate, not baud rate)
â Juraj
Sep 10 at 20:21