【问题标题】:Qt not receiving serial data from arduinoQt没有从arduino接收串行数据
【发布时间】:2016-08-22 13:38:09
【问题描述】:

我正在使用 Qt 编写一个从串行线路读取数据的 C++ 程序。数据的“生产者”是一块 Arduino UNO 板。

Arduino 代码非常简单。目前,它只是生成一个随机数并通过串行线路发送。代码如下:

long randNumber;

void setup() {
  Serial.begin(9600);
  randomSeed(analogRead(0));
}

void loop() {
  randNumber = random(300);
  Serial.write(randNumber);
  delay(10);
}

我已使用 Arduino 的“串行监视器”来验证数据是否通过串行线路。

在 Qt 方面,我有一个工作线程,它应该读取串行数据并相应地更新 UI 上的绘图。工作线程肯定正在运行,并且此代码正在执行(我已经检查过)。我的“端口列表”中只有一个设备显示,它是 Arduino,所以目前我直接连接到它。代码如下:

void doWork ()
{
    QList<QSerialPortInfo> port_list = QSerialPortInfo::availablePorts();
    QSerialPort serialPort;
    serialPort.setPort(port_list[0]);
    serialPort.setBaudRate(QSerialPort::Baud9600);

    if (!serialPort.open(QIODevice::ReadWrite))
    {
        cout << QObject::tr("Failed to open port COM3, error: %1").arg(serialPort.errorString()).toStdString() << endl;
    }

    while(!abort_thread)
    {
        int bytes_available = serialPort.bytesAvailable();
        if (bytes_available >= 4)
        {
            QByteArray byte_array = serialPort.read(4);
            int data = byte_array.toInt();
            emit signalDataReady(data);
        }
    }

    serialPort.close();
}

不幸的是,从来没有任何可用的字节。它成功打开串行端口,但没有字节通过。我在这里做错了什么?有任何想法吗?谢谢!

【问题讨论】:

  • 您似乎已经检查了我能想到的几乎所有错误,但是您绝对确定您的计算机上只有一个端口吗?你是打印出port_list 的长度还是用别的东西检查?我只是问,因为许多计算机往往有额外的串行端口,即使它们可能没有物理接口。
  • 我认为 Qt 正在连接到您的 arduino 板的 PC 上运行? - 或者 Qt 是否也在另一个 arduino 板上运行?无论如何,有几件事要尝试:首先是在你的 doWork() 线程函数中,你可能会因为你没有切换点而最大化你的处理器。尝试添加QThread::msleep(10); 以添加暂停,减慢轮询并允许其他进程一些 cpu 时间(不确定它会修复它,但是....)。你需要在你的文件中#include &lt;QThread&gt;
  • 第二件事……好吧,这比第一件事更像是在黑暗中刺伤,但我总是通过设置 setPortName() 打开我的 QSerialPorts……总是对我有用。所以你可以试试serialPort.setPortName(port_list[0].portName()); 而不是serialPort.setPort(port_list[0]);
  • 最后,您是否尝试过与已知良好的 comport 输出进行通信? - 即用串行终端(如腻子)连接到 windows/linux 盒子并寻找 ardiuno 板输出? - 如果没问题,那么尝试从腻子终端接收您的 Qt 应用程序并更新我们解决此问题的方法/不起作用(我知道您说您已经使用自己的工具验证了 arduino 板......但我从来没有相信这些,直到我看到它与标准工具一起工作)。

标签: qt arduino arduino-uno qtserialport qtserial


【解决方案1】:

您忘记在 bytesAvailable() 之前添加 waitForReadyRead()。

【讨论】:

  • 仔细观察,这可能会解决它。您的线程中可能没有事件循环,我不记得没有事件循环QSerialPort 的行为如何,但文档指出此方法在“在非 GUI 线程中执行 I/O 操作时”很有用。无论如何,阻止而不是忙于等待是一种好习惯。
  • 在查看了这里提出的所有各种建议之后,看起来就是这样做的!谢谢!有趣的是,每次调用 bytesAvailable() 之前,我都必须这样做,而不仅仅是在连接到 Arduino 之后。
【解决方案2】:

来自https://www.arduino.cc/en/Serial/Write

Serial.write(val)

val:作为单个字节发送的值

如果你写一个数字 Arduino 只发送一个字节,如果你想发送一个 long 那么你必须将它分解为一个数组并发送数组(或者获取一个指向 long 地址的指针并发送每个字节) .

由于您的 Qt 代码期望读取四个字节,因此永远不会执行 if。

【讨论】:

  • 这可能是一个错误,但由于 Arduino 代码在循环中运行,它最终会发送 4 个或更多字节,这并不能解释为什么 Qt 程序没有接收到数据。
  • 嗯,循环没有贴在代码上,我无法想象没有贴出的代码细节:D(是的,有一个 loop() 函数,但我看不出它是实际上是一个循环,因为函数只是进入和退出)。
  • 出于某种原因,Arduino/Wiring 开发人员认为保护程序员不必自己编写循环是合适的,因此他们提供了一个 main() 函数,该函数调用 setup(),然后在循环中继续调用 loop()为他们。去图吧。
  • 我很糟糕,XD,我不太习惯 Arduino,我更喜欢直接在他们的原生框架上编程微控制器。
  • 这里也一样。我不是整个 Wiring 交易的忠实粉丝。
猜你喜欢
  • 2016-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多