我有一个QSocketNotifier,它从串口读取数据(来自文件/ dev / ttyUSB0)。 QSocketNotifier似乎打破了字符串,但...... 我从CuteCom(在类似Debian的系统中使用 apt-get source cutecom )中获取了一些代码,并尝试在仅限终端的程序中实现它。所以,到目前为止:
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通知程序。问题是我只会被切断(在中间)字符串,而不是一个真正的大字符串!我不知道是什么原因导致了这个问题,但Cutecom运行良好,而上述程序却没有!
虽然我不知道实际问题是什么,但我知道我的检查没有实际导致这个程序(我没有应用任何字符串过滤)而且QSocketNotifier实际上只发送了一些第一部分和最后一部分string(从不是整个字符串)。
我知道这个很难,但是,如果有人可以提供帮助......谢谢!
答案 0 :(得分: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;
}
}