Go Down

Topic: A serial port speed optimization question (Read 870 times) previous topic - next topic

liudr

Hi all,

I'm running into a problem with arduino serial communication. Hope someone can help me.

Here is my question: I have 4 bytes to send to a computer. Will sending one byte at a time add up to the same total time as sending all 4 bytes together? Like t1+t2+t3+t4=t_all4_together?.

I'm trying to figure out if there's a lot of overhead for initiating serial communication, like a lot of delayMicroseconds(), before and after sending the info.

Here is what I'm trying to do: I want to send 4-byte info to a computer via serial on an arduino board, every time the info is available.

Here's what I want to avoid: I am blocked from sensing a digital pin while I'm busy sending the byte message altogether.

Reason: I am waiting for a LOW on a digital pin. I could be sending the 4-byte signal when the pin changes to LOW. The time it takes to send 4 bytes (my naive calculation) is time=4bytes*10bits/byte/115200=0.35ms. I can't afford to delay .35ms. I'm trying to cut it down to 0.1ms delay by drizzling one byte a time on the serial port.

Thank you.

AWOL

Send one byte, the "write" returns almost immediately (as soon as the byte is written to the UART tx register).
However, if you send "write" another byte immediately, it will block until the tx register is empty. (10/ 115200 seconds later)
So, you could poll the tx empty bit yourself, whilst looking for your transition.

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

liudr

Thank you AWOL! I was so deeply thinking about my problem and forgot about the most basic way to find out.

Code: [Select]
void loop()
{
 
 //Sending n bytes at a time testing speed
 t1=micros();
 Serial.write(tempout,1);
 t2=micros();
 Serial.println(t2-t1);
 delay(200);
}


I did some testings and my finding is:
 Average over 121 tests is 12us (87us calculated) for 1 byte.
 Average over 94 tests is 16us(173us calculated) for 2 byte.
 Average over 69 tests is 101us (260us calculated) for 3 bytes.
 Average over 37 tests is 865us (1042us calculated) for 12 bytes.

I was surprised by the 12us short delay but then your explanation makes almost perfect sense since my tests have enough delay in it between iterations. There is only one thing I don't agree with you, the UART tx register may be a word register instead of byte. If it's a byte register, then sending 2 bytes at a time should have a delay of about 10/115200s+12us=99us instead of 16us, sending 3 bytes at a time should have a delay of 20/115200s+12us=186us, not 101us as I tested, and the 12 byte send will last 110/115200s+12us=967us, instead of 865us.

If instead the register is a word and can take 2 bytes at a time, then everything checks out.

Is the UART serial separate from the processing unit in the ATMEGA 328 so that while UART does the sending and receiving, ATMEGA can just do its thing in parallel? Thanks.

bill2009

you could think about using an interrupt for your transition instead of polling for it.

liudr

bill2009,

I've thought about it. Does Serial.anything() disable interrupt?

Go Up