0

我有一个 QSocketNotifier,它从串行端口(从文件 /dev/ttyUSB0)读取数据。不过,QSocketNotifier 似乎切断了字符串......我从 CuteCom 获取了一些代码(apt-get source cutecom在类 Debian 系统中),我试图在仅限终端的程序中实现它。所以,到目前为止:

主.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 通知程序。问题是我只被切碎(在中间)字符串,而不是真正的大字符串!我不知道是什么导致了这个问题,但是Cutecom 运行良好,而上述程序却不行!

虽然我不知道实际问题是什么,但我知道我的任何检查都没有真正导致这个程序(我没有应用任何字符串过滤)并且 QSocketNotifier 实际上只发送了字符串的第一部分和最后一部分(从不整个字符串)。

我知道这很难,但是,如果有人可以帮助...谢谢!

4

1 回答 1

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;
   }
}
于 2012-07-26T07:00:06.627 回答