2012-01-28 49 views
5

Tôi đang sử dụng LibSerial trên Ubuntu để đọc và ghi dữ liệu trên cổng nối tiếp.Đọc và ghi trên cổng nối tiếp trong Ubuntu với C/C++ và LibSerial

Hiện tại, tôi có thể viết và nhận chuỗi trên cổng nối tiếp, nhưng mã của tôi không hoạt động tốt: cụ thể, Tôi muốn kiểm soát chức năng đọc để chỉ đọc nếu có một cái gì đó để đọc và thoát ra khi không có thông tin để đọc để gửi một lệnh khác mà không bloicking chương trình dòng chảy.

tôi muốn làm:

  • Viết lệnh
  • Chờ câu trả lời
  • sau đó Viết lệnh khác
  • Chờ câu trả lời

Bây giờ, tôi có thể để gửi lệnh đầu tiên và đọc câu trả lời bằng cách sử dụng chức năng đọc trong một vòng lặp while nhưng tôi không thể làm gì khác. Tôi không thể gửi lệnh thứ hai vì vòng lặp while không bao giờ thoát để chương trình tiếp tục đọc.

Bạn có thể giúp tôi không?

Đây là mã tôi đang sử dụng: (Đọc và viết chức năng là ở phần cuối của mã)

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

Trả lời

4

Tôi nghĩ rằng bạn chỉ cần sử dụng while(serial_port.rdbuf()->in_avail() > 0) như một điều kiện để cuối cùng của bạn trong khi vòng lặp . Sau đó, nó sẽ đọc tất cả các dữ liệu có sẵn ("trả lời") và bạn có thể gửi lệnh thứ hai sau đó.

+0

Vấn đề là nếu tôi sử dụng ** serial_port.rdbuf() -> in_avail()> 0 ** nó không bao giờ đi vào trong vòng lặp while. Có vẻ như rất lạ, vì có dữ liệu trên cổng nối tiếp nhưng chương trình không đọc chúng. Ngược lại, nếu tôi sử dụng ** trong khi (1) ** nó đọc chính xác. –

+0

Vậy thì, nhân vật nào bạn nhận được sau khi tất cả các byte của câu trả lời thực tế được đọc? Bạn có thể kiểm tra nhân vật đó (tôi nghĩ rằng nó nên là '\ 0' hoặc '\ n') và làm 'break' ra khỏi vòng lặp sau khi bạn nhận được nó. –

1

Sử dụng thử và bắt sẽ hữu ích. :)

Hãy thử điều này: Con trỏ toàn cục SerialPort * pu đã được khai báo và cổng đã được mở.

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

tham khảo: http://libserial.sourceforge.net/doxygen/class_serial_port.html#a15

Các vấn đề liên quan