Чтение и запись на последовательный порт в Ubuntu с C/C++ и LibSerial

Я использую LibSerial на Ubuntu для чтения и записи данных на последовательный порт.

На данный момент я могу писать и получать строки через последовательный порт, но мой код работает не очень хорошо: в частности, я хотел бы контролировать функцию чтения, чтобы читать только в том случае, если есть что читать и выйти, когда нет информации для чтения, чтобы отправить другую команду, не блокируя потоковую программу.

Я хочу делать:

  • Написать команду
  • Ждать ответа
  • затем напишите другую команду
  • Ждать ответа

Теперь я могу отправить первую команду и прочитать ответ, используя функцию чтения в цикле while, но больше ничего не могу сделать.Я не могу отправить вторую команду, потому что цикл 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 ;
}

2 ответа

Решение

Я думаю, что вам просто нужно использовать while( serial_port.rdbuf()->in_avail() > 0 ) как условие для вашего последнего цикла while. Затем он зачитает все доступные данные ("ответ"), и вы можете отправить вторую команду после этого.

Использование 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

Другие вопросы по тегам