I'm reading and plotting data from a serial port using Qt. I'm trying to create a timeout with the QTimer class, who sends in the function "lettura()". It works one time and after creating a loop inside that, is there some way to get out from that loop? I'm a beginner and I don't know how to use thread and qtimer.
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QSerialPort>
#include<QtDebug>
#include<QTimer>
#include <thread>
#include<QSharedPointer>
#include"qcustomplot.h"
QSerialPort *serial;
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
//Timer start
timer.start();
//Set up form
ui->setupUi(this);
//Set up poerta seriale
serial= new QSerialPort(this);
serial->setPortName("COM3");
serial->setBaudRate(QSerialPort::Baud115200);
serial->setDataBits(QSerialPort::Data8);
serial->setParity(QSerialPort::NoParity);
serial->setStopBits(QSerialPort::OneStop);
serial->setFlowControl(QSerialPort::NoFlowControl);
serial->open(QIODevice::ReadOnly);
//Set up grafici
//Set up del grafico dell'umidità
ui->plotH->addGraph();
ui->plotH->graph(0)->setScatterStyle((QCPScatterStyle::ssCircle));
ui->plotH->graph(0)->setLineStyle(QCPGraph::lsLine);
ui->plotH->xAxis->setRange(0,8);
ui->plotH->yAxis->setRange(0,100);
ui->plotH->xAxis->setLabel("t[h]");
ui->plotH->yAxis->setLabel("H[RH%]");
//Set up del grafico della temperatura
ui->plotT->addGraph();
ui->plotT->graph(0)->setScatterStyle((QCPScatterStyle::ssCircle));
ui->plotT->graph(0)->setLineStyle(QCPGraph::lsLine);
ui->plotT->xAxis->setRange(0,8);
ui->plotT->yAxis->setRange(-20,50);
ui->plotT->xAxis->setLabel("t[h]");
ui->plotT->yAxis->setLabel("T[°C]");
//Connessione con la funzione principale
connect(serial, &QSerialPort::readyRead, this, &MainWindow::Reader);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::Reader()
{
QTimer *timer3 = new QTimer(this);
connect(timer3, &QTimer::timeout, this, QOverload<>::of(&MainWindow::lettura));
timer3->start(10000);
}
void MainWindow::PLOTTER_H()
{
ui->plotH->graph(0)->setData(vec_t, vec_H);
ui->plotH->replot();
ui->plotH->update();
}
void MainWindow::PLOTTER_T()
{
ui->plotT->graph(0)->setData(vec_t, vec_T);
ui->plotT->replot();
ui->plotT->update();
}
void MainWindow::addPoints(double HUM, double TEMP,double t)
{
vec_t.append(t);
vec_H.append(HUM);
vec_T.append(TEMP);
}
void MainWindow::Clear()
{
vec_t.clear();
vec_T.clear();
vec_H.clear();
}
void MainWindow::on_Clear_clicked()
{
Clear();
PLOTTER_H();
PLOTTER_T();
}
void MainWindow::lettura()
{
//Letura dei dati
serial->waitForReadyRead();
m_readData=serial->QSerialPort::readAll();
//Sgrossatura dei dati
inter=QString(m_readData);
QStringList firstlist2= inter.split("$");
m_readData2=firstlist2.takeFirst();
inter2=QString(m_readData2);
QStringList firstlist3= inter2.split(" ");
m_readData3=firstlist3.takeFirst();
H=m_readData3.toDouble();
QStringList firstlist4=inter2.split(" ");
m_readData4=firstlist4.takeLast();
T=m_readData4.toDouble();
//Ottenere dal timer la variabile tempo
milli=timer.elapsed();
double sec=milli/1000;
min=sec/60;
double ore=min/60;
//Creazione dei punti
addPoints(H,T,min);
//Aggiunta dei punti ai grafici
PLOTTER_H();
PLOTTER_T();
//Programma in stand-by per 5 minuti
//Sleep(10000);
// QThread::sleep(10); //300
}
First issue is:
You need to create the timer3 pointer as a member variable new it in the constructor setup the connect in the constructor, set it to singleshot most likely if you are going to use it this way. and then just call timer3->start(10000)
The other issue is what is
Do you already have a timer? If you do us it instead of the timer3 one
There are other issues with starting the timer on the ReadyRead call from a serial port since it will trigger every time a byte is ready and the timer->start() call will reset the timer each time. But that is a threading question.