2
votes

I'm using the boost::asio library to control a motor with serial connection. The problem is that the boost::asio::serial_port::read() function would get the program to freeze if the device does not send anything for me to read.

How can I check whether the device has something to tell me through the port?

If I send a command to the device, I can get an answer back with no problems. But is there a way to know whether it sent anything without me sending a command? or does that not make any sense in serial connections, where a command is only received as a response to a sent command?

Please check my code

try
{
    port = new boost::asio::serial_port(io_serial, comPort.c_str());
}
char rcvd;
std::string res;
while(1)
{
    boost::asio::read(*port,boost::asio::buffer(&rcvd, 1)); //here it freezes till something is read
    std::cout<<rcvd<<std::endl; //I know it froze in the last line because nothing was written from here
    if(rcvd == '\r' || rcvd == '\0')
    {
        break;
    }
    res.push_back(rcvd);
}
return res;

Thanks for any efforts.

1
Why not use async read with boost::asio::async_read_*? - ForEveR
Thank you for the reply. I don't know actually what the difference would make. Could you please explain the difference? - The Quantum Physicist
It cannot says you, that there are data in port... But it will not block execution (until you call ios.run()) and you can set timeout (and if timeout happens - there is no data in port)... I think in asio, there is no function, that can says you, that port has any data for send. - ForEveR
Actually, I didn't find any timeout method. Could you please point out how a timeout can be used with it? - The Quantum Physicist

1 Answers

2
votes

For serial ports, Boost.Asio neither provides non-blocking synchronous reads nor reads with timeouts. Therefore, the alternative option is to use asynchronous reads. Boost.Asio provides this example. While the example is for TCP, it should exemplify the overall concepts and approach to asynchronous reads with timeouts.

Additionally, based on the posted logic, where data is read until a carriage-return or NULL, it may be worth considering using a line-based operation, such as boost::asio::async_read_until.