【问题标题】:Read and Write on serial port in Ubuntu with C/C++ and LibSerial使用 C/C++ 和 LibSerial 在 Ubuntu 中读取和写入串行端口
【发布时间】:2012-02-21 05:31:58
【问题描述】:

我在 Ubuntu 上使用LibSerial 在串口上读写数据。

目前,我可以通过串口写入和接收字符串,但是我的代码不能很好地工作:特别是,我想控制读取功能以便只读如果有要读取的内容并在没有要读取的信息时退出以发送另一个命令而不会阻塞流程序。

我想做:

  • 编写命令
  • 等待答复
  • 然后编写另一个命令
  • 等待答复

现在,我可以发送第一个命令并通过在 while 循环中使用 read 函数来读取答案,但我无能为力。 我无法发送第二个命令,因为 while 循环永远不会退出,因此程序会继续读取。

你能帮帮我吗?

这是我正在使用的代码: (读写函数在代码末尾)

#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 ;
}

【问题讨论】:

    标签: c++ linux ubuntu serial-port libserial


    【解决方案1】:

    使用 try 和 catch 会很有帮助。 :)

    试试这个: 一个全局指针 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]='\0';
    if(print_str)
        puts(cstr);
    return 0;
    }
    

    参考: http://libserial.sourceforge.net/doxygen/class_serial_port.html#a15

    【讨论】:

      【解决方案2】:

      我认为您只需要使用while( serial_port.rdbuf()-&gt;in_avail() &gt; 0 ) 作为最后一个while 循环的条件。然后它会读出所有可用的数据(“答案”),然后你可以发送第二个命令。

      【讨论】:

      • 问题是如果我使用 serial_port.rdbuf()->in_avail() > 0 它永远不会进入 while 循环。看起来很奇怪,因为串口上有数据但是程序没有读取。相反,如果我使用 while(1) 它会正确读取它。
      • 那么,在读取了实际答案的所有字节后,您会得到哪个字符?你可以检查那个字符(我认为它应该是'\0'或'\n')并在你得到它之后做break
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-05
      • 1970-01-01
      • 2018-02-12
      • 1970-01-01
      相关资源
      最近更新 更多