2012-10-20 15 views
8

Tôi đang sử dụng thiết bị nối tiếp cho một dự án và những gì tôi đang cố thực hiện bên PC, đang nghe lệnh được thiết bị nối tiếp gửi, giải thích truy vấn, chạy một số mã tùy thuộc vào truy vấn và truyền lại kết quả.Trình nghe và nối tiếp cổng nối tiếp Linux?

Thành thật mà nói tôi đã thử sử dụng PHP làm trình nghe, và nó hoạt động, tiếc là vòng lặp vô hạn cần thiết để làm cho tập lệnh hoạt động như một bộ thu, tải CPU lên 25%. Vì vậy, nó không thực sự là lựa chọn tốt nhất.

Tôi đang sử dụng Cygwin ngay bây giờ, tôi muốn tạo một tập lệnh bash bằng cách sử dụng các lệnh gốc của Linux.

tôi có thể nhận dữ liệu bằng cách sử dụng:

cat /dev/ttyS2 

Và gửi một phản ứng với:

echo "command to send" > /dev/ttyS2 

Câu hỏi của tôi là, làm thế nào để làm cho một người nghe tự động để có thể nhận và gửi dữ liệu ? Vấn đề chính mà tôi có, thực sự là làm thế nào để dừng lệnh cat/dev/ttyS2 sau khi nhận được thông tin, đặt nó vào một biến mà sau đó tôi có thể so sánh với một công tắc, hoặc một chuỗi nếu khác chặn. Sau đó gửi lại phản hồi và bắt đầu lại chu kỳ?

Cảm ơn

+0

bash sẽ không là sự lựa chọn đầu tiên của tôi. Có thể là thời điểm tốt để thử một con trăn nhỏ hoặc perl - cả hai đều có thư viện và các ví dụ cho việc này. – stark

+0

Hoặc thử sử dụng lập trình hệ thống C và Linux. Vẫn. Bạn đang cố gắng tạo một loại chương trình máy khách-khách hàng trong bash script? – askmish

+0

Tôi đã thử sử dụng C++, tuy nhiên tôi chưa bao giờ đặt tay lên loại ngôn ngữ lập trình đó, vì vậy tôi thất bại .. Sử dụng bash có ý nghĩa hơn với tôi, vì tôi cũng có thể dễ dàng sử dụng cả ứng dụng Windows và Linux với Cygwin . Một lệnh có thể sử dụng tệp thực thi Windows hoặc tệp dơi để lưu đầu ra thành biến mà tôi chuyển sang thiết bị nối tiếp và tôi có thể sử dụng lệnh Linux (chẳng hạn như wget) trên dòng khác mà không phải viết toàn bộ hàm để làm trong C++. – Matt

Trả lời

9

Đây không phải là những gì bạn đang tìm kiếm?

while read -r line < /dev/ttyS2; do 
    # $line is the line read, do something with it 
    echo $result > /dev/ttyS2 
done 
+0

Cảm ơn bạn đây chính xác là những gì tôi cần :) – Matt

+0

Chỉ dành cho tôi nhưng trong trường hợp của tôi Arduino được đặt lại mỗi lần " bubblebath

+1

@bubblebath: Điều đó chắc chắn có thể, và giải pháp sẽ là di chuyển ' rici

0

Nếu bạn sử dụng đúng công cụ, có thể thực sự sử dụng CPU chính xác 0 khi thiết bị của bạn không có đầu ra. Để thực hiện điều này, bạn nên sử dụng một số ngôn ngữ cấp cao hơn (Perl, Python, C/C++ sẽ làm, nhưng không bash) và sử dụng vòng lặp chọn trên đầu của tập tin xử lý của thiết bị nối tiếp của bạn. Đây là một ví dụ cho Perl http://perldoc.perl.org/IO/Select.html, nhưng bạn có thể sử dụng bất kỳ ngôn ngữ nào khác miễn là nó có hỗ trợ cho select() syscall.

+0

Sử dụng Cygwin, quá trình nghe, được tạo bằng vòng lặp do rici cung cấp, (như được hiển thị trong Trình quản lý Tác vụ) sử dụng CPU 0% và chỉ 100k bộ nhớ. Tuy nhiên khi một yêu cầu được nhận từ thiết bị nối tiếp, CPU tăng lên tùy thuộc vào độ phức tạp của đầu ra yêu cầu (chẳng hạn như kết hợp regexp, curl để lấy thông tin từ các trang web, vv), nó dao động từ 0% đến 25%. Tôi đoán sử dụng một ngôn ngữ cấp cao hơn sẽ nhỏ hơn, nhưng tôi hài lòng với kết quả, vì nó tốt hơn nhiều so với vòng lặp PHP vô hạn với việc sử dụng CPU 25% :) – Matt

1

Để duy trì hệ thống khá độc lập, hãy sử dụng ngôn ngữ lập trình nền tảng chéo: như Python, sử dụng thư viện nối tiếp nền tảng chéo như: pySerial và thực hiện việc xử lý bên trong tập lệnh. Tôi đã sử dụng pySerial và tôi có thể chạy các nền tảng kịch bản chéo với hầu như không có thay đổi trong mã nguồn. Bằng cách sử dụng BASH, bạn đang hạn chế một chút công bằng.

+0

Theo cách tôi giới hạn bản thân, nhưng bash tay có nguồn gốc trong Linux cũng như trong Mac và có sẵn trên Windows thông qua Cygwin. Ngoài ra tôi không sử dụng bất kỳ phần mềm/gói/thư viện bổ sung nào không có nền tảng chéo trong trạng thái gốc. Bằng cách sử dụng các lệnh đơn giản như 'while read -r line/dev/ttyS2' tôi đang loại bỏ sự phụ thuộc của các thư viện hoặc phần mềm cần thiết có thể không được chuyển qua nền tảng hoặc tương tác khác với hệ điều hành được đề cập. Phương pháp của bạn cũng hợp lý hơn tôi đoán, nhưng tôi không quen thuộc với Python :) – Matt

+0

đã sử dụng Cygwin để truy cập vào cửa sổ cổng com làm việc? –

+0

@Matt cũng nếu bạn đang sử dụng Cygwin bạn đang nhận được thư viện với nó :) infact toàn bộ một lớp UNIXY trên đầu trang của cửa sổ –

0

Tôi khuyên bạn nên sử dụng C/C++ với Qt 5.1.1, nó thực sự dễ dàng và nếu bạn đã quen thuộc với khuôn khổ, nó sẽ là một miếng bánh !!! Here bạn có thể tìm thêm thông tin và here các ví dụ hữu ích khác, hãy thử xem, nó thực sự là miễn phí! Ngoài ra bạn có thể phát triển trên chiến thắng và sau đó cổng mã của bạn để linux ... thẳng về phía trước.

Khai báo một đối tượng như thế này:

QSerialPort mPort; //remember to #include <QtSerialPort/QSerialPort> 
//also add QT += serialport to your .pro file 

Sau đó thêm mã này:

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) 
{ 
    setupUi(this); 


    connect(this->pushButton,SIGNAL(clicked()),this,SLOT(sendData())); 

    mPort.setPortName("ttyS0"); 
    mPort.setBaudRate(QSerialPort::Baud115200); 
    mPort.setParity(QSerialPort::EvenParity); 

    if(!mPort.open(QSerialPort::ReadWrite)) 
    { 
     this->label->setText(tr("unable to open port, %1").arg(mPort.error())); 
    } 

    connect(&(this->mPort),SIGNAL(readyRead()),this,SLOT(readData())); 
} 

void MainWindow::sendData() 
{ 

    QByteArray data = lineEdit->text().toLatin1(); 
    if(mPort.isOpen()) 
    { 
     mPort.write(data); 
    } 
    else 
    { 
     this->label->setText(tr("port closed %1").arg(mPort.error())); 

    } 
} 


void MainWindow::readData() 
{ 

    QString newData; 
    int bread=0; 
    while(bread < mPort.bytesAvailable()){ 
     newData += mPort.readAll(); 
     bread++; 
    } 
    this->textEdit->insertPlainText("\n" + newData); 
}