简体   繁体   English

使用C / C ++和LibSerial在Ubuntu中对串口进行读写

[英]Read and Write on serial port in Ubuntu with C/C++ and LibSerial

I'm using LibSerial on 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 command without 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. 现在,我能够发送第一个命令并在while循环中使用read函数读取答案,但我无法做任何其他事情。 I'm not able to send the second command because the while loop never exits so the program continues to 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 ;
}

I think you just need to use while( serial_port.rdbuf()->in_avail() > 0 ) as a condition for your last while loop. 我想你只需要使用while( serial_port.rdbuf()->in_avail() > 0 )作为你最后一个while循环的条件。 Then it'll read out all the available data (“answer”) and you can send the second command after that. 然后它将读出所有可用数据(“回答”),然后您可以发送第二个命令。

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]='\0';
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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM