I am trying to transfer data from Arduino to a C++ Qt5.7 and from a Arduino to a C++ Qt5.7 (MinGW) program.
I am able to transfer the data FROM QT TO ARDUINO without any problems. The Arduino blinks perfectly.
On the other hand, the data transfered FROM THE ARDUINO TO QT isnt always the expected (sends "LED ON" when it should be "LED OFF") and sometimes it doesnt communicate at all!
QT code:
#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();
}
The ARDUINO CODE:
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 Image of Error:
Please help! Thank you,
You have no packetization whatsoever: there are no delimiters between individual chunks of data - other than time passing.
On the Arudino side, instead of
write
, you should useprintln
so that each message is a complete line.On the Qt side, process complete lines. You're not guaranteed to get a complete response from the serial port after
waitForReadyRead
. All that you're guaranteed is that at least 1 byte is available to read. That is the source of your problem. Note how you gotLE
, then sometime later you gotD OFF
immediately followed byLED ON
. You must wait for data until complete line(s) are available.The following should work on the Qt end of things - also note that you don't need as many includes, and you can use
QTextStream
instead of iostream, to lower the number of APIs that you use. Finally, you don't needapp.exec
since you write blocking code.If you wish, you can also easily turn it into a GUI application, it's only a few lines to do so:
I think you must use EOL and Carrige return character on QT. Try to replace
Serial.write
toSerial.println
in Arduino code.