Arduino Serial Port Latency

I have a Ubuntu PC connected to an Arduino UNO board via serial port at 230kpbs. The serial communication is working fine except latency. With my old serial implementation, I got about 1 second latency from PC sends 4 bytes to Arduino and Arduino replies right away with 10 bytes. My Arduino is an very simple application which runs an infinite loop and there is no extra processing on the incoming request other than reading them from serial port and write a few bytes back.

Then I suspect maybe my Linux serial implementation.I replaced it with BOOST asio serial API. But still I got 550ms latency. Is this expected?

I tried another Arduino YUN and the result is even worse, about 2 seconds...

You need to post your code. I use Linux on this laptop (and others) and I have never noticed any latency.

The USB system might cause 1 ms latency for small data packets.

...R

Sure.

==========================
Ubuntu PC side:
void* serial_rx_thread(void *port)
{
unsigned char buf[100], *p;
ROS_INFO("%s: called", FUNCTION);
ros::Rate loop_rate(100); // run 100 times per second
static int rx_cnt = 0;
int eof_cnt = 0;

while (serial_rx_thread_running)
{
memset(buf, 0x0, sizeof(buf));
p = buf;
try {
while (1) {
char c;
size_t cnt;
// read 1 byte into c, this will block forever if no character
// arrives
cnt = asio::read(m_arduino_serial, asio::buffer(&c,1));
rx_cnt++;
if (c != ‘\n’) {
if (c == ‘[’) {
ROS_INFO("<<<%s: got start [", FUNCTION);
}
*p = c;
p++;
continue;
} else
{
string s = string((char *)buf);
serial_rx_q.push(s);
ROS_INFO("<<<%s: got line break. eof_cnt %d. buf %s. “, FUNCTION, eof_cnt, buf);
arduinoAcked = true;
break;
}
}
} catch (std::exception& e) {
//std::cerr << e.what() << std::endl;
eof_cnt++;
}
loop_rate.sleep();
}
ROS_INFO(”%s: exit", FUNCTION);
pthread_exit(NULL);
}

void* serial_tx_thread(void *port)
{
ROS_INFO("%s: called", FUNCTION);
ros::Rate loop_rate(100); // run 100 times per seconds
static int tx_cnt = 0;

while (serial_tx_thread_running)
{
if (serial_tx_q.size() != 0 && arduinoAcked == true)
{
string s;
int cnt;
s = serial_tx_q.front();
serial_tx_q.pop();
boost::system::error_code ec;
cnt = m_arduino_serial.write_some(boost::asio::buffer(s.c_str(), s.size()),ec);
if (cnt != 0)
{
ROS_INFO(">>>%s: sending %s, tx_cnt %u",
FUNCTION, s.c_str(), tx_cnt++);
if (s.compare(“st”) == 0)
{
arduinoAcked = false;
}
}
}
loop_rate.sleep();
}
ROS_INFO("%s: exit", FUNCTION);
pthread_exit(NULL);
}

asio::io_service _io;
asio::serial_port m_arduino_serial(_io);

main()
{
m_arduino_serial.open(port);
m_arduino_serial.set_option(asio::serial_port_base::baud_rate(baud));

//spawn two threads…
//every 10 seconds
serial_tx_q.push(“st”);

}

================================
Arduino side

void setup() {

Serial.begin(230400);

}

String incomingStr;
void loop() {
if (Serial.available() > 0) {
incomingStr = Serial.readString();
commandHandler(incomingStr);
}
delay(5);
}

void commandHandler(String cmd)
{
String keyWord = cmd.substring(0,2);

if (keyWord == “st”) {
String resp = “[st]”;
resp = resp + 0;
resp = resp + “,”;
resp = resp + 0;
Serial.println(resp);
}
}

I am not good on C/C++ on PCs and you did not use the code button </> so your code looks like this and is easy to copy to my text editor.

On the Arduino side the function Serial.readString() is a blocking function and is probably what is causing the problem

Have a look at the examples in Serial Input Basics - simple reliable, non-blocking ways to receive data.

Also it is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. Just use cstrings - char arrays terminated with 0.

…R

I tried Example 2 in your suggestion. It reduced latency so significantly. Now it's just 1~2ms. :slight_smile: :slight_smile:

scheng98:
I tried Example 2 in your suggestion. It reduced latency so significantly. Now it’s just 1~2ms. :slight_smile: :slight_smile:

If you still need help please post the updated Arduino program (and your PC program) using the code button </>

…R