c++ - Qt和Arduino串行通信(读写)

标签 c++ qt interface arduino serial-port

我陷入了一个非常简单的问题。

我正在尝试制作一个Qt GUI应用程序以从GUI控制我的Arduino(而不是从Arduino IDE的串行监视器控制它)。我能够使用QSerialPort write()方法成功写入Arduino,但是我无法从Arduino读取任何内容。我可以从串行端口读取的唯一方法是在Qt代码的waitForBytesWritten()中的write()函数之后使用waitForReadyRead(5000)。但是我必须使用5000毫秒的时间间隔才能成功读取,这很费时间。请让我知道Qt GUI应用程序中是否有更快的读取Arduino串行端口的方法。

我正在发布我的Qt和Arduino代码。

Qt代码

#include "GuiApp.h"
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QDebug>
#include <QMessageBox>

GuiApp::GuiApp(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    ui.lcdNumber_temp->display("--------");
    arduino = new QSerialPort(this);

    bool arduino_available = false;
    QString arduino_portName;


    foreach(const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()) {
        if (serialPortInfo.hasVendorIdentifier() && serialPortInfo.hasProductIdentifier()) {
            if ((serialPortInfo.productIdentifier() == arduino_pid) && (serialPortInfo.vendorIdentifier() == arduino_vid)) {
                arduino_available = true;
                arduino_portName = serialPortInfo.portName();
            }
        }
    }

    //qDebug() << "Number of ports" << QSerialPortInfo::availablePorts().length() << "\n";
    //foreach(const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()) {
    //  qDebug() << "Description" << serialPortInfo.description() << "\n";
    //  qDebug() << "Has Vendor Id?" << serialPortInfo.hasVendorIdentifier() << "\n";
    //  qDebug() << "Vendor Id" << serialPortInfo.vendorIdentifier() << "\n";
    //  qDebug() << "Has Product Id?" << serialPortInfo.hasProductIdentifier() << "\n";
    //  qDebug() << "Product Id" << serialPortInfo.productIdentifier() << "\n";
    //}


    if (arduino_available) {
        arduino->setPortName(arduino_portName);
        arduino->setBaudRate(QSerialPort::Baud9600);
        arduino->setDataBits(QSerialPort::Data8);
        arduino->setParity(QSerialPort::NoParity);
        arduino->setStopBits(QSerialPort::OneStop);
        arduino->setFlowControl(QSerialPort::NoFlowControl);
        arduino->open(QIODevice::ReadWrite);
        if (!arduino->isOpen()) {
            qDebug() << "Arduino Not Opening";
        }
        QObject::connect(ui.pushButton_connect,SIGNAL(clicked()),this,SLOT(button_pressed()));
        QObject::connect(arduino,SIGNAL(readyRead()),this,SLOT(readSerial()));
        //serial.write("OK ---");
    } else {
        qDebug() << "Couldn't find correct arduino port.\n";
        QMessageBox::information(this,"Serial Port Error","Couldn't open serial port to arduino.");
    }
}

GuiApp::~GuiApp()
{
    //serial.close();
    if (arduino->isOpen()) {
        qDebug() << "Arduino Closed!\n";
        arduino->close();
    }
}

void GuiApp::button_pressed() {
    if (arduino->isWritable()) {
        arduino->write("255");
        arduino->waitForBytesWritten(5000);

        //QByteArray s = arduino->readAll();
        //arduino->waitForReadyRead(1000);
        //std::string str = s.toStdString();
        //qDebug("My String %s", str);

    }
    else {
        QMessageBox::information(this, "Serial Port Error", "Couldn't write to Serial port.");
    }
}

void GuiApp::readSerial() {
    qDebug() << "Serial Port Works!!\n";
    QMessageBox::information(this, "Serial Port Works", "Opened serial port to arduino.");
    QByteArray serialData = arduino->readAll();
    QString temp = QString::fromStdString(serialData.toStdString());
    qDebug() << temp;
}

Arduino代码
#include <SPI.h>
#include <Controllino.h>


int led = CONTROLLINO_D1;
int led2 = CONTROLLINO_D2;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(led,OUTPUT);
  pinMode(led2,OUTPUT);
  digitalWrite(led,LOW);
  digitalWrite(led2,LOW);

}

void loop() {
  // put your main code here, to run repeatedly:
  if(Serial.available()) {
     const int val = Serial.parseInt();

     if(val == 255) {
        digitalWrite(led,HIGH);
        delay(1000);
        Serial.write("Ok");
     } else {
        digitalWrite(led2,HIGH);
        Serial.write("Not Ok");
     }

  }


}

最佳答案

尝试连接QIODevice::readyRead信号:

    QObject::connect(&serialPort, &QSerialPort::readyRead, [&]() {
        standardOutput << "Recieved: " << serialPort.readAll() << endl;
    });

关于c++ - Qt和Arduino串行通信(读写),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59862831/

相关文章:

java - 抽象类实现接口(interface)

C++ 模板接口(interface)自动解析赋值类型

java - 有人可以帮我(新手)解释抽象类和接口(interface)吗?

c++ - libGL 确实存在,但链接器无法找到它 - Qt 4.8.7、CentOS 7.5

android - 向 Android 应用程序添加额外文件

c++ - 使用 qt creator 构建 boost c++ 1.48.0

c++ - 我想隐藏从 system() 发出的系统命令

c++ - 如何修复循环依赖?

c++ - Qt:无法初始化 QApplication 对象

c++ - QComboBox:仅在展开时显示图标