PDA

View Full Version : STM32 Nucleo F446RE - Serial Port Problem



dernis
19th November 2019, 21:41
Hello.

I have a problem with NucleoF446RE namely the Qt program will only work once. After connecting, I can only light the diode once, then I have to disconnect and connect the device to do anything over and over again. What could be the problem ?? It looks like I have a clogged port.

With HyperTerminal Nukleo works fine...

Ps.

Sorry for English, I'm from Poland and I'm looking for help here because I found a bug in Qt :)

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QDebug>
#include <QList>
#include <QSerialPortInfo>
#include <QDateTime>
#include <QtSerialPort>

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->device = new QSerialPort(this);
}

MainWindow::~MainWindow()
{
delete ui;
}

void MainWindow::on_pushButtonSearch_clicked()
{
ui->comboBoxDevices->clear();

this->addToLogs("Szukam urz?dze?...");

QList<QSerialPortInfo> devices;
devices = QSerialPortInfo::availablePorts();


for(int i = 0; i < devices.count(); i++)
{
this->addToLogs("Znalaz?em urz?dzenie: " + devices.at(i).portName() + " " + devices.at(i).description());
ui->comboBoxDevices->addItem(devices.at(i).portName() + "\t" + devices.at(i).description());
}
}

void MainWindow::addToLogs(QString message)
{
QString currentDateTime = QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm:ss");
ui->textEditLogs->append(currentDateTime + "\t" + message);

}

void MainWindow::sendMessageToDevice(QString message)

{

if(this->device->isOpen() && this->device->isWritable())
{
this->addToLogs("Wysy?am informacje do urz?dzenia " + message);
this->device->write(message.toStdString().c_str());

}
else
{
this->addToLogs("Nie mog? wys?a? wiadomo?ci. Port nie jest otwarty!");
}
return;
}

void MainWindow::on_pushButtonConnect_clicked()
{
if(ui->comboBoxDevices->count() == 0)
{
this->addToLogs("Nie wykryto ?adnych urz?dze?!");
return;
}

QString comboBoxQString = ui->comboBoxDevices->currentText();
QStringList portList = comboBoxQString.split("\t");
QString portName = portList.first();

this->device->setPortName(portName);

// OTWÓRZ I SKONFIGURUJ PORT:
if(!device->isOpen())
{
if(device->open(QSerialPort::ReadWrite))
{
this->device->setBaudRate(QSerialPort::Baud9600);
this->device->setDataBits(QSerialPort::Data8);
this->device->setParity(QSerialPort::NoParity);
this->device->setStopBits(QSerialPort::OneStop);
this->device->setFlowControl(QSerialPort::NoFlowControl);


// CONNECT:
connect(this->device, SIGNAL(readyRead()),
this, SLOT(readFromPort()));

this->addToLogs("Otwarto port szeregowy.");
}
else
{
this->addToLogs("Otwarcie porty szeregowego si? nie powiod?o!");
}
}
else
{
this->addToLogs("Port ju? jest otwarty!");
return;
}
}

void MainWindow::readFromPort()
{
while(this->device->canReadLine())
{
QString line = this->device->readLine();
//qDebug() << line;

QString terminator = "\r";
int pos = line.lastIndexOf(terminator);
//qDebug() << line.left(pos);

this->addToLogs(line.left(pos));
}
}

void MainWindow::on_pushButtonCloseConnection_clicked()
{
if(this->device->isOpen())
{
this->device->close();
this->addToLogs("Zamkni?to po??czenie.");
}
else
{
this->addToLogs("Port nie jest otwarty!");
return;
}
}

void MainWindow::on_pushButtonLedOn_clicked()

{

this->sendMessageToDevice("1");

}

void MainWindow::on_pushButtonLedOff_clicked()
{

this->sendMessageToDevice("0");
}


#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSerialPort>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();

private slots:
void on_pushButtonSearch_clicked();

void on_pushButtonConnect_clicked();

void readFromPort();

void on_pushButtonCloseConnection_clicked();

void on_pushButtonLedOn_clicked();

void on_pushButtonLedOff_clicked();

private:
Ui::MainWindow *ui;

void addToLogs(QString message);

QSerialPort *device;
void sendMessageToDevice(QString message);

};

#endif // MAINWINDOW_H

d_stranz
20th November 2019, 01:01
I found a bug in Qt

Probably not. Most people are quick to blame Qt when the problem is in their own code.

Do you need to flush the port after you write to it? Are you sure that HyperTerminal is using -exactly- the same port setup as your code? You are opening your port as read/write, but you say you are lighting an LED. That sounds like a write-only operation. What are you reading?

dernis
20th November 2019, 05:56
Reads from the Stm in the logs of the written program "active" "" off "" incorrect character ". I have the same port, I open it correctly once. Manual reset of the device (unplug and reconnect) or software (rebinding) allows status change.
A bug found on the Polish forum, their suggestion, that's why I came here..

dernis
20th November 2019, 16:43
Ok ... I found my "bug". I added:


this->device->waitForBytesWritten();

and everything works.

:)

kuzulis
20th November 2019, 18:30
Ok ... I found my "bug". I added:

Nonono. If You use Windows && Qt 5.13.1/5.12.5 then it is a bug in QSP (just update Qt to latest version 5.13.2/5.12.6 or to use a previous version 5.13.0/5.12.4).


waitForBytesWritten()

Don't do that.