I've been trying for more than a week to communicate from raspberry pi (QT C++) to Arduino (Arduino IDE c++) through a serial port but i keep failing.
I did some searching on google, read the example... and still i didn't succeeded. Ok so the basic thing is that i need to communicate continuously the serial port sent command from Raspberry pi to Arduino. I tried to keep the code as simple as possible.
Initially I'm sending "J" char from raspberry pi (QT C++) to Arduino (Arduino IDE c++) and waiting on that J, to make the LED blink on Arduino. But it doesn't work.. Even I didn't get any sample for interfacing & communicating & sending data raspberry pi (QT C++) to Arduino (Arduino IDE c++). I don't know what is the problem exactly. Kindly help me to solve the issue.
In monitor, 9600 baudrate
I have attached program what I have tried on both side.
main.cpp
#include <iostream>
#include <QIODevice>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QString>
using namespace std;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();
QSerialPort serialPort;
serialPort.setBaudRate(QSerialPort::Baud9600);
QSerialPortInfo info("ttyUSB0");
qDebug() << "Name : " << info.portName();
qDebug() << "Description : " << info.description();
qDebug() << "Busy:" << info.isBusy();
QSerialPort serial;
serial.setPortName("ttyUSB0");
serial.open(QIODevice::ReadWrite);
serial.setBaudRate(QSerialPort::Baud9600);
serial.setDataBits(QSerialPort::Data8);
serial.setParity(QSerialPort::NoParity);
serial.setStopBits(QSerialPort::OneStop);
serial.setFlowControl(QSerialPort::NoFlowControl);
serial.open(QSerialPort::ReadWrite);
cout<<"Readable :"<<serial.isReadable()<<endl;
cout<<"Writable :"<<serial.isWritable()<<endl<<endl;
if (serial.isOpen() && serial.isWritable())
{
qDebug() << "Is open : " << serial.isOpen() << endl;
qDebug() << "Is writable : " << serial.isWritable() << endl;
qDebug() << "Ready..." << endl;
serial.write("J");
QByteArray ba("J\n");
serial.write(ba);
{
QByteArray ba("J");
serial.write(ba);
serial.flush();
qDebug() << "data has been send" << endl;
serial.close();
}
if (serial.bytesToWrite() > 0)
{
serial.flush();
if(serial.waitForBytesWritten(1000))
{
qDebug() << "data has been send" << endl;
}
}
if(serial.flush())
{
qDebug() << "ok" << endl;
}
qDebug() <<"value sent "<< endl;
serial.close();
}
else
{
qDebug() << "An error occured" << endl;
}
return a.exec();
}
Arduino code:
int led = 13, avlb = 0;
void setup()
{
Serial.begin(9600);
pinMode(led, OUTPUT);
Serial.println("started");
}
void loop()
{
if (Serial.available() > 0)
{
Serial.println("available");
Serial.println(Serial.available());
delay(2000);
digitalWrite(led, HIGH);
delay(5000);
if(Serial.read() == 'J')
{
Serial.println("read");
Serial.println(Serial.read());
delay(2000);
digitalWrite(led, LOW);
delay(1000);
}
}
else
{
Serial.println("not available");
delay(1000);
}
}
Output Displayed:
Raspberry qt creator ide o/p:
Name : "ttyUSB0"
Description : "FT232R USB UART"
Busy: false
Readable :1
Writable :1
Is open : true
Is writable : true
Ready...
data has been send
bool QSerialPort::flush(): device not open
value sent
Arduino Ide Output displayed:
started
not available
not available
not available
not available
not available
not available
not available
not available
not available
I would suggest you to read about how Qt event system works. All Qt IODevice derived classes work asynchronously. You need to use QApplication in order to host its object system. After that, you need to change your code so that it's not blocking io thread of QSerialPort.
I usually use readyRead singal or I use waitForBytesWritten and waitForReadReady combination.You should take a look at the QtSerialPort examples. You'll find there several possible implementations depending on your application needs.
You can try this, it will work fine.
#include <QCoreApplication>
#include <iostream>
#include <QSerialPort>
#include <QDebug>
#include <Windows.h>
#include <QElapsedTimer>
using namespace std;
QSerialPort serial;
QElapsedTimer timer;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
serial.setPortName("ttyUSB0");
serial.open(QIODevice::ReadWrite);
serial.setBaudRate(QSerialPort::Baud9600);
serial.setDataBits(QSerialPort::Data8);
serial.setParity(QSerialPort::NoParity);
serial.setStopBits(QSerialPort::OneStop);
serial.setFlowControl(QSerialPort::NoFlowControl);
while(!serial.isOpen()) serial.open(QIODevice::ReadWrite);
if (serial.isOpen() && serial.isWritable())
{
qDebug() << "Serial is open";
QByteArray output;
QByteArray input;
while(true)
{
output = "a";
serial.write(output);
serial.flush();
timer.start();
// Sleep(80);
qDebug() << timer.elapsed();
serial.waitForBytesWritten(100);
serial.waitForReadyRead(100);
if(serial.bytesAvailable()>=18)
input = serial.read(18);
qDebug()<<input;
}
}
return a.exec();
}
The answer to your question is in the following code:
QByteArray ba("J");
serial.write(ba);
serial.flush();
qDebug() << "data has been send" << endl;
serial.close();
After you make serial.flush (), you immediately close the port. It is necessary to wait until the data is really sent. For example, using bool QSerialPort :: waitForBytesWritten (int msecs).
Related
To develop my program first without connecting two physical machines on serial port, I downloaded and used this program to simulate COM ports:
https://sourceforge.net/projects/com0com/
I connected virtual COM4 to virtual COM5. It works fine.
Using Br#y's Terminal program, I tested if I connect to COM4 in one Terminal instance, and to COM5 in another instance on the same computer, the data that I send on one terminal arrives in the other terminal, and vice versa.
Terminal program: https://sites.google.com/site/terminalbpp/
Now let's see the problem:
I used SerialPortReader class from this official Qt sample code for async serial read: https://code.qt.io/cgit/qt/qtserialport.git/tree/examples/serialport/creaderasync
It connects to COM5 and sets baud rate to 9600 successfully, but no data arrives if I send something via Terminal to COM4, so: SerialPortReader runs through with no error, but after then, no matter what message I send on my Terminal instance, handleReadyRead, handleError, and handleTimeout never get called.
(If I have already a terminal emulator connected to the virtual COM5 port, then connection in my C++ program fails, so indeed the open() check works fine.
Also, if I try to send more than one messages to my program via the virtual COM4 port, Terminal freezes, which is a clear sign of that the previous message has not yet been read on the other side(COM5).)
I have googled a lot, but have not yet found any solutions. Someone here said that it is/was a bug Qt Serial Port Errors - Data not getting read and that the problem is in qserialport_win.cpp, but even if I change that and compile my program again, nothing happens.
I use the following code to create the class, but the class' content is unchanged, I use it as I found in the sample program:
// Serial comm init
QSerialPort serialPort;
QString serialPortName = "COM5";
serialPort.setPortName(serialPortName);
int serialPortBaudRate = 9600;
if (serialPort.open(QIODevice::ReadOnly)) {
if(serialPort.setBaudRate(serialPortBaudRate) &&
serialPort.setDataBits(QSerialPort::Data8) &&
serialPort.setParity(QSerialPort::NoParity) &&
serialPort.setStopBits(QSerialPort::OneStop) &&
serialPort.setFlowControl(QSerialPort::NoFlowControl)) {
//SerialPortReader serialPortReader(&serialPort);
SerialPortReader serialPortReader(&serialPort, this);
} else {
std::cout << "Failed to set COM connection properties " << serialPortName.toStdString() << serialPort.errorString().toStdString() << std::endl;
}
} else {
std::cout << "Failed to open port " << serialPortName.toStdString() << serialPort.errorString().toStdString() << std::endl;
}
I would appreciate any help. Thanks!
Today I figured out a sketchy but working version:
SerialPortReader.h
#pragma once
#include <QtCore/QObject>
#include <QByteArray>
#include <QSerialPort>
#include <QTextStream>
#include <QTimer>
class SerialPortReader : public QObject {
Q_OBJECT
public:
explicit SerialPortReader(QObject *parent = 0);
~SerialPortReader() override;
void close();
private:
QSerialPort *serialPort = nullptr;
QByteArray m_readData;
QTimer m_timer;
public slots:
void handleReadyRead();
//void handleTimeout();
//void handleError(QSerialPort::SerialPortError error);
};
SerialPortReader.cpp
#include <iostream>
#include "SerialPortReader.h"
SerialPortReader::SerialPortReader(QObject *parent) : QObject(parent)
{
serialPort = new QSerialPort(this);
const QString serialPortName = "COM4"; //argumentList.at(1);
serialPort->setPortName(serialPortName);
const int serialPortBaudRate = QSerialPort::Baud9600;
serialPort->setBaudRate(serialPortBaudRate);
if (!serialPort->open(QIODevice::ReadOnly)) {
std::cout << "Failed to open port" << std::endl;
//return 1;
}
std::cout << "SerialPortReader(QSerialPort *serialPort, QObject *parent)" << std::endl;
connect(serialPort, SIGNAL(readyRead()), this, SLOT(handleReadyRead()), Qt::QueuedConnection);
// connect(serialPort, &QSerialPort::readyRead, this, &SerialPortReader::handleReadyRead);
//connect(serialPort, &QSerialPort::errorOccurred, this, &SerialPortReader::handleError);
//connect(&m_timer, &QTimer::timeout, this, &SerialPortReader::handleTimeout);
//m_timer.start(5000);
}
void SerialPortReader::handleReadyRead()
{
std::cout << "handleReadyRead()" << std::endl;
m_readData.append(serialPort->readAll());
if (!m_timer.isActive())
m_timer.start(5000);
}
/*
void SerialPortReader::handleTimeout()
{
std::cout << "handleTimeout()" << std::endl;
if (m_readData.isEmpty()) {
std::cout << "No data was currently available for reading" << std::endl;
} else {
std::cout << "Data successfully received" << std::endl;
//m_standardOutput << m_readData << Qt::endl;
}
//QCoreApplication::quit();
}
void SerialPortReader::handleError(QSerialPort::SerialPortError serialPortError)
{
std::cout << "handleError()" << std::endl;
if (serialPortError == QSerialPort::ReadError) {
std::cout << "An I/O error occurred while reading" << std::endl;
//QCoreApplication::exit(1);
}
}
*/
SerialPortReader::~SerialPortReader() {
close();
}
// Close the files, filestreams, etc
void SerialPortReader::close() {
// ...
}
... and in my QApplication code you just need to include the .h and write this to instantiate the serial listener:
SerialPortReader *serialPortReader = new SerialPortReader(this);
Here is a short UDP server example in Qt below which does work but what I don't like is that I'm polling to see if new data is available. I've come across some examples of a readyRead() but they all seem to introduce a qt class. Do I need to use a qt class in order to take advantage of the readyRead() signal?
Here is the working but simple UDP server implemented entirely in main:
#include <QDebug>
#include <QUdpSocket>
#include <QThread>
int main(int argc, char *argv[])
{
QUdpSocket *socket = new QUdpSocket();
u_int16_t port = 7777;
bool bindSuccess = socket->bind(QHostAddress::AnyIPv4, port);
if (!bindSuccess) {
qDebug() << "Error binding to port " << port << " on local IPs";
return a.exec();
}
qDebug() << "Started UDP Server on " << port << endl;
QHostAddress sender;
while (true) {
while (socket->hasPendingDatagrams()) {
QByteArray datagram;
datagram.resize(socket->pendingDatagramSize());
socket->readDatagram(datagram.data(),datagram.size(),&sender,&port);
qDebug() << "Message From :: " << sender.toString();
qDebug() << "Port From :: "<< port;
qDebug() << "Message :: " << datagram.data();
}
QThread::msleep(20);
}
return 0;
}
Here is an example of the readyRead() signal:
https://www.bogotobogo.com/Qt/Qt5_QUdpSocket.php
I haven't really figured out how to get this to work yet. I must be doing something wrong. Here is the UDP connection code i'm trying:
#include "myudp.h"
MyUDP::MyUDP(QObject *parent) : QObject(parent) {
}
void MyUDP::initSocket(u_int16_t p) {
port = p;
udpSocket = new QUdpSocket(this);
bool bindSuccess = udpSocket->bind(QHostAddress::LocalHost, port);
if (!bindSuccess) {
qDebug() << "Error binding to port " << port << " on local IPs";
return;
}
connect(udpSocket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));
}
void MyUDP::readPendingDatagrams() {
QHostAddress sender;
while (udpSocket->hasPendingDatagrams()) {
QByteArray datagram;
datagram.resize(udpSocket->pendingDatagramSize());
udpSocket->readDatagram(datagram.data(), datagram.size(), &sender, &port);
qDebug() << "Message From :: " << sender.toString();
qDebug() << "Port From :: " << port;
qDebug() << "Message :: " << datagram.data();
}
}
myudp.h
#include <QObject>
#include <QUdpSocket>
class MyUDP : public QObject
{
Q_OBJECT
public:
explicit MyUDP(QObject *parent);
void initSocket(u_int16_t p);
u_int16_t port;
QUdpSocket *udpSocket;
signals:
public slots:
void readPendingDatagrams();
};
new main.cpp
int main(int argc, char *argv[])
{
MyUDP *myUDP = new MyUDP(0);
myUDP->initSocket(port);
while (true) {
usleep(1000);
}
return 0;
}
I am testing with:
netcat 127.0.0.1 -u 7777
{"cid"="0x1234123412341", "fill_level"=3245 }<cr>
What you're doing wrong is that you're not letting Qt's event loop run. i.e. this is incorrect:
int main(int argc, char *argv[])
{
MyUDP *myUDP = new MyUDP(0);
myUDP->initSocket(port);
while (true) {
usleep(1000);
}
return 0;
}
... instead, you should have something like this:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// connect needs to occur after QCoreApplication declaration
MyUDP *myUDP = new MyUDP(0);
myUDP->initSocket(port);
return app.exec();
}
... it is inside the app.exec() call where a Qt application spends most of its time (app.exec() won't return until Qt wants to quit), and there is where Qt will handle your UDP socket's I/O and signaling needs.
Please modify your processPendingDatagrams like this, to let newer incoming data be processed:
void MyUDP::readPendingDatagrams() {
QHostAddress sender;
uint16_t port;
QByteArray datagram; // moved here
while (udpSocket->hasPendingDatagrams()) {
//QByteArray datagram; // you don't need this here
datagram.resize(udpSocket->pendingDatagramSize());
udpSocket->readDatagram(datagram.data(), datagram.size(), &sender, &port);
qDebug() << "Message From :: " << sender.toString();
qDebug() << "Port From :: " << port;
qDebug() << "Message :: " << datagram.data();
}
// God knows why, there is always one more "dummy" readDatagram call to make,
// otherwise no new readyRead() will be emitted, and this function would never be called again
datagram.resize(udpSocket->pendingDatagramSize());
socket->readDatagram(datagram.data(),datagram.size(),&sender,&port);
}
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:
TERMINAL WITH ERROR image
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 use println 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 got LE, then sometime later you got D OFF immediately followed by LED 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 need app.exec since you write blocking code.
// 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
}
}
If you wish, you can also easily turn it into a GUI application, it's only a few lines to do so:
#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();
}
I think you must use EOL and Carrige return character on QT. Try to replace Serial.write to Serial.println in Arduino code.
I am trying to read my SerialPort based on the
http://doc.qt.io/qt-5/qtserialport-creadersync-main-cpp.html
example:
QCoreApplication coreApplication(argc, argv);
QTextStream standardOutput(stdout);
QSerialPort serialPort;
QByteArray readData;
serialPort.setPortName("ttyS4");
serialPort.setBaudRate(QSerialPort::Baud9600);
serialPort.setDataBits(QSerialPort::Data8);
serialPort.setParity(QSerialPort::EvenParity);
serialPort.setStopBits(QSerialPort::OneStop);
serialPort.setFlowControl(QSerialPort::NoFlowControl);
if (!serialPort.open(QIODevice::ReadOnly)) {
standardOutput << QObject::tr("Failed to open port") << endl;
return 1;
}
while (serialPort.waitForReadyRead(5000))
readData.append(serialPort.readAll());
qDebug() << readData;
return coreApplication.exec();
I also tried reading Data based on the http://doc.qt.io/qt-5/qtserialport-cwriterasync-example.html example:
Main:
int main(int argc, char *argv[])
{
QCoreApplication coreApplication(argc, argv);
QTextStream standardOutput(stdout);
QSerialPort serialPort;
serialPort.setPortName("ttyS4");
serialPort.setBaudRate(QSerialPort::Baud9600);
serialPort.setDataBits(QSerialPort::Data8);
serialPort.setParity(QSerialPort::EvenParity);
serialPort.setStopBits(QSerialPort::OneStop);
serialPort.setFlowControl(QSerialPort::NoFlowControl);
if (!serialPort.open(QIODevice::ReadOnly)) {
standardOutput << QObject::tr("Failed to open port") << endl;
return 1;
}
SerialPortReader serialPortReader(&serialPort);
return coreApplication.exec();
}
serialPortReader:
SerialPortReader::SerialPortReader(QSerialPort *serialPort, QObject *parent):QObject(parent), m_serialPort(serialPort), m_standardOutput(stdout)
{
connect(m_serialPort, SIGNAL(readyRead()), SLOT(handleReadyRead()));
connect(m_serialPort, SIGNAL(error(QSerialPort::SerialPortError)), SLOT(handleError(QSerialPort::SerialPortError)));
connect(&m_timer, SIGNAL(timeout()), SLOT(handleTimeout()));
m_counter = 0;
m_timer.start(5000);
}
SerialPortReader::~SerialPortReader()
{
}
void SerialPortReader::handleReadyRead()
{ m_counter++;
m_readData.append(m_serialPort->readAll());
qDebug()<< m_serialPort->readAll();
qDebug() << "triggered" << m_counter;
}
void SerialPortReader::handleTimeout()
{
if (m_readData.isEmpty()) {
m_standardOutput << QObject::tr("No data was currently available for reading from port %1").arg(m_serialPort->portName()) << endl;
} else {
m_standardOutput << QObject::tr("Data successfully received from port %1").arg(m_serialPort->portName()) << endl;
m_standardOutput << m_readData << endl;
}
QCoreApplication::quit();
}
void SerialPortReader::handleError(QSerialPort::SerialPortError serialPortError)
{
if (serialPortError == QSerialPort::ReadError) {
m_standardOutput << QObject::tr("An I/O error occurred while reading the data from port %1, error: %2").arg(m_serialPort->portName()).arg(m_serialPort->errorString()) << endl;
QCoreApplication::exit(1);
}
}
But when I send data to this COM port (with same serialPort Settings for Sender), not all of the data is received.
With the MSB-RS232 I can check which data really has been sendet to the port and there is nothing wrong with my sender.
For testing I am sending
main:
QString alpha = "abcdefghijklmnopqrstuvwxyz123456789";
handler.writetoPort(alpha);
handler.cpp:
void SerialHandler::writetoPort(QString x)
{
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
QByteArray encodedVar = codec->fromUnicode(x);
writetoPort(encodedVar);
}
void SerialHandler::writetoPort(const QByteArray x)
{
serial.write(x);
serial.waitForBytesWritten(-1);
}
The result of this is the output:
abyz123456789 or abcdklmnopqrstuvwxyz123456789 or abcdefghijklm or ...
It's always different.
Does anyone have a clue what is going on here?
Thank you for reading my long post.
--added 17.07--
This might be mandatory for my problem:
The code has to run on a microprocessor.
CPU: Atmel -AT91SAM9X25 - ARM926(ARMv5) - 400MHz
RAM: 32 MB
Linux Kernel Version: 3.9.0
QT Version: 5.4.1 (cross compiled)
both the async and sync example are working perfectly fine on my Windows PC.
Maybe this will help
void SerialPortReader::handleReadyRead()
{
m_counter++;
while (m_serialPort->bytesAvailable())
{
m_readData.append(m_serialPort->readAll());
}
qDebug()<< m_readData;
qDebug() << "triggered" << m_counter;
}
I tried the exact same Projekt on a different Board and everything works smoothly.
I think the COM Port of the old Board might have been damaged.
Will mark this as resolved but I can't tell what the true problem really was.
I am trying to rig up some basic serial communications in QT
I am getting the port COM19 from QSerialPortInfo, and I speaking successfully to the port via Arduino. However, I cannot get anything back via QT.
#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
#include <QTextStream>
#include <QFile>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()){
qDebug() << "Name :" << info.portName();
qDebug() << "Description :" << info.description();
qDebug() << "Manufactuer :" << info.manufacturer();
QSerialPort serial;
serial.setPort(info);
if(serial.open(QIODevice::ReadWrite))
qDebug() << serial.errorString();
serial.write("M114 \n");
qDebug() << serial.readAll();
serial.close();
// Now we need to send and receive commands
serial.setPortName("COM19");
serial.setBaudRate(QSerialPort::Baud57600);
serial.setDataBits(QSerialPort::Data8);
serial.setParity(QSerialPort::NoParity);
serial.setStopBits(QSerialPort::OneStop);
serial.setFlowControl(QSerialPort::NoFlowControl);
if(serial.open(QIODevice::ReadWrite)){
qDebug() << "opened";
}else{
qDebug() << "Not opened";
}
qDebug() << serial.errorString();
serial.write("M114 \n");
qDebug() << serial.readAll();
serial.close();
}
MainWindow w;
w.show();
return a.exec();
}
As you can see, I am trying a simple connection along the lines of the documentation, and one where I write out all the baud rate information. They throw two different errors.
Like I said, I am connecting via arduino to this same port and having success. Any ideas what's wrong?
Name : "COM19"
Description : "USB Serial (Communication Class, Abstract Control Model)"
Manufactuer : "PJRC.COM, LLC."
"Unknown error"
""
opened
"The handle is invalid."
""
Any ideas for what I am doing wrong?
My idea is to send commands to the device, and read them back to the console.
the code looks a bit confuse. You open all port available and then you try to do something wrong.
NOTE: You use a GUI application like a shell application. It is wrong.
Try:
#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
#include <QTextStream>
#include <QFile>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QSerialPort serial;
serial.setPortName("COM19");
if(serial.open(QIODevice::ReadWrite)){
//Now the serial port is open try to set configuration
if(!serial.setBaudRate(QSerialPort::Baud57600))
qDebug()<<serial.errorString();
if(!serial.setDataBits(QSerialPort::Data8))
qDebug()<<serial.errorString();
if(!serial.setParity(QSerialPort::NoParity))
qDebug()<<serial.errorString();
if(!serial.setStopBits(QSerialPort::OneStop))
qDebug()<<serial.errorString();
if(!serial.setFlowControl(QSerialPort::NoFlowControl))
qDebug()<<serial.errorString();
//If any error was returned the serial il corrctly configured
serial.write("M114 \n");
//the serial must remain opened
if(serial.waitForReadyRead(100)){
//Data was returned
qDebug()<<"Response: "<<serial.readAll();
}else{
//No data
qDebug()<<"Time out";
}
//I have finish alla operation
serial.close();
}else{
qDebug()<<"Serial COM19 not opened. Error: "<<serial.errorString();
}
MainWindow w;
w.show();
return a.exec();
}
Starting with the tenth port, his name will be \\.\COM10
You can reassign the port to a different number in Device Manager