gpt4 book ai didi

c++ - Arduino与Qt 5.7之间的双向串口通信

转载 作者:行者123 更新时间:2023-12-01 19:43:08 25 4
gpt4 key购买 nike

我正在尝试将数据从 Arduino 传输到 C++ Qt5.7,以及从 Arduino 传输到 C++ Qt5.7 (MinGW) 程序。

我能够毫无问题地将数据从 QT 传输到 ARDUINO。Arduino 完美闪烁。

另一方面,从 ARDUINO 传输到 QT 的数据并不总是预期的(在应该是“LED OFF”时发送“LED ON”),有时根本不进行通信!

QT代码:

#include <QCoreApplication>
#include <QDebug>

#include <QSerialPort>
#include <QSerialPortInfo>
#include <QThread>

#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

QSerialPort serial;
serial.setPortName("COM6");
serial.setBaudRate(9600);
serial.setDataBits(QSerialPort::Data8);
serial.setParity(QSerialPort::NoParity);
serial.setStopBits(QSerialPort::OneStop);
serial.setFlowControl(QSerialPort::NoFlowControl);

if(serial.open(QSerialPort::ReadWrite))
{
string c;
QByteArray s;
QByteArray received;
while(true)
{
qDebug("TRUE");
//WRITE
cin >> c;
cout << endl;
s = QByteArray::fromStdString(c);
serial.write(s);
serial.waitForBytesWritten(-1);

//serial.flush();

s = serial.readAll();
serial.waitForReadyRead(-1);
cout << s.toStdString() << endl;

//serial.flush();
}
}
else
{
QString error = serial.errorString();
cout << error.toStdString() << endl;
qDebug("FALSE") ;
}


serial.close();

return a.exec();
}

Arduino 代码:

void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);

Serial.begin(9600);
}

// the loop function runs over and over again forever
void loop() {
delay(1000); // wait for a second
}

void serialEvent()
{
char inChar;
while (Serial.available())
{
// get the new byte:
inChar = (char)Serial.read();
if(inChar == 'a')
{
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
}
else
{
digitalWrite(LED_BUILTIN, LOW); // turn the LED off (LOW is the voltage level)
}
}
delay(500);
if(inChar == 'a')
{
Serial.write("LED ON");
}
else
{
Serial.write("LED OFF");
}
}

错误的终端图像:

TERMINAL WITH ERROR image

请帮忙!谢谢,

最佳答案

您没有进行任何打包:各个数据 block 之间没有分隔符 - 除了时间流逝之外。

  1. 在 Arudino 端,您应该使用 println,而不是 write,以便每条消息都是完整的一行。

  2. 在 Qt 端,处理完整的行。不保证您在 waitForReadyRead 之后从串行端口获得完整的响应。您所保证的是至少有 1 个字节可供读取。这就是你的问题的根源。请注意您是如何获得 LE 的,然后过了一段时间,您获得了 D OFF,然后立即获得了 LED ON。您必须等待数据,直到完整的行可用。

以下内容应该适用于 Qt 端 - 另请注意,您不需要那么多包含,并且您可以使用 QTextStream 而不是 iostream,以减少您需要的 API 数量使用。最后,您不需要 app.exec 因为您编写的是阻塞代码。

// https://github.com/KubaO/stackoverflown/tree/master/questions/arduino-read-40246601
#include <QtSerialPort>
#include <cstdio>

int main(int argc, char *argv[])
{
QCoreApplication a{argc, argv};
QTextStream in{stdin};
QTextStream out{stdout};

QSerialPort port;
port.setPortName("COM6");
port.setBaudRate(9600);
port.setDataBits(QSerialPort::Data8);
port.setParity(QSerialPort::NoParity);
port.setStopBits(QSerialPort::OneStop);
port.setFlowControl(QSerialPort::NoFlowControl);

if (!port.open(QSerialPort::ReadWrite)) {
out << "Error opening serial port: " << port.errorString() << endl;
return 1;
}

while(true)
{
out << "> ";
auto cmd = in.readLine().toLatin1();
if (cmd.length() < 1)
continue;

port.write(cmd);

while (!port.canReadLine())
port.waitForReadyRead(-1);

while (port.canReadLine())
out << "< " << port.readLine(); // lines are already terminated
}
}

如果您愿意,您还可以轻松地将其变成 GUI 应用程序,只需几行即可:

#include <QtSerialPort>
#include <QtWidgets>

int main(int argc, char *argv[])
{
QApplication app{argc, argv};
QWidget ui;
QFormLayout layout{&ui};
QLineEdit portName{"COM6"};
QTextBrowser term;
QLineEdit command;
QPushButton open{"Open"};
layout.addRow("Port", &portName);
layout.addRow(&term);
layout.addRow("Command:", &command);
layout.addRow(&open);
ui.show();

QSerialPort port;
port.setBaudRate(9600);
port.setDataBits(QSerialPort::Data8);
port.setParity(QSerialPort::NoParity);
port.setStopBits(QSerialPort::OneStop);
port.setFlowControl(QSerialPort::NoFlowControl);

QObject::connect(&open, &QPushButton::clicked, &port, [&]{
port.setPortName(portName.text());
if (port.open(QSerialPort::ReadWrite)) return;
term.append(QStringLiteral("* Error opening serial port: %1").arg(port.errorString()));
});

QObject::connect(&command, &QLineEdit::returnPressed, &port, [&]{
term.append(QStringLiteral("> %1").arg(command.text()));
port.write(command.text().toLatin1());
});

QObject::connect(&port, &QIODevice::readyRead, &term, [&]{
if (!port.canReadLine()) return;
while (port.canReadLine())
term.append(QStringLiteral("< %1").arg(QString::fromLatin1(port.readLine())));
});
return app.exec();
}

关于c++ - Arduino与Qt 5.7之间的双向串口通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40246601/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com