2012-07-24 2 views
0

직렬 포트 (/ dev/ttyUSB0 파일)에서 데이터를 읽는 QSocketNotifier가 있습니다. QSocketNotifier는 문자열을 잘라내는 것 같습니다. CuteCom (데비안과 유사한 시스템에서 apt-get cutecom)에서 일부 코드를 가져 왔으며 터미널 전용 프로그램에서이 코드를 구현하려고했습니다. 그래서, 여기에 지금까지입니다 :QSocketNotifier가 전체 스트림을 읽지 않는 것 같습니다.

MAIN.CPP :

#include <QtCore/QCoreApplication> 
#include <QSocketNotifier> 
#include <QTimer> 
#include <QDebug> 

#include <sys/termios.h> 
#include <stdio.h> 
#include <fcntl.h> 
#include <iostream> 

using namespace std; 

QSocketNotifier *m_notifier; 
QString output_buffer=""; 
int m_fd; 
char m_buf[4096]; 

class Timer : public QTimer { 
    Q_OBJECT 
public: 
    explicit Timer(QObject *parent = 0) : QTimer(parent) { 

    } 
public slots: 
    void readData(int fd){ 
     if (fd!=m_fd) 
      return; 

     int bytesRead=::read(m_fd, m_buf, 4096); 

     if (bytesRead<0) 
     { 
      cerr << "read result: " << bytesRead << endl; 
      return; 
     } 
     // if the device "disappeared", e.g. from USB, we get a read event for 0 bytes 
     else if (bytesRead==0) 
     { 
      disconnectTTY(); 
      return; 
     } 

     const char* c=m_buf; 
     qDebug() << "THEY CAME " << bytesRead << " bytes!"; 
     QString text=""; 
     for (int i=0; i<bytesRead; i++) 
     { 
      // also print a newline for \r, and print only one newline for \r\n 
      if ((isprint(*c)) || (*c=='\n') || (*c=='\r')) 
      { 
       text+=(*c); 
      } 
      else 
      { 
       char buf[64]; 
       unsigned int b=*c; 
       snprintf(buf, 16, "\\0x%02x", b & 0xff); 
       text+=buf; 
      } 
     c++; 
     } 
     addOutput(text); 
    } 
    void addOutput(QString text){ 
     output_buffer+=text; 
     this->setSingleShot(true); 
     this->start(100); 
    } 
    void process_input(){ 
     //this function processes the input strings. 
     cout << QString(output_buffer).toLocal8Bit().data(); 
     output_buffer.clear(); 
    } 
    void create_avg(){ 
     cout << "I will create the average in the future!\n"; 
    } 
    void disconnectTTY(){ 
     delete m_notifier; 
     m_notifier=0; 
    } 
    void connect_normal_timer() 
    { 
     connect(this, SIGNAL(timeout()), this, SLOT(process_input())); 
    } 
    void connect_avg_maker_timer() 
    { 
     connect(this ,SIGNAL(timeout()), this, SLOT(create_avg())); 
    } 
    void disconnect_from_slot() 
    { 
     disconnect(this, 0, this, 0); 
    } 
    void create_notifier(){ 
     m_notifier=new QSocketNotifier(m_fd, QSocketNotifier::Read, this); 
     connect(m_notifier, SIGNAL(activated(int)), this, SLOT(readData(int))); 
    } 
}; 

void open_device(QString device){ 
    m_fd=open(device.toLatin1(), O_RDONLY | O_NDELAY | O_NONBLOCK);//O_NDELAY); 
    if(m_fd<0){ 
     cerr << QString("Cannot open device '"+device+"'\n").toLocal8Bit().data(); 
     exit(1); 
    } 
    tcflush(m_fd, TCIOFLUSH); 
} 

Timer timer; 
Timer avg_maker; 

#include "main.moc" 


int main(int argc, char *argv[]) 
{ 
    QCoreApplication a(argc, argv); 

    /* 
     SETTING UP TIMERS 
    */ 

    timer.connect_normal_timer(); 
    avg_maker.connect_avg_maker_timer(); 

    /* 
     OPENING DEVICE 
    */ 

    open_device("/dev/ttyUSB0"); 

    /* 
     CREATE SOCKET READER 
    */ 
    timer.create_notifier(); 

    avg_maker.start(3000); 
    return a.exec(); 
} 

그래서, 설치 2 타이머, 나는 읽기 전용으로는/dev/ttyUSB0를를 열고 내 QSocket 알리미를 연결합니다. 문제는 내가 (중간에) 잘게 썬 문자열과 결코 실제 큰 문자열을 얻지 못한다는 것입니다. 나는 무엇이 문제를 일으키는 지 알지 못하지만, 위의 프로그램은 잘하지 않는다.

실제 문제가 무엇인지 모르겠지만 실제로이 검사를 수행하지 않아도 (문자열 필터링을 적용하지 않았 음) QSocketNotifier는 실제로 일부만을 보내고 마지막 부분은 문자열 (결코 전체 문자열).

나는이 사람이 힘들다는 것을 알고 있지만, 누군가가 도울 수 있다면 ... 감사합니다!

답변

0

open_device() 함수는 같아야

void open_device(QString device){ 
    m_fd=open(device.toLatin1(), O_RDONLY | O_NDELAY); 
    if(m_fd<0){ 
     cerr << QString("Cannot open device '"+device+"'\n").toLocal8Bit().data(); 
     exit(1); 
    } 
    tcflush(m_fd, TCIOFLUSH); 
    int n = fcntl(m_fd, F_GETFL, 0); 
    fcntl(m_fd, F_SETFL, n & ~O_NDELAY); 
    if (tcgetattr(m_fd, &m_oldtio)!=0) 
    { 
     cerr << "tcgetattr() 2 failed" << endl; 
    } 

    struct termios newtio; 

    if (tcgetattr(m_fd, &newtio)!=0) 
    { 
     cerr << "tcgetattr() 3 failed" << endl; 
    } 

    speed_t _baud=B9600; 

    cfsetospeed(&newtio, (speed_t)_baud); 
    cfsetispeed(&newtio, (speed_t)_baud); 

    newtio.c_cflag = (newtio.c_cflag & ~CSIZE) | CS8; 
    newtio.c_cflag |= CLOCAL | CREAD; 

    newtio.c_cflag &= ~(PARENB | PARODD); 

    newtio.c_cflag &= ~CRTSCTS; 

    newtio.c_cflag &= ~CSTOPB; 

    newtio.c_iflag=IGNBRK; 

    newtio.c_iflag &= ~(IXON|IXOFF|IXANY); 

    newtio.c_lflag=0; 
    newtio.c_oflag=0; 

    newtio.c_cc[VTIME]=1; 
    newtio.c_cc[VMIN]=60; 

    if (tcsetattr(m_fd, TCSANOW, &newtio)!=0) 
    { 
     cerr << "tcsetattr() 1 failed" << endl; 
    } 

    int mcs=0; 
    ioctl(m_fd, TIOCMGET, &mcs); 
    mcs |= TIOCM_RTS; 
    ioctl(m_fd, TIOCMSET, &mcs); 

    if (tcgetattr(m_fd, &newtio)!=0) 
    { 
     cerr << "tcgetattr() 4 failed" << endl; 
    } 

    newtio.c_cflag &= ~CRTSCTS; 

    if (tcsetattr(m_fd, TCSANOW, &newtio)!=0) 
    { 
     cerr << "tcsetattr() 2 failed" << endl; 
    } 
} 
관련 문제