使用QSerialPort从串行端口读取时出现问题

时间:2014-02-08 10:31:53

标签: qt qtcore qt-signals qtserialport qiodevice

我必须为嵌入式基于FriendlyARM的处理器系统开发一个C ++程序。 我使用Qt Creator 3.0.0(基于Qt 5.2.0)用于台式计算机。我的程序应该能够从Mini2440 FriendlyARM处理器的串口读取。

在进入目标系统(嵌入式系统)之前,我试图在笔记本电脑上读取/写入串口。我的主要问题是如何从串口读取。如您所知,新计算机和笔记本电脑没有串行端口,因此我尝试使用手工制作的USB转串口适配器电缆模拟串口编程。当插入USB串行电缆时,它在Ubuntu上被识别为“/ dev / ttyUSB0”。它似乎运作良好。 请注意,电缆的另一端(串行端口)没有连接任何东西。

我的第一个问题是:可以像这样配置电缆,还是我必须将它连接到其他设备? 我尝试每10秒写入/ dev / ttyUSB0并读取数据。我最终得到了以下代码:

void MainWindow::refreshNotificationArea()
{
    generateNotifAreaData(); // a typical random data-generator
    QList<QSerialPortInfo> L = QSerialPortInfo::availablePorts();
    for (auto e : L)
        qDebug() << e.portName() << '\n'; // it prints 1 serial port: :ttyUSB0
    // write to the port
    QSerialPort notifAreaPort;
    // 1. set properties
    notifAreaPort.setBaudRate(QSerialPort::Baud9600); 
    notifAreaPort.setStopBits(QSerialPort::OneStop);
    notifAreaPort.setParity(QSerialPort::NoParity); 
    notifAreaPort.setDataBits(QSerialPort::Data8);
    notifAreaPort.setFlowControl(QSerialPort::NoFlowControl); 
    QObject::connect(&notifAreaPort,SIGNAL(error(QSerialPort::SerialPortError)),
    this, SLOT(errorReport(QSerialPort::SerialPortError)));
    notifAreaPort.setPortName(serial_device.c_str());
    // 2. open port
    notifAreaPort.open(QIODevice::ReadWrite);
    if (!notifAreaPort.isOpen())
        qDebug() << "Open failed"; // open is OK, no error message printed

    string s  = convertNotifAreadData2Str();
    qDebug() << "Generated data " << s.c_str(); // OK
    int a = notifAreaPort.write(s.c_str()); // write done
    qDebug() << "Write count" << a; // OK

    // now read the info

    QByteArray ba = notifAreaPort.readLine(3); // read failed
    QSerialPort::SerialPortError err = notifAreaPort.error();
    qDebug() << "Error code" << err;
    qDebug() << "What? " << notifAreaPort.errorString();
    qDebug() << "Read count " << ba.size(); // 0

    notifAreaPort.close();
}

void MainWindow::errorReport(QSerialPort::SerialPortError error)
{
    if(error!=0)
        qDebug()<<"ERROR:"<<endl<<error; // nothing printed
}

写入串口是可以的。但阅读问题有时“没有这样的文件或目录”! 有时“文件暂时不可用! 奇怪的是notifAreaPort.error()返回0,这意味着没有错误 发生!

思想?

- Saeed Amrollahi Boyouki

3 个答案:

答案 0 :(得分:0)

“手工制作USB转串口适配器” - 听起来很有趣。你确定这个工作正常吗?我认为连接PIN 2(Rx)和3(Tx)是个好主意,因此您可以获得数据。现在,您可以使用任何其他终端软件测试您的设备。 我用串行端口总是readyRead()信号,我在使用port-&gt; bytesAvailable()读取之前检查。 我用port-&gt; open打开我的端口(QIODevice :: ReadWrite | QIODevice :: Unbuffered)。

答案 1 :(得分:0)

您的代码中存在一些问题,但我将重点介绍其中最重要的一些问题:

  • 您在打开前设置参数。这应该在打开后发生。这就是API设计得很糟糕的方式,但我们正在对其进行改造。

  • 您应该在5.2中添加command line examples for reading吗?看来你不知道如何阅读,那些会给你一个简单的例子。简而言之:在写作可能甚至完成之前,你基本上都在尝试阅读。

答案 2 :(得分:0)

你不能在同一个函数中写QSerialPort

我使用两种方法进行QSerialPort处理:

METHOD ONE 创建并打开QSerialPort对象。 设置QTimer,超时大约50毫秒左右(取决于硬件)。

readyRead()信号连接到一个插槽,该插槽基本上只是将所有数据读入缓冲区(QByteArray非常适用于此)。插槽会停止QTimer,读取readAll()的所有可用数据,然后重新启动QTimer并返回。

timeout的{​​{1}}信号连接到函数以处理读取的输入字节。

这里的前提是,最终所有数据都将到达并且QTimer将超时,此时您将在缓冲区中处理所有数据。

QTimer 处理METHOD TWO信号的槽可以检查缓冲区中的所有数据是否有一些“标记”,表示某些数据块已完全到达。许多设备使用readyRead()0x0D作为转发器。其他人使用NULL 0x0d0x0A或其他字节。

0x00处理程序槽的每次迭代中评估缓冲区。

此示例显示了第二个选项,它适用于小读取。

readyRead()

这允许在数据到达时读取QSerialPort,然后程序可以返回到事件循环,以防止GUI变得无响应。典型的串行读取很小且持续时间很短,因此使用这些方法很少发生UI冻结。