Linux 使用 C/C++ 和 LibSerial 在 Ubuntu 中的串行端口上读写
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9046649/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Read and Write on serial port in Ubuntu with C/C++ and LibSerial
提问by Marcus Barnet
I'm using LibSerialon Ubuntu to read and write data on serial port.
我在 Ubuntu 上使用LibSerial在串口上读写数据。
At the moment, I'm able to write and receive strings over the serial port, but my code does not work very well: in particular, I'd like to control the reading function in order to read only if there is something to read and exit when there is no information to read in order to send another commandwithout bloicking the flow program.
目前,我可以通过串行端口写入和接收字符串,但我的代码不能很好地工作:特别是,我想控制读取功能以便仅在有内容时读取并在没有要读取的信息时退出,以便在不阻塞流程程序的情况下发送另一个命令。
I want to do:
我想要做:
- Write a command
- Wait for the answer
- then Write another command
- Wait for answer
- 写一个命令
- 等待答案
- 然后写另一个命令
- 等待答复
Now, i'm able to send the first command and read the answer by using read function in a while loop but i'm not able to do nothing else. I'm not able to send the second command because the while loop never exits so the program continues to read.
现在,我可以通过在 while 循环中使用 read 函数发送第一个命令并阅读答案,但我无法做任何其他事情。 我无法发送第二个命令,因为 while 循环永远不会退出,因此程序会继续读取。
Can you help me, please?
你能帮我吗?
This is the code i'm using: (Read and write function are at the end of the code)
这是我正在使用的代码:(读取和写入功能在代码的末尾)
#include <SerialStream.h>
#include <iostream>
#include <unistd.h>
#include <cstdlib>
#include <string>
int
main( int argc,
char** argv )
{
//
// Open the serial port.
//
using namespace std;
using namespace LibSerial ;
SerialStream serial_port ;
char c;
serial_port.Open( "/dev/ttyACM0" ) ;
if ( ! serial_port.good() )
{
std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] "
<< "Error: Could not open serial port."
<< std::endl ;
exit(1) ;
}
//
// Set the baud rate of the serial port.
//
serial_port.SetBaudRate( SerialStreamBuf::BAUD_9600 ) ;
if ( ! serial_port.good() )
{
std::cerr << "Error: Could not set the baud rate." <<
std::endl ;
exit(1) ;
}
//
// Set the number of data bits.
//
serial_port.SetCharSize( SerialStreamBuf::CHAR_SIZE_8 ) ;
if ( ! serial_port.good() )
{
std::cerr << "Error: Could not set the character size." <<
std::endl ;
exit(1) ;
}
//
// Disable parity.
//
serial_port.SetParity( SerialStreamBuf::PARITY_NONE ) ;
if ( ! serial_port.good() )
{
std::cerr << "Error: Could not disable the parity." <<
std::endl ;
exit(1) ;
}
//
// Set the number of stop bits.
//
serial_port.SetNumOfStopBits( 1 ) ;
if ( ! serial_port.good() )
{
std::cerr << "Error: Could not set the number of stop bits."
<< std::endl ;
exit(1) ;
}
//
// Turn off hardware flow control.
//
serial_port.SetFlowControl( SerialStreamBuf::FLOW_CONTROL_NONE ) ;
if ( ! serial_port.good() )
{
std::cerr << "Error: Could not use hardware flow control."
<< std::endl ;
exit(1) ;
}
//
// Do not skip whitespace characters while reading from the
// serial port.
//
// serial_port.unsetf( std::ios_base::skipws ) ;
//
// Wait for some data to be available at the serial port.
//
//
// Keep reading data from serial port and print it to the screen.
//
// Wait for some data to be available at the serial port.
//
while( serial_port.rdbuf()->in_avail() == 0 )
{
usleep(100) ;
}
char out_buf[] = "check";
serial_port.write(out_buf, 5); <-- FIRST COMMAND
while( 1 )
{
char next_byte;
serial_port.get(next_byte); HERE I RECEIVE THE FIRST ANSWER
std::cerr << next_byte;
}
std::cerr << std::endl ;
return EXIT_SUCCESS ;
}
采纳答案by Michael Pankov
I think you just need to use while( serial_port.rdbuf()->in_avail() > 0 )
as a condition for your last while loop. Then it'll read out all the available data (“answer”) and you can send the second command after that.
我认为您只需要while( serial_port.rdbuf()->in_avail() > 0 )
用作最后一个 while 循环的条件。然后它会读出所有可用的数据(“答案”),然后您可以发送第二个命令。
回答by Bazooka
Using try and catch would be helpful. :)
使用 try 和 catch 会有所帮助。:)
Try this: A global pointer SerialPort *pu was already declared and the port was opened.
试试这个:一个全局指针 SerialPort *pu 已经被声明并且端口被打开。
int rxstring(char *cstr, unsigned int len, bool print_str)
{
char temp=0;
int i=0;
while(temp!='\n')
{
try
{
temp=pu->ReadByte(100);
}
catch(SerialPort::ReadTimeout &e)
{
//cout<<"Read Timeout"<<endl;
return 1;
}
if((temp!='\n')&&(temp!=0)&&(temp!=' '))
{
cstr[i]=temp;
++i;
//cout<<i++<<temp<<'x'<<endl;
}
}
cstr[i]='##代码##';
if(print_str)
puts(cstr);
return 0;
}
Reference: http://libserial.sourceforge.net/doxygen/class_serial_port.html#a15
参考:http: //libserial.sourceforge.net/doxygen/class_serial_port.html#a15