Reputation: 149
I'm trying to use Boost.Asio to read from and write to a serial port. Here is my code:
void async_read(boost::asio::serial_port& serial_port)
{
auto buffer = std::make_shared<std::vector<uint8_t>>(64);
serial_port.async_read_some(boost::asio::buffer(*buffer),
[buffer, &serial_port](const boost::system::error_code& error, size_t bytes_read)
{
if (error)
{
std::cout << "Error reading serial port: " << error.message() << std::endl;
return;
}
std::string message(buffer->begin(), buffer->end());
std::cout << "Read " << bytes_read << " bytes:\t" << message << std::endl;
async_read(serial_port);
});
}
void async_write(boost::asio::serial_port& serial_port)
{
auto timer = std::make_shared<boost::asio::deadline_timer>(serial_port.get_io_service(), boost::posix_time::seconds(1));
timer->async_wait(
[&serial_port, timer](const boost::system::error_code& error)
{
if (error)
{
std::cout << "Timer error: " << error.message() << std::endl;
return;
}
auto message = std::make_shared<std::string>("Hello\n");
boost::asio::async_write(serial_port, boost::asio::buffer(*message),
[message, &serial_port](const boost::system::error_code& error, size_t bytes_sent)
{
if (error)
{
std::cout << "Error writing to serial port: " << error.message() << std::endl;
return;
}
std::cout << "Wrote " << bytes_sent << " bytes" << std::endl;
async_write(serial_port);
});
});
}
int main()
{
boost::asio::io_service service;
auto serial_port = boost::asio::serial_port(service, "/dev/ttyUSB0");
serial_port.set_option(boost::asio::serial_port::baud_rate(9600));
async_read(serial_port);
async_write(serial_port);
service.run();
}
At the opposite end of the serial cable, I have a separate machine running cat /dev/ttyTHS0
.
My issue is that whenever the program performs an async_write
, those same bytes are immediately handled by the async_read
completion handler - even though the remote machine isn't sending anything.
I'm not sure if the root cause is the code, or because I'm using cat
at the other end. When cat
is not running, I'm not having the issue.
Running the above code, (with cat /dev/ttyTHS0
at the other end) gives output like this:
Wrote 6 bytes
Read 7 bytes: Hello
Wrote 6 bytes
Read 3 bytes: Hel
Read 4 bytes: lo
Wrote 6 bytes
Read 7 bytes: Hello
Wrote 6 bytes
Read 1 bytes: H
Read 6 bytes: ello
Wrote 6 bytes
Read 7 bytes: Hello
Maybe I'm missing something obvious, but any help is appreciated! Thank you!
Upvotes: 1
Views: 506
Reputation: 12255
This is the expected behaviour for a serial port. These were typically used to connect a terminal like a vt100 to a computer. When you type on the keyboard, the character is sent to the computer, and the serial port echoes it back to the vt100 screen where it is displayed.
If you run stty -a -F /dev/ttyTHS0
on the remote you will see the setting echo
is on (before you ran your program on the remote). You can switch it off with stty -echo -F /dev/ttyTHS0
, when it will show as -echo
.
Typically, when serial ports are used for comms between computers, the application will set the port to raw, noecho. This is to avoid certain translations being done by the serial port driver, so the data arrives unchanged at the application.
Upvotes: 2